This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
name: Deploy production
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: labyricorn-production
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: labyricorn-deploy
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Build and activate current main
|
||||
run: sudo -n /usr/local/bin/deploy-labyricorn
|
||||
|
||||
- name: Verify the deployed revision and origin
|
||||
run: |
|
||||
deployed_revision="$(cat /srv/labyricorn/current/.labyricorn-commit)"
|
||||
test "$deployed_revision" = "$GITHUB_SHA"
|
||||
curl --fail --silent --show-error \
|
||||
-H 'Host: www.labyricorn.com' \
|
||||
-H 'X-Forwarded-Proto: https' \
|
||||
http://127.0.0.1/ >/dev/null
|
||||
@@ -71,8 +71,9 @@ ignored and must not be committed.
|
||||
|
||||
## Routine content workflow
|
||||
|
||||
The preferred workflow is to edit in a normal Git checkout, review the changes,
|
||||
push them to `main`, and then deploy on the production host.
|
||||
Edit in a normal Git checkout, review the changes, and push them to `main`.
|
||||
A successful push triggers the repository's Gitea Action, which builds and
|
||||
atomically activates that exact revision on the production host.
|
||||
|
||||
```bash
|
||||
git switch main
|
||||
@@ -87,7 +88,8 @@ git commit -m "Describe the site change"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Then deploy on `ubuntu2-47`:
|
||||
Watch the run under **Actions** in Gitea. Manual deployment remains available
|
||||
for recovery or controlled operations:
|
||||
|
||||
```bash
|
||||
sudo deploy-labyricorn
|
||||
@@ -512,17 +514,61 @@ The first origin request should redirect; the simulated Cloudflare HTTPS request
|
||||
should return the site. A different result indicates a proxy/header or nginx
|
||||
configuration problem.
|
||||
|
||||
## Future automatic deployment
|
||||
## Automatic deployment
|
||||
|
||||
Manual deployment is complete and remains the supported path. Automatic
|
||||
deployment is not configured.
|
||||
Pushes to `main` automatically deploy through Gitea Actions. The workflow is
|
||||
versioned with the site at `.gitea/workflows/deploy.yml` and has one job:
|
||||
|
||||
The preferred future design is a Gitea Action triggered only by pushes to
|
||||
`main`, invoking `deploy-labyricorn` through a dedicated, narrowly restricted
|
||||
SSH identity. A webhook receiver is acceptable only if it authenticates a
|
||||
secret, verifies the repository and branch, never executes payload text, and
|
||||
runs with minimal privileges. Never expose a general shell endpoint or an
|
||||
unauthenticated HTTP deployment URL.
|
||||
1. Run on the repository-scoped runner labelled `labyricorn-deploy`.
|
||||
2. Execute the existing root-owned `deploy-labyricorn` command.
|
||||
3. Confirm `/srv/labyricorn/current/.labyricorn-commit` equals the pushed commit.
|
||||
4. Request the site through nginx on the local origin and fail if it is unhealthy.
|
||||
|
||||
The action intentionally does not check out the repository into its own
|
||||
workspace. The deployment script fetches `origin/main` using the dedicated
|
||||
`labyricorn-deploy` account, validates a clean checkout, builds a new release,
|
||||
and atomically changes the `current` symlink. Concurrent action runs share the
|
||||
`labyricorn-production` concurrency group, and the deployment script also uses
|
||||
a filesystem lock.
|
||||
|
||||
### Runner installation
|
||||
|
||||
The production host runs official Gitea Runner 3.0.0 directly on Linux; Docker
|
||||
is not installed or required for this workflow.
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| systemd unit | `gitea-runner.service` |
|
||||
| service account | `gitea-runner` |
|
||||
| runner name | `labyricorn-production` |
|
||||
| registration scope | `Labyricorn/labyricorn-site` repository |
|
||||
| execution label | `labyricorn-deploy:host` |
|
||||
| runner binary | `/usr/local/bin/gitea-runner` |
|
||||
| runner configuration | `/etc/gitea-runner/config.yaml` |
|
||||
| registration state | `/var/lib/gitea-runner/.runner` |
|
||||
| job workspace | `/var/lib/gitea-runner/work` |
|
||||
| sudo policy | `/etc/sudoers.d/gitea-runner-labyricorn` |
|
||||
|
||||
The runner account has no general administrative access. Its sudo policy allows
|
||||
only this exact command without a password:
|
||||
|
||||
```text
|
||||
/usr/local/bin/deploy-labyricorn
|
||||
```
|
||||
|
||||
Useful checks:
|
||||
|
||||
```bash
|
||||
systemctl status gitea-runner
|
||||
journalctl -u gitea-runner -n 100 --no-pager
|
||||
sudo -l -U gitea-runner
|
||||
```
|
||||
|
||||
If the runner must be replaced, delete or disable it in **Repository Settings →
|
||||
Actions → Runners**, generate a fresh repository registration token, and
|
||||
register the replacement. Registration tokens and `.runner` contents are
|
||||
credentials: never commit or print them. A push can still be deployed manually
|
||||
with `sudo deploy-labyricorn` while the runner is unavailable.
|
||||
|
||||
## Change-control checklist
|
||||
|
||||
|
||||
Reference in New Issue
Block a user