Deploy Forgejo trial instance
This commit is contained in:
parent
ff560ea84c
commit
b49138d95a
4 changed files with 580 additions and 0 deletions
216
docs/forgejo-operations.md
Normal file
216
docs/forgejo-operations.md
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
# Forgejo trial operations
|
||||
|
||||
This runbook covers the initial Forgejo trial on Tobserver. The complete
|
||||
service, SQLite, package, and nginx configuration lives in
|
||||
`modules/forgejo.nix`.
|
||||
|
||||
> **Warning:** This trial is unprotected. It has no Forgejo backup job, and its
|
||||
> data must be treated as disposable. Keep the authoritative copy of anything
|
||||
> important somewhere else.
|
||||
|
||||
Run deployment commands from the Tobserver checkout unless noted otherwise.
|
||||
Never place passwords or other credentials in Git, Nix expressions, command
|
||||
arguments, shell history, logs, or issue comments.
|
||||
|
||||
## Pre-deployment checks
|
||||
|
||||
Confirm that the dedicated hostname points only to Tobserver:
|
||||
|
||||
```console
|
||||
test "$(dig +short git.tobiasostner.de A)" = "162.55.103.218"
|
||||
test -z "$(dig +short git.tobiasostner.de AAAA)"
|
||||
```
|
||||
|
||||
On a workstation, evaluate the configuration and build it on a compatible Linux
|
||||
builder when one is available:
|
||||
|
||||
```console
|
||||
nix flake check --no-build
|
||||
nix build .#nixosConfigurations.tobserver.config.system.build.toplevel
|
||||
```
|
||||
|
||||
Commit and push the reviewed changes. On Tobserver, update a clean checkout and
|
||||
build without activating it:
|
||||
|
||||
```console
|
||||
cd ~/tobserver
|
||||
test -z "$(git status --porcelain)" || {
|
||||
echo "Refusing to deploy from a dirty checkout" >&2
|
||||
exit 1
|
||||
}
|
||||
git pull --ff-only
|
||||
git rev-parse HEAD
|
||||
nix flake check --no-build
|
||||
|
||||
if sudo test -e /var/lib/forgejo \
|
||||
&& sudo find /var/lib/forgejo -mindepth 1 -print -quit | grep -q .; then
|
||||
echo "Refusing to reuse non-empty Forgejo state" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo nixos-rebuild build --flake .#tobserver
|
||||
```
|
||||
|
||||
Compare the printed commit with the reviewed deployment commit. Do not continue
|
||||
if evaluation, the full host build, or the empty-state check fails.
|
||||
|
||||
## Activation and service checks
|
||||
|
||||
Activate the configuration only after reviewing the successful build. Immediately
|
||||
before switching, recheck that the checkout is clean and still at the reviewed
|
||||
commit printed during the build step:
|
||||
|
||||
```console
|
||||
read -r -p 'Reviewed commit hash: ' reviewed_commit
|
||||
test -z "$(git status --porcelain)" || {
|
||||
echo "Refusing to switch from a dirty checkout" >&2
|
||||
exit 1
|
||||
}
|
||||
current_commit="$(git rev-parse HEAD)"
|
||||
printf 'Switching commit: %s\n' "$current_commit"
|
||||
test "$current_commit" = "$reviewed_commit" || {
|
||||
echo "Refusing to switch an unreviewed commit" >&2
|
||||
exit 1
|
||||
}
|
||||
sudo nixos-rebuild switch --flake .#tobserver
|
||||
unset current_commit reviewed_commit
|
||||
```
|
||||
|
||||
Verify the services, loopback-only backend, local API, rendered nginx
|
||||
configuration, and public HTTPS endpoint:
|
||||
|
||||
```console
|
||||
sudo systemctl is-active forgejo.service nginx.service
|
||||
sudo ss -H -ltn 'sport = :3001'
|
||||
|
||||
curl --fail --silent --show-error \
|
||||
-H 'Host: git.tobiasostner.de' \
|
||||
http://127.0.0.1:3001/api/v1/version \
|
||||
| jq -e .
|
||||
|
||||
sudo nginx -t
|
||||
(
|
||||
set -euo pipefail
|
||||
nginx_config="$(sudo nginx -T 2>&1)"
|
||||
for required_line in \
|
||||
'git.tobiasostner.de' \
|
||||
'merge_slashes off' \
|
||||
'client_max_body_size 512M' \
|
||||
'proxy_set_header Host $host' \
|
||||
'proxy_set_header X-Real-IP $remote_addr' \
|
||||
'proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for' \
|
||||
'proxy_set_header X-Forwarded-Proto $scheme' \
|
||||
'proxy_set_header Connection $http_connection' \
|
||||
'proxy_set_header Upgrade $http_upgrade'
|
||||
do
|
||||
printf '%s\n' "$nginx_config" | grep -F -- "$required_line" >/dev/null
|
||||
done
|
||||
)
|
||||
|
||||
curl --fail --silent --show-error --location \
|
||||
--output /dev/null \
|
||||
--write-out '%{http_code} %{url_effective}\n' \
|
||||
http://git.tobiasostner.de/
|
||||
```
|
||||
|
||||
The listener output must contain `127.0.0.1:3001` and no non-loopback address.
|
||||
The public request must report HTTP 200 at `https://git.tobiasostner.de/`.
|
||||
Port 3001 must not be reachable from an external machine:
|
||||
|
||||
```console
|
||||
! nc -z git.tobiasostner.de 3001
|
||||
```
|
||||
|
||||
If a check fails, inspect logs before restarting or changing state:
|
||||
|
||||
```console
|
||||
sudo journalctl \
|
||||
-u forgejo.service \
|
||||
-u nginx.service \
|
||||
--since '-15 minutes' \
|
||||
--no-pager
|
||||
```
|
||||
|
||||
## Create the first administrator
|
||||
|
||||
Run this once in an interactive shell on Tobserver. Enter the administrator
|
||||
email when prompted; it stays in the shell variable and is not recorded in this
|
||||
runbook or shell history.
|
||||
|
||||
```console
|
||||
read -r -p 'Admin email: ' admin_email
|
||||
sudo -u forgejo env \
|
||||
HOME=/var/lib/forgejo \
|
||||
USER=forgejo \
|
||||
FORGEJO_WORK_DIR=/var/lib/forgejo \
|
||||
FORGEJO_CUSTOM=/var/lib/forgejo/custom \
|
||||
forgejo --config /var/lib/forgejo/custom/conf/app.ini \
|
||||
admin user create \
|
||||
--username "oibot" \
|
||||
--email "$admin_email" \
|
||||
--admin \
|
||||
--random-password
|
||||
unset admin_email
|
||||
```
|
||||
|
||||
The command prints a generated password once. Copy it directly into the
|
||||
approved password manager immediately, then clear the terminal. Do not redirect,
|
||||
pipe, log, or save the output in a temporary file, and do not choose a password
|
||||
on the command line.
|
||||
|
||||
Confirm that the account is an administrator:
|
||||
|
||||
```console
|
||||
sudo -u forgejo env \
|
||||
HOME=/var/lib/forgejo \
|
||||
USER=forgejo \
|
||||
FORGEJO_WORK_DIR=/var/lib/forgejo \
|
||||
FORGEJO_CUSTOM=/var/lib/forgejo/custom \
|
||||
forgejo --config /var/lib/forgejo/custom/conf/app.ini \
|
||||
admin user list --admin \
|
||||
| grep -F -- 'oibot'
|
||||
```
|
||||
|
||||
Sign in at `https://git.tobiasostner.de/` and confirm that the interface does
|
||||
not offer public registration.
|
||||
|
||||
## Disposable HTTPS and SSH smoke test
|
||||
|
||||
In the Forgejo interface:
|
||||
|
||||
1. Add the external client's public SSH key to the `oibot` account.
|
||||
2. Create an empty repository named `clone-smoke`.
|
||||
|
||||
From an external client, exercise HTTPS clone and push with a disposable commit:
|
||||
|
||||
```console
|
||||
workdir="$(mktemp -d)"
|
||||
git clone https://git.tobiasostner.de/oibot/clone-smoke.git \
|
||||
"$workdir/clone-smoke-https"
|
||||
cd "$workdir/clone-smoke-https"
|
||||
printf '%s\n' 'Forgejo trial' > README.md
|
||||
git add README.md
|
||||
git commit -m 'Test Forgejo trial'
|
||||
git push origin HEAD:main
|
||||
```
|
||||
|
||||
Then exercise host OpenSSH clone and fetch:
|
||||
|
||||
```console
|
||||
git clone forgejo@git.tobiasostner.de:oibot/clone-smoke.git \
|
||||
"$workdir/clone-smoke-ssh"
|
||||
git -C "$workdir/clone-smoke-ssh" fetch origin
|
||||
rm -rf -- "$workdir"
|
||||
```
|
||||
|
||||
All clone, push, and fetch commands must exit successfully. The repository and
|
||||
commit are disposable trial data.
|
||||
|
||||
## Trial rollback boundary
|
||||
|
||||
Tobserver hosts unrelated services, so do not use a broad live NixOS generation
|
||||
rollback as a routine Forgejo test. If the service is unhealthy, collect its
|
||||
status and journals first. Prepare and review a narrow change that removes only
|
||||
the `modules/forgejo.nix` import and its Forgejo service and nginx virtual host.
|
||||
Preserve `/var/lib/forgejo`; never delete trial state as an automatic rollback
|
||||
action.
|
||||
Loading…
Add table
Add a link
Reference in a new issue