Skip to content

Commit 89c138d

Browse files
committed
Auto-deploy site under wintermeyer-consulting.de/phoenix/book/
Point site.url at https://wintermeyer-consulting.de/phoenix so the canonical URL of the `book` component renders cleanly as /phoenix/book/<page>.html. Replace the old SSH/rsync-to-static-host workflow with a self-hosted runner workflow (label `eliph`) that builds the UI bundle, runs Antora, and atomically swaps a timestamped release directory under /var/www/elixir-phoenix-ash/current/ on bremen2. The deploy lives in a dedicated OS user and directory so it cannot interfere with wincon on the same host. The old elixir-phoenix-ash.com domain becomes a path-preserving 301 redirect to the new location (nginx-side). Why: we are folding the standalone book site into the Wintermeyer Consulting presence so it shares navigation and styling and so we only operate one public Phoenix ecosystem entry point.
1 parent c4b02f2 commit 89c138d

5 files changed

Lines changed: 108 additions & 116 deletions

File tree

.github/workflows/antora_build_deploy.yml

Lines changed: 0 additions & 115 deletions
This file was deleted.

.github/workflows/deploy.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
deploy:
12+
# Self-hosted runner registered on bremen2 under the `eliph` user,
13+
# with label `eliph`. Pinned so this never lands on wincon's runner
14+
# or any other self-hosted fleet.
15+
runs-on: [self-hosted, eliph]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Deploy
21+
run: ./scripts/deploy.sh

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,18 @@ npm run build && cd .. && npx antora --fetch antora-local-playbook.yml
5252
```
5353

5454
Dark mode follows the OS `prefers-color-scheme`; there is no toggle.
55+
56+
## Deployment
57+
58+
Pushing to `main` triggers `.github/workflows/deploy.yml`, which runs on
59+
a self-hosted runner (label `eliph`) on bremen2. The runner checks the
60+
repo out, runs `scripts/deploy.sh`, and publishes the rendered site to
61+
`/var/www/elixir-phoenix-ash/releases/<timestamp>/`. An atomic symlink
62+
swap makes `/var/www/elixir-phoenix-ash/current/` point at the new
63+
release. The last five releases are kept.
64+
65+
Nginx serves the site under
66+
<https://wintermeyer-consulting.de/phoenix/book/> via two location
67+
blocks on the `wintermeyer-consulting.de` vhost (one for pages, one for
68+
`antora-assets/`). The old domain <https://elixir-phoenix-ash.com>
69+
returns a path-preserving 301 to the new location.

antora-playbook.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
site:
22
title: An Elixir, Phoenix and Ash Beginner's Guide
3-
url: https://elixir-phoenix-ash.com
3+
url: https://wintermeyer-consulting.de/phoenix
44
start_page: book:index.adoc
55
keys:
66
google_analytics: 'G-B4DB8GLK8G'

scripts/deploy.sh

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env bash
2+
# Deploy the Antora site to bremen2 under
3+
# /var/www/elixir-phoenix-ash/releases/<timestamp>/
4+
# and atomically swap the `current` symlink.
5+
#
6+
# Runs on the `eliph` self-hosted GitHub Actions runner from the
7+
# actions/checkout workdir. Invoked as `./scripts/deploy.sh`.
8+
#
9+
# The Antora build needs Node (provided via mise under ~eliph).
10+
11+
set -euo pipefail
12+
13+
# Activate mise so node/npm/npx resolve on the non-interactive shell.
14+
if command -v mise >/dev/null 2>&1; then
15+
eval "$(mise activate bash)"
16+
elif [ -x "$HOME/.local/bin/mise" ]; then
17+
eval "$("$HOME/.local/bin/mise" activate bash)"
18+
fi
19+
20+
APP_DIR="/var/www/elixir-phoenix-ash"
21+
RELEASES_DIR="${APP_DIR}/releases"
22+
CURRENT_LINK="${APP_DIR}/current"
23+
SHARED_DIR="${APP_DIR}/shared"
24+
LOCK_FILE="${SHARED_DIR}/.deploy.lock"
25+
KEEP_RELEASES=5
26+
TIMESTAMP="$(date +%Y%m%d%H%M%S)"
27+
RELEASE_DIR="${RELEASES_DIR}/${TIMESTAMP}"
28+
29+
log() { echo "[$(date '+%H:%M:%S')] $*"; }
30+
31+
mkdir -p "${SHARED_DIR}"
32+
exec 9>"${LOCK_FILE}"
33+
flock -n 9 || { log "ERROR: another deploy is running"; exit 1; }
34+
35+
REPO_DIR="$(pwd)"
36+
log "Repo: ${REPO_DIR}"
37+
38+
log "Building UI bundle..."
39+
( cd "${REPO_DIR}/ui-bundle" && npm ci --no-audit --no-fund && npm run build )
40+
41+
log "Installing Antora..."
42+
( cd "${REPO_DIR}" && npm ci --no-audit --no-fund )
43+
44+
log "Rendering site..."
45+
( cd "${REPO_DIR}" && npx antora --fetch antora-playbook.yml )
46+
47+
if [ ! -d "${REPO_DIR}/build/site/book" ]; then
48+
log "ERROR: expected build/site/book/ not found"
49+
exit 1
50+
fi
51+
52+
log "Publishing release ${TIMESTAMP}..."
53+
mkdir -p "${RELEASE_DIR}"
54+
cp -a "${REPO_DIR}/build/site/." "${RELEASE_DIR}/"
55+
chmod -R a+rX "${RELEASE_DIR}"
56+
57+
log "Atomic swap..."
58+
ln -sfn "${RELEASE_DIR}" "${CURRENT_LINK}.new"
59+
mv -fT "${CURRENT_LINK}.new" "${CURRENT_LINK}"
60+
61+
log "Pruning old releases (keeping last ${KEEP_RELEASES})..."
62+
mapfile -t _old < <(
63+
find "${RELEASES_DIR}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' \
64+
| sort | head -n "-${KEEP_RELEASES}"
65+
)
66+
for r in "${_old[@]}"; do
67+
[ -n "${r}" ] && rm -rf "${RELEASES_DIR:?}/${r}"
68+
done
69+
70+
log "Deploy complete: ${TIMESTAMP}"
71+
log " Active: ${CURRENT_LINK} -> $(readlink -f "${CURRENT_LINK}")"

0 commit comments

Comments
 (0)