VS Code Automated Deployment to Linux: Non-Root User, SSH Keys & Systemd in Practice — Boost Efficiency and Security

Manually deploying an application to a remote server can be a chore. By automating the process, you save time, avoid repetitive steps, and stay focused on coding. In this guide we’ll set up a convenient workflow where Visual Studio Code (VS Code) tasks automatically build your app, transfer files securely to a remote Linux server using SSH key authentication (through a non-root user), and restart the app with a systemd service. This not only streamlines deployment but also increases security by eliminating root logins and password-based SSH. Using a dedicated, unprivileged user adds another barrier between attackers and your server, and relying on keys instead of passwords all but removes brute-force risk on SSH. Let’s dive into the step-by-step setup.

1. Create a Dedicated Non-Root User for Deployment

Deploying or running an app as root is bad practice, so we’ll create a new user (e.g. vscodeuser) on the remote server to own and run our app. A non-root account limits damage if it’s compromised and is generally recommended. This user will be used for SSH logins and to run the app’s service.

Log in to the remote server as root (or any sudo-capable admin) and add the new user (replace vscodeuser with the username you prefer):

sudo adduser vscodeuser

This prompts for a password and user details. Pick a strong password (though we’ll switch to key-based logins shortly, so SSH won’t ask for it). Accept the defaults for user info if you like. A new account and home directory (e.g. /home/vscodeuser) are created.

Optional: If you want this user to perform admin tasks, add it to the sudo group (Debian/Ubuntu):

sudo usermod -aG sudo vscodeuser

For a pure deploy user, sudo isn’t usually necessary.

Why not root? Every Unix/Linux system has a root account, and attackers routinely target it. Disabling direct root SSH and using an ordinary user means an attacker must compromise a non-root account first, then escalate privileges — an extra hurdle. Completely disabling root SSH logins and using an unprivileged, key-authenticated account is widely considered best practice.

2. Set Up SSH Key Authentication for the New User

Next we’ll enable SSH public-key authentication for vscodeuser so we can log in without passwords. Key-based logins are not only more convenient (no prompts in our automation) but also more secure, especially if password logins are disabled.

On your local machine

You need an SSH key pair (a private key and a public key). If you already have one you’d like to use, skip generating a new key; otherwise generate one in step 4.

On the remote server

Authorize your public key for the new user:

Your server now allows vscodeuser to log in with a key. This replicates what ssh-copy-id does: create ~/.ssh, add the key, fix perms. If ssh-copy-id is available locally, run:

# On your local machine:
ssh-copy-id vscodeuser@your_server_ip

It prompts once for the user’s password, then installs the key properly. Afterwards you should SSH with no password prompt.

Security tip: Since vscodeuser is key-only, consider disabling password auth and prohibiting root logins in /etc/ssh/sshd_config by setting PasswordAuthentication no and PermitRootLogin no, then restarting SSH. All access must then use keys, thwarting brute-force attempts and blocking root entirely. Log in as vscodeuser and use sudo only when necessary.

3. Verify SSH Permissions and Ownership

Double-check the SSH setup — it’s a frequent source of errors. On the remote server (as root or sudo):

Verify:

ls -l /home/vscodeuser/.ssh
ls -l /home/vscodeuser/.ssh/authorized_keys

You should see something like:

drwx------ 2 vscodeuser vscodeuser 4096 May 24 00:30 .ssh
-rw------- 1 vscodeuser vscodeuser  382 May 24 00:30 authorized_keys

Fix anything with chmod and chown as above. StrictModes in SSH will reject loose perms.

Now test from your local machine (you may need a key first — see next step):

ssh vscodeuser@your_server_ip

You should log in without a password prompt. If prompted, key auth failed — re-check earlier steps.

4. Generate and Use an SSH Key Pair Locally

If you don’t already have a key pair on your dev box, create one now. The private key stays local (guard it!), the public key is what you installed on the server.

On your local machine:

ssh-keygen -t rsa -b 4096 -C "VSCode Deploy Key"

Accept the default path (~/.ssh/id_rsa / id_rsa.pub) or choose something like ~/.ssh/id_vscode_deploy. Enter a passphrase for extra security, or press Enter for none (but then anyone with the file can use it). If you set a passphrase, use an SSH agent so automation runs without prompts.

You’ll now have:

If this is a new key, go back to Step 2 and add id_rsa.pub to the server. Then test:

ssh vscodeuser@your_server_ip -i ~/.ssh/id_rsa

(or omit -i if it’s your default key).

Example key formats:

Add the key to your agent (ssh-add ~/.ssh/id_rsa) so VS Code can use it without prompting.

Key-based SSH for vscodeuser now works; time to set up the app under that user and automate deployment.

5. Create a Systemd Service (User Service) for Your App

Instead of running the app by hand, create a systemd service. It can start at boot, restart on crash, and be controlled with one command. We’ll make a user service under vscodeuser, so no root is required.

As on the remote server:

Now vscodeuser can control the service:

systemctl --user restart myapp.service

We’ll automate that next.

6. Automate Build & Deployment with VS Code Tasks

Here’s the magic: configure VS Code to build, deploy, and restart with a single command or keybinding. VS Code’s task runner can call external tools/scripts.

Open .vscode/tasks.json in your workspace:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build App",
            "type": "shell",
            "command": "go build -o myapp .",
            "group": { "kind": "build", "isDefault": true },
            "problemMatcher": []
        },
        {
            "label": "Deploy App",
            "type": "shell",
            "command": "rsync -avz ./myapp vscodeuser@your-server-ip:/home/vscodeuser/myapp/",
            "dependsOn": "Build App",
            "problemMatcher": []
        },
        {
            "label": "Restart App Service",
            "type": "shell",
            "command": "ssh vscodeuser@your-server-ip 'systemctl --user restart myapp.service'",
            "dependsOn": "Deploy App",
            "problemMatcher": []
        }
    ]
}

How it works

Run “Tasks: Run Task” → Restart App Service. VS Code chains Build ➝ Deploy ➝ Restart. Bind a key or use Ctrl+Shift+B if Build is grouped.

Note: Tasks assume a non-interactive environment. With key auth, no password prompts occur. If your key has a passphrase, make sure an agent caches it; otherwise tasks may hang waiting for input.

Summary

With this setup you can:

All with one command, no manual SSH, no passwords, no unnecessary root privileges. The non-root user vscodeuser runs its own service, boosting security, and key-based SSH lets automation run safely while eliminating brute-force password attacks. It’s a lightweight deployment pipeline using simple, fully controlled tools, and VS Code keeps the entire workflow inside your editor — convenient and error-free.

你可能也感兴趣