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):
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):
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:
Create the
.ssh
directory in the new user’s home (and lock down its permissions). As root (or via sudo):Add your public key to
authorized_keys
: If you have the key text handy, append it manually, for example:(Replace the ssh-rsa string with your actual key, all on one line.)
Or open the file withsudo nano /home/vscodeuser/.ssh/authorized_keys
and paste the key.Fix permissions and ownership:
authorized_keys
must be 600 and owned by the user. SSH will ignore it otherwise.
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:
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):
/home/vscodeuser/.ssh
must be owned byvscodeuser
anddrwx------
(700)./home/vscodeuser/.ssh/authorized_keys
must be owned byvscodeuser
and-rw-------
(600).
Verify:
You should see something like:
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):
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:
-t rsa -b 4096
: RSA key, 4096 bits.-C "VSCode Deploy Key"
: a label.
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:
~/.ssh/id_rsa
– private key (keep secret).~/.ssh/id_rsa.pub
– public key (copy to server).
If this is a new key, go back to Step 2 and add id_rsa.pub
to the server. Then test:
(or omit -i
if it’s your default key).
Example key formats:
Public (
id_rsa.pub
)ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxqHYEE3XdexSmo5rT01nxOKjP4YOIuC/... demo@local
Private (
id_rsa
)-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnN... -----END OPENSSH PRIVATE KEY-----
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:
Create the unit file:
Define the service:
[Unit] Description=My App Service After=network.target [Service] ExecStart=/home/vscodeuser/myapp/myappbinary WorkingDirectory=/home/vscodeuser/myapp Restart=on-failure # No User= needed; this is a user service [Install] WantedBy=default.target
- ExecStart: command to run your app. Adjust path.
- WorkingDirectory: (optional) app folder.
- Restart: restart on crashes.
Reload systemd and enable:
Check status:
Enable lingering (so the service survives logouts/reboots):
Now vscodeuser
can control the 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
- Build App: compiles your project (example for Go). Adjust for Node, Java, Rust, etc.
- Deploy App:
rsync
syncs the artifact(s) to the server. Add--delete
if you want to remove stale files.rsync
will auto-use your key or any agent. - Restart App Service: SSH in and restart systemd. It runs only if deploy succeeds.
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:
- Build/compile your project.
- Securely copy updated files to the server (rsync over SSH keys).
- Restart the app’s service on the server.
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.
你可能也感兴趣
- VS Code 自动化部署到 Linux:非 Root 用户、SSH 密钥与 Systemd 实战,提升效率与安全
- Five-Minute Guide to WinPE Network Boot: Tiny PXE Server + Wimboot
- A Deep Dive into JWT: How to Secure HTTP Endpoints and Refine Authentication
- Recent Project Updates: Blog Refactoring, PXE Exploration & WeChat Backend Optimization
- Nebula 私有网络全攻略:轻量组网、Lighthouse 与中继配置详解