diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 5d4a301..37d582d 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -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 `/releases/`. 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.