A VS Code Extension That Ships Frontend Builds to Linux in 30 Seconds
Simple Deploy
Simple Deploy is a VS Code extension that uploads locally built frontend or static sites to a Linux server with one click, automatically backing up old code, extracting the new package, and swapping it in to go live, making the release process simpler.
What It Can Do
- Upload build artifacts (e.g.,
dist/) from Vue, React, and other frontend projects to a Linux server and swap them in to go live with one click. - Deploy admin dashboards to server subdirectories (e.g.,
/var/www/admin), completing "build + go live" in one step when combined with pre-commands. - Publish static sites or documentation sites generated by VitePress, Docusaurus, etc., with one click.
- Configure multiple projects from the same codebase, deploying to different environments such as testing and production separately.
- Automatically execute local commands before deployment (e.g.,
bun run build), stopping the deployment if the command fails. - Automatically back up old code before deployment; the new package is first extracted to a temporary directory and then swapped in entirely, avoiding a half-finished state.
- Protect upload directories, configuration files, etc., on the server from being deleted via retention rules.
- Display deployment progress, stage status, and scrolling logs in real time, retaining the last 100 deployment records.
Prerequisites
- VS Code version
>= 1.101.0. - The target server must be Linux and must have the
unzipcommand installed. - The server uses account + password login; SSH keys are not currently supported.
First-Time Use
- Click the
Simple Deployicon in VS Code's left Activity Bar to open the panel. - Switch to the
Serverstab and add your server information. - Switch to the
Projectstab and add a deployment project. - Click the project card, confirm the rules, and click
Confirm Deployment. - Wait for the deployment to complete, then copy the logs or close the panel.
The extension relies on
Suiyi Storefor authorization management. Authorization or a trial must be completed before first use.
Interface Description
Panel Entry
- Click the
Simple Deployicon in the left Activity Bar to open the panel. - Switch between the
Projects/Serverstabs at the top of the panel. - The top right shows authorization status, purchase/trial buttons, and the settings center.
Project Card
Displays the project name, target server, and deployment path. Click the card to start deployment.
Server Card
Displays the server name and account information, supporting editing and deletion.
Adding a Server
- Open the
Simple Deploypanel and switch to theServerstab. - Click
Add Server. - Fill in the form: - Server Name: Give the server a name for easy identification; can be left blank. - Host / IP: The server address. - Port: SSH port, default 22. - Username: SSH login username. - Password: Must be filled in when creating; leave blank when editing to keep the password unchanged.
- Click
Save.
Passwords are securely stored inside VS Code and will not be displayed in plain text.
Server Preparation
It is recommended to create a dedicated deployment account on the server and grant it permissions for the target directory:
sudo useradd -m deploy
sudo passwd deploy
sudo chown -R deploy:deploy /var/www/app
sudo chmod -R u+rwx /var/www/app
Adding a Project
- Switch to the
Projectstab and clickAdd Project. - Fill in the form: - Project Name: Required, e.g., "Official Website Frontend". - Target Server: Required, select from saved servers. - Remote Path: Required, the deployment directory on the server, e.g.,
/var/www/app. - Pre-command: Optional, a command to execute locally before deployment. - Upload Rules: Required, which files or directories to upload. - Delete Rules: Optional, which files to delete on the server before deployment. - Retention Rules: Optional, which files should not be deleted even if they match a delete rule. - Click
Save.
Configuration Details
Remote Path
The directory on the server to deploy to.
- Must start with
/. - Cannot contain
... - Must have at least 2 directory levels, e.g.,
/var/www/app. - Cannot be system directories like
/or/var.
| Path | Allowed |
|---|---|
/var/www/app |
✅ |
/var/www |
✅ |
/var |
❌ Too short |
/ |
❌ System root |
/var/www/../etc |
❌ Contains .. |
Upload Rules
Used to specify which local files to upload to the server, using glob syntax:
| Symbol | Meaning |
|---|---|
* |
Matches any character in the same directory level, excluding /. |
** |
Matches any directory level. |
? |
Matches a single character. |
Starts with ! |
Exclusion, e.g., !node_modules/**. |
Common patterns:
dist/**: Upload all contents of thedistdirectory.dist/index.html: Upload a single file only.assets/*.png: Upload all png images underassets.!node_modules/**: Excludenode_modules.
Note:
distuploads the entiredistdirectory;dist/ordist/**only uploads the contents insidedist.
Upload Root Directory
Each upload rule can specify an upload root directory:
- If left blank, the system calculates it automatically.
- If filled in manually, it must be a prefix of this rule.
- For example, if the rule is
dist/**, the automatic upload root isdist.
Why is an upload root directory needed?
The upload root directory determines the top-level structure inside the zip package. After the server extracts it, files are placed according to this structure.
Example:
- Rule
dist/**, upload rootdist- Local files:dist/index.html,dist/assets/main.js- After server extraction:index.html,assets/main.js- This strips thedistdirectory layer, suitable for placing frontend build artifacts directly into the website root. - Rule
dist/**- If the upload root is left blank, the system automatically calculates it asdist, with the same effect as above. - Rule
public/**, upload rootpublic- Local file:public/logo.png- After server extraction:logo.png
Delete Rules
Purpose:
Before deployment, first delete old files or directories on the server that match the rules to prevent old file remnants from affecting the new version.
Use Cases:
- Frontend project filenames change with each build (e.g., hashed
assets/main-abc123.js), so old files don't disappear automatically and need periodic cleanup. - Completely clearing a directory, such as all files under an old
assets/. - Deleting temporary files no longer needed on the server, such as
**/*.zip.
Pattern Examples:
| Rule | What It Deletes |
|---|---|
assets/* |
Deletes all files directly one level under the assets directory, not subdirectories. |
assets/** |
Deletes all contents under the assets directory, including subdirectories. |
index.html |
Deletes a single file. |
**/*.zip |
Deletes all zip files, regardless of level. |
Notes:
- Content not matched by delete rules is left as is.
- If retention rules are configured, they override delete rules; retained files will not be deleted.
- Deletion is executed on the server side; a list of matches is displayed with the count in the logs before deletion.
Retention Rules
Purpose:
Tell the extension which files or directories should not be deleted even if they match a delete rule.
Use Cases:
- Directories with user-uploaded files on the server, such as
uploads/, that should not be emptied with each deployment. - Configuration files or log files that need to be kept, such as
config.json,logs/. - Some files in old assets that the new version doesn't have but need to be kept.
Pattern Examples:
| Rule | What It Retains |
|---|---|
uploads/ |
Retains the entire uploads directory and its contents. |
logo.png |
Retains a single file. |
assets/legacy.css |
Retains legacy.css under the assets directory. |
**/*.config.json |
Retains all files ending with .config.json. |
Notes:
- Retention rules have higher priority than delete rules.
- Retention rules themselves use glob syntax, supporting
*,?,**. - Retained files are moved to the new package's temporary directory during deployment, and after the old directory is cleared, they are published together with the new package.
Pre-commands
Purpose:
Execute some commands locally before packaging and uploading, typically used to rebuild the project to ensure the latest artifacts are uploaded.
Use Cases:
- Run
bun run buildornpm run buildbefore deployment. - Compress images, generate sitemaps, run tests, etc., before deployment.
- Multi-step builds, such as building first and then compressing.
Field Descriptions:
| Field | Description |
|---|---|
| Command | The command to execute in the terminal, e.g., bun run build. |
| Working Dir | The directory in which to execute the command. Leave blank for the project root; if filled in, it's a subdirectory of the project root. |
Pattern Examples:
| Command | Working Dir | Description |
|---|---|---|
bun run build |
Blank | Execute build at project root, generating dist/. |
npm run build |
Blank | Same as above, using npm. |
bun run compress |
dist |
After build, enter dist directory to compress. |
python scripts/copy_assets.py |
Blank | Execute a Python script at the project root. |
Notes:
- Pre-commands are executed sequentially in the order they are added.
- If any command fails (exit code is not 0), the entire deployment is terminated.
- Commands and working directories cannot contain special symbols, start with
/, or contain... - The working directory is relative to the project root, not an absolute path.
General Rule Restrictions
Upload rules, delete rules, retention rules, and the working directory for pre-commands all follow these restrictions:
- Cannot start with
/. - Cannot contain
... - Cannot contain dangerous shell characters:
; & |$ ( ) { } [ ] \ < > ! # ~`. - Cannot be a standalone
*or**.
These restrictions are in place to prevent misoperation and command injection, ensuring deployment security.
Deployment Process
After clicking Confirm Deployment, the extension performs the following steps in order:
- Prepare Deployment: Record basic information such as project, workspace, and rules.
- Execute Pre-commands: Execute local commands in order; terminate on failure.
- Compress Local Files: Package matched files into a zip, temporarily stored in the system tmp directory.
- Connect to Server: Log in to the server via SSH and verify it is a Linux system.
- Back Up Old Code: Package the old code on the server and back it up to
~/.static-deploy/.../backups/, keeping a maximum of 20 copies. - Upload Files: Upload the zip via SFTP, displaying progress and speed in real time.
- Verify and Extract New Package: Verify the zip integrity on the server and extract it to a temporary directory.
- Clear Old Files: Clear the old contents in the target directory, but keep the directory itself.
- Replace with New Directory: Replace the temporary directory with the official target directory.
- Clean Up Temporary Files: Delete the temporary directory on the server and the local temporary zip.
- Deployment Complete: Display success or failure result.
Deployment Panel Introduction
After deployment starts, the deployment panel appears:
- Left: Deployment Logs: Logs are displayed grouped by stage; command output can be expanded/collapsed. Clicking a stage highlights the corresponding step on the right, and clicking a step on the right highlights the corresponding log on the left.
- Right: Deployment Stages: Displays the status of the 11 stages. Gray means not started, green means completed, blue means in progress, red means error.
- Bottom Progress Area: Shows the current step name, percentage progress bar, and deployment result.
If deployment fails, it can automatically restore from backup and clean up temporary files.
Security Tips
- Passwords are stored using VS Code's internal encryption and are not saved in plain text.
- Remote paths must pass security validation, prohibiting dangerous paths like the system root directory.
- Inputs such as project names, rules, and commands are filtered for dangerous characters to reduce injection risks.
- The new package is first extracted to a temporary directory before replacing the official directory, avoiding a half-finished state.
- Only one deployment task can run at a time.
FAQ
Deployment fails with "Only Linux servers are supported"
Please confirm that the target server is a Linux system.
Deployment fails with "Password not found for this server"
Edit the corresponding server, re-enter the password, and save.
Pre-command execution failed
First, manually execute the command in the local terminal to confirm it runs correctly, then check if the working directory is correct.
File hierarchy is wrong after upload
Check the upload rules. dist/** uploads the contents inside dist; if you want to keep the dist directory layer, use dist.
Retention rules didn't take effect
Retention rules have higher priority than delete rules, but ensure the rule pattern matches the actual path.
Contact Us
- Developer WeChat:
chensuiyime - Official Website:
https://yicode.tech
Top 2 from juejin.cn, machine-translated. The original thread is authoritative.
This VS Code extension is quite thoughtfully made. The deployment flow of 'back up old code → extract to temp directory → full replacement' is designed very solidly, effectively preventing the problem of the live site being left in a 'half-broken' state due to deployment interruption. A few small suggestions for reference: 1. Currently it only supports password login. It would be better if SSH key authentication could be added later, since using password login in a production environment carries higher security risks. 2. If it could automatically trigger a simple health check after deployment (like curling the homepage to check the return code), it would be even more complete. I've used similar tools for frontend project deployment before, and deployment efficiency really improves a lot. But one thing to keep in mind: after deployment, it's best to check if there are any abnormal fluctuations in live performance metrics, like page load time, JS error rate, etc. We had a deployment once where the first screen time suddenly increased by 2 seconds, and later found out it was because the build configuration changed, causing unreasonable chunk splitting. If you use performance monitoring tools (like APM-type ones), keeping an eye on the dashboard data after deployment will give you peace of mind. Just personal experience, for reference~
That's so much trouble. I just push to a git server and then set up a server-side CI so it auto-updates on the server after a push.