docs: document automated release deployment

This commit is contained in:
2026-09-07 00:18:37 +03:30
parent bc2feba49a
commit fa98f70b51

View File

@@ -1,23 +1,66 @@
# Deployment
This project builds the Next.js static export in a Node container and serves the
generated files from Nginx on port 80. The container joins the existing
`caddy_proxy` Docker network under the `static-site` service name expected by
Caddy.
The Gitea Actions workflow in `.gitea/workflows/ci-cd.yml` verifies every pull
request and every push to `main`. A successful push to `main` is then deployed
over SSH. The server builds the exact Git archive tested by CI, starts the
Compose service, and waits for its container health check.
## Deploy or update
Releases are stored in `<DEPLOY_PATH>/releases/<commit-sha>`. The `current`
symlink is changed only after the new container is healthy. If startup fails,
the deployment script automatically rebuilds and starts the previous release.
From the project directory on the server, run:
## Gitea repository secrets
Add these secrets under the repository's **Settings > Actions > Secrets**:
| Secret | Value |
| --- | --- |
| `DEPLOY_HOST` | Server hostname or IP address |
| `DEPLOY_USER` | SSH user allowed to run Docker |
| `DEPLOY_PORT` | SSH port; optional, defaults to `22` |
| `DEPLOY_PATH` | Absolute server directory, for example `/srv/portfolio` |
| `DEPLOY_SSH_KEY` | Private SSH key for the deployment user |
| `DEPLOY_KNOWN_HOSTS` | Pinned SSH host-key line for the server |
Generate the known-hosts value from a trusted machine and verify its fingerprint
before saving it:
```sh
docker compose up --build -d
ssh-keyscan -p 22 your-server.example.com
```
The external `caddy_proxy` network must already exist and Caddy must be attached
to it. No host port is published because Caddy is the public entry point and
terminates TLS for `amiirkhl.ir` and `www.amiirkhl.ir`.
Do not copy an unverified key directly into the secret; doing so would remove
the protection against a man-in-the-middle attack.
If the previous `static-site` container was created from a different Compose
project directory, remove that old stack once before the first deployment to
avoid a Docker container-name conflict. Updates from this project then use only
the command above.
## One-time server setup
The server needs Docker Engine with the Compose v2 plugin. The deployment user
must be able to run `docker` without an interactive password prompt.
Create the deployment root and the external network once:
```sh
sudo mkdir -p /srv/portfolio/releases
sudo chown -R deploy:deploy /srv/portfolio
docker network create caddy_proxy
```
Replace `deploy:deploy` and `/srv/portfolio` with the values used for
`DEPLOY_USER` and `DEPLOY_PATH`. Add the public half of `DEPLOY_SSH_KEY` to the
deployment user's `~/.ssh/authorized_keys`.
The container joins `caddy_proxy` under the `static-site` service name. Caddy
must also join that network and proxy to `static-site:80`. No host port is
published by this project.
## Manual deployment
For an emergency manual deployment from a checkout on the server:
```sh
docker compose --project-name portfolio up --detach --build --remove-orphans
```
Old versioned release directories are deliberately retained for rollback. They
can be removed manually after a newer release has been proven stable; keep the
directory referenced by the `current` symlink.