Deploy with Git on a VPS
Git lets you deploy exactly the version you tested, instead of overwriting files by hand over FTP. On a VPS, the simplest approach is a clone in /var/www, updated with git pull. It requires a read-only deploy key, clean permissions and one clear rule: the server never edits the code.
Prepare a deploy key
As the deployment user, for example deploy:
ssh-keygen -t ed25519 -C "deploy@vps" -f ~/.ssh/deploy_key -N ""
cat ~/.ssh/deploy_key.pubIn GitHub or GitLab, add the public key as a read-only deploy key limited to this repository. A machine account with access to every repository is unnecessary here. Declare the alias:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/deploy_key
IdentitiesOnly yesIdentitiesOnly yes stops SSH from trying other keys. Test with ssh -T [email protected]: the expected message confirms authentication, without a shell.
Clone into /var/www
sudo mkdir -p /var/www
sudo chown deploy:www-data /var/www
git clone [email protected]:account/repository.git /var/www/app
cd /var/www/appDo not clone into /root, and avoid serving a directory that contains .git, node_modules or tests directly. For a static site, point Nginx at the public subdirectory. Permissions stay: directories 750, files 640, owner deploy, group www-data.
Update without overwriting
git fetch --prune
git status
git pull --ff-only--ff-only refuses an implicit local merge: the update fails instead of creating an unexpected commit. Do not edit files by hand on the server, or the next pull will be blocked. To return to a known state, git log --oneline identifies a healthy commit; after confirming there are no local changes, git reset --hard <commit> replaces the working copy, then restart the service.
A short script avoids omissions:
#!/bin/sh
set -eu
cd /var/www/app
git pull --ff-only
npm ci --omit=dev
sudo systemctl restart appAdapt the dependency and restart commands to your stack: composer install --no-dev for PHP, the virtual environment for Python.
Secrets and verification
.env, private keys and backups never go into Git. Create them on the server with chmod 600. A compromised deploy key allows reading the repository, not writing to it: keep that scope and revoke the key if needed.
After deployment, check git log -1 --oneline, systemctl status and a health route with curl. Back up the database before any migration. If the repository is private, test the clone from the VPS before removing the previous deployment: a key problem shows up immediately.
Advertisement
Was this article helpful?
Read next
- Install and secure RedisInstall Redis, restrict it to local listening, add authentication and back up its data.
- Install Python and a virtual environmentCreate a Python virtual environment, install dependencies and run the application with systemd.
- Install PHP-FPM for a websiteConnect Nginx to PHP 8.4-FPM over a Unix socket, with correct permissions and a test page.