Files
vigilcare-clinical/docs/ops/cd-deploy-ssh-setup.md
voltsrage 5a7fc2790f
CI / backend (push) Successful in 10m44s
CI / frontend (push) Successful in 1m51s
Deployment updates
2026-08-07 19:33:37 +08:00

4.0 KiB

CD Deploy SSH Key Setup

How to create and place the SSH key pair used by .gitea/workflows/cd.yml to copy docker-compose.prod.yml and run deploy commands on the production VM.

Related Gitea secrets: DEPLOY_SSH_KEY, DEPLOY_HOST, DEPLOY_USER.


Who holds what

Generate the key pair on your computer (or any trusted machine). Split it afterward: private key → Gitea; public key → VM.

Piece Where it lives Who uses it
Private key (vigilcare-deploy) Gitea secret DEPLOY_SSH_KEY The act_runner (CD job) when it SSHs
Public key (vigilcare-deploy.pub) Prod VM → ~/.ssh/authorized_keys for DEPLOY_USER The VM accepts logins that present the matching private key

The private key does not need to live on the VM. The VM only needs the public half.


Step by step

1. On your computer — create the key pair

Windows (PowerShell):

ssh-keygen -t ed25519 -f vigilcare-deploy -N '""' -C "gitea-cd"

Windows 10/11 ships the OpenSSH client by default (Settings → Optional features → OpenSSH Client if it's missing). PowerShell needs the empty passphrase quoted as '""' — a bare -N "" sometimes gets swallowed by PowerShell's argument parsing and prompts for a passphrase anyway.

Linux (Ubuntu):

ssh-keygen -t ed25519 -f vigilcare-deploy -N "" -C "gitea-cd"

Both produce two files in the current folder:

  • vigilcare-deployprivate (secret)
  • vigilcare-deploy.pubpublic (safe to copy)

2. On the VM — install the public key

Log into the prod VM as a user that can set up the deploy account (or as DEPLOY_USER if it already exists).

Copy the public key onto the VM, then:

# On the VM, as DEPLOY_USER (e.g. deploy)
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Paste the contents of vigilcare-deploy.pub into authorized_keys:
echo "ssh-ed25519 AAAA... gitea-cd" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Or from your computer (if you already have another way to SSH in):

Windows (PowerShell): ssh-copy-id doesn't exist on Windows, so pipe the public key into the same mkdir/echo/chmod sequence over SSH instead:

Get-Content vigilcare-deploy.pub | ssh deploy@YOUR_DEPLOY_HOST "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Linux (Ubuntu):

ssh-copy-id -i vigilcare-deploy.pub deploy@YOUR_DEPLOY_HOST

Ensure DEPLOY_USER can manage /opt/vigilcare and run Docker (docker compose).

3. On Gitea — store the private key as a secret

Repo → SettingsActionsSecrets → New secret:

  • Name: DEPLOY_SSH_KEY
  • Value: entire contents of vigilcare-deploy (including -----BEGIN OPENSSH PRIVATE KEY----- and the end line)

Also set:

  • DEPLOY_HOST — hostname or IP of the VM
  • DEPLOY_USER — that Linux user (e.g. deploy)

4. Sanity check from your computer

Windows (PowerShell):

ssh -i vigilcare-deploy deploy@YOUR_DEPLOY_HOST

Linux (Ubuntu):

ssh -i vigilcare-deploy deploy@YOUR_DEPLOY_HOST

Same command either way — if that works without a password, CD's SSH steps will work the same way (the runner uses the same private key from the secret).

5. Optional cleanup on your computer

After the private key is in Gitea and you've verified SSH, you can delete the local private file if you don't want another copy. Keep the public key only if you need it again. Prefer regenerating over emailing or sharing the private key.

Windows (PowerShell):

Remove-Item vigilcare-deploy

Linux (Ubuntu):

rm vigilcare-deploy

How CD uses it

When the deploy job runs, the runner roughly does:

  1. Write secrets.DEPLOY_SSH_KEY to ~/.ssh/id_ed25519
  2. scp / ssh as DEPLOY_USER@DEPLOY_HOST
  3. The VM checks that private key against the public key in authorized_keys and allows the session

Summary: generate on your PC → public key on the VM → private key in Gitea.