Add polling Docker deployments
Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -41,6 +41,16 @@ prebuilt package assets, Monaco, and the persistent SQLite volume. Configure the
|
|||||||
path in `compose.yaml`. The default port binding is private to the VPS at `127.0.0.1:5002`; put
|
path in `compose.yaml`. The default port binding is private to the VPS at `127.0.0.1:5002`; put
|
||||||
Caddy or nginx in front of it for HTTPS. Follow logs with `docker compose logs -f yawn`.
|
Caddy or nginx in front of it for HTTPS. Follow logs with `docker compose logs -f yawn`.
|
||||||
|
|
||||||
|
To check for new pushes every minute, add this entry with `crontab -e`:
|
||||||
|
|
||||||
|
```cron
|
||||||
|
* * * * * $HOME/yawn/server/poll-deploy.sh >> $HOME/yawn-deploy.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
The poller compares `origin/main` with the last healthy deployed revision and does nothing when they
|
||||||
|
match. A shared lock prevents overlapping manual and scheduled deployments. Failed deployments do
|
||||||
|
not update the revision marker, so the next poll retries them.
|
||||||
|
|
||||||
Run the previous VitePress documentation site with `npm start`.
|
Run the previous VitePress documentation site with `npm start`.
|
||||||
|
|
||||||
Run `npm run coredocs` for the raw worker-message, shared-memory, and render-graph reference intended for custom handles, editors, and direct SAB clients.
|
Run `npm run coredocs` for the raw worker-message, shared-memory, and render-graph reference intended for custom handles, editors, and direct SAB clients.
|
||||||
|
|||||||
+19
-6
@@ -3,13 +3,16 @@ set -euo pipefail
|
|||||||
|
|
||||||
repository="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
repository="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
expected_repository="$HOME/yawn"
|
expected_repository="$HOME/yawn"
|
||||||
|
state_directory="$HOME/.local/state/yawn"
|
||||||
|
deployed_revision_file="$state_directory/deployed-revision"
|
||||||
|
compose=(docker compose --project-name yawn --project-directory "$repository" --file "$repository/compose.yaml")
|
||||||
|
|
||||||
if [[ "$repository" != "$expected_repository" ]]; then
|
if [[ "$repository" != "$expected_repository" ]]; then
|
||||||
printf 'Expected the repository at %s, found %s\n' "$expected_repository" "$repository" >&2
|
printf 'Expected the repository at %s, found %s\n' "$expected_repository" "$repository" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for command in git docker; do
|
for command in git docker flock; do
|
||||||
if ! command -v "$command" >/dev/null 2>&1; then
|
if ! command -v "$command" >/dev/null 2>&1; then
|
||||||
printf 'Missing required command: %s\n' "$command" >&2
|
printf 'Missing required command: %s\n' "$command" >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -20,6 +23,13 @@ if ! docker compose version >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$state_directory"
|
||||||
|
exec 9>"$state_directory/deploy.lock"
|
||||||
|
if ! flock -n 9; then
|
||||||
|
printf 'Another Yawn deployment is already running.\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
cd "$repository"
|
cd "$repository"
|
||||||
|
|
||||||
if [[ "$(git branch --show-current)" != "main" ]]; then
|
if [[ "$(git branch --show-current)" != "main" ]]; then
|
||||||
@@ -41,10 +51,10 @@ if [[ "$(git rev-parse HEAD)" != "$fetched" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
printf 'Building the production image...\n'
|
printf 'Building the production image...\n'
|
||||||
docker compose build --pull yawn
|
"${compose[@]}" build --pull yawn
|
||||||
docker compose up -d --remove-orphans yawn
|
"${compose[@]}" up -d --remove-orphans yawn
|
||||||
|
|
||||||
container="$(docker compose ps -q yawn)"
|
container="$("${compose[@]}" ps -q yawn)"
|
||||||
if [[ -z "$container" ]]; then
|
if [[ -z "$container" ]]; then
|
||||||
printf 'Docker Compose did not create the Yawn container.\n' >&2
|
printf 'Docker Compose did not create the Yawn container.\n' >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -55,11 +65,14 @@ for _ in {1..60}; do
|
|||||||
status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container")"
|
status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container")"
|
||||||
case "$status" in
|
case "$status" in
|
||||||
healthy)
|
healthy)
|
||||||
|
temporary_revision="$(mktemp "$state_directory/deployed-revision.XXXXXX")"
|
||||||
|
git rev-parse HEAD >"$temporary_revision"
|
||||||
|
mv -f -- "$temporary_revision" "$deployed_revision_file"
|
||||||
printf 'The Yawn container is healthy.\n'
|
printf 'The Yawn container is healthy.\n'
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
unhealthy | exited | dead)
|
unhealthy | exited | dead)
|
||||||
docker compose logs --tail 50 yawn >&2
|
"${compose[@]}" logs --tail 50 yawn >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -67,5 +80,5 @@ for _ in {1..60}; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
printf 'Yawn did not become healthy before the timeout.\n' >&2
|
printf 'Yawn did not become healthy before the timeout.\n' >&2
|
||||||
docker compose logs --tail 50 yawn >&2
|
"${compose[@]}" logs --tail 50 yawn >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Executable
+67
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repository="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
expected_repository="$HOME/yawn"
|
||||||
|
state_directory="$HOME/.local/state/yawn"
|
||||||
|
deployed_revision_file="$state_directory/deployed-revision"
|
||||||
|
compose=(docker compose --project-name yawn --project-directory "$repository" --file "$repository/compose.yaml")
|
||||||
|
|
||||||
|
if [[ "$repository" != "$expected_repository" ]]; then
|
||||||
|
printf 'Expected the repository at %s, found %s\n' "$expected_repository" "$repository" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for command in git docker flock; do
|
||||||
|
if ! command -v "$command" >/dev/null 2>&1; then
|
||||||
|
printf 'Missing required command: %s\n' "$command" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
printf 'Docker Compose v2 is required.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$state_directory"
|
||||||
|
exec 9>"$state_directory/deploy.lock"
|
||||||
|
if ! flock -n 9; then
|
||||||
|
printf 'Another Yawn deployment is already running.\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$repository"
|
||||||
|
if [[ "$(git branch --show-current)" != "main" ]]; then
|
||||||
|
printf 'Deployments must run from the main branch.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -n "$(git status --porcelain --untracked-files=normal)" ]]; then
|
||||||
|
printf 'Refusing to deploy a checkout with local changes.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
git fetch origin main
|
||||||
|
remote_revision="$(git rev-parse FETCH_HEAD)"
|
||||||
|
current_revision="$(git rev-parse HEAD)"
|
||||||
|
deployed_revision=""
|
||||||
|
if [[ -f "$deployed_revision_file" ]]; then
|
||||||
|
read -r deployed_revision <"$deployed_revision_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
container="$("${compose[@]}" ps -q yawn 2>/dev/null || true)"
|
||||||
|
container_status="missing"
|
||||||
|
if [[ -n "$container" ]]; then
|
||||||
|
container_status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container" 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$current_revision" == "$remote_revision" &&
|
||||||
|
"$deployed_revision" == "$remote_revision" &&
|
||||||
|
"$container_status" == "healthy" ]]; then
|
||||||
|
printf 'Yawn is already running revision %s.\n' "${remote_revision:0:12}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Deploying revision %s...\n' "${remote_revision:0:12}"
|
||||||
|
flock -u 9
|
||||||
|
exec 9>&-
|
||||||
|
"$repository/server/deploy-docker.sh"
|
||||||
Reference in New Issue
Block a user