Dockerfile builds warp-aio on SQLite, Dockerfile.PocketBase builds warp-aio-pocketbase and Dockerfile.PostgreSQL builds warp-aio-postgresql with PostgreSQL bundled. The database driver and connection string now come from the image, so the SQLite and PocketBase images no longer carry PostgreSQL (103 MB instead of 149 MB). The AIO compose files point at their own Dockerfile and image, and the entrypoint refuses to start an embedded PostgreSQL in an image that has none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
109 lines
3.2 KiB
Bash
109 lines
3.2 KiB
Bash
#!/bin/sh
|
|
# warp-aio: runs the homeserver, the admin panel and the web client (and,
|
|
# with WARP_AIO_EMBEDDED_POSTGRES=true, PostgreSQL) in one container.
|
|
#
|
|
# If any of them exits, the others are stopped and the container exits, so
|
|
# the restart policy brings the whole set back. SIGTERM stops the clients
|
|
# first, then the homeserver, then PostgreSQL.
|
|
#
|
|
# With arguments, runs them instead: `docker run warp-aio warp version`.
|
|
#
|
|
# WARP_AIO_ADMIN=false no admin panel
|
|
# WARP_AIO_WEB=false no web client
|
|
# WARP_AIO_EMBEDDED_POSTGRES=true PostgreSQL in the container, data in
|
|
# $PGDATA (/data/postgres); the default
|
|
# in warp-aio-postgresql, the only image
|
|
# that has PostgreSQL
|
|
|
|
set -eu
|
|
|
|
if [ "$#" -gt 0 ]; then
|
|
exec "$@"
|
|
fi
|
|
|
|
log() { echo "warp-aio: $*" >&2; }
|
|
|
|
pg_pid=""
|
|
warp_pid=""
|
|
admin_pid=""
|
|
web_pid=""
|
|
|
|
# stop PID...: SIGTERM, then wait for each to exit.
|
|
stop() {
|
|
for pid in "$@"; do
|
|
[ -n "$pid" ] && kill -TERM "$pid" 2>/dev/null || true
|
|
done
|
|
for pid in "$@"; do
|
|
[ -n "$pid" ] && wait "$pid" 2>/dev/null || true
|
|
done
|
|
}
|
|
|
|
shutdown() {
|
|
trap '' TERM INT
|
|
stop "$web_pid" "$admin_pid"
|
|
stop "$warp_pid"
|
|
if [ -n "$pg_pid" ]; then
|
|
# SIGINT is PostgreSQL's fast shutdown: it does not wait for
|
|
# clients, and the homeserver is gone by now anyway.
|
|
kill -INT "$pg_pid" 2>/dev/null || true
|
|
wait "$pg_pid" 2>/dev/null || true
|
|
fi
|
|
exit "${1:-0}"
|
|
}
|
|
trap 'log "stopping"; shutdown 0' TERM INT
|
|
|
|
if [ "$WARP_AIO_EMBEDDED_POSTGRES" = true ]; then
|
|
if ! command -v postgres >/dev/null; then
|
|
log "WARP_AIO_EMBEDDED_POSTGRES=true, but this image has no PostgreSQL; use warp-aio-postgresql"
|
|
exit 1
|
|
fi
|
|
export PGDATA="${PGDATA:-/data/postgres}"
|
|
if [ ! -s "$PGDATA/PG_VERSION" ]; then
|
|
log "initialising PostgreSQL in $PGDATA"
|
|
# Trust is safe here: PostgreSQL listens on no TCP address, only on
|
|
# a socket inside this container.
|
|
initdb -D "$PGDATA" -U warp --auth=trust --encoding=UTF8 --locale=C >/dev/null
|
|
fi
|
|
postgres -D "$PGDATA" -c listen_addresses='' -c unix_socket_directories=/run/postgresql &
|
|
pg_pid=$!
|
|
until pg_isready -q -h /run/postgresql -U warp; do
|
|
kill -0 "$pg_pid" 2>/dev/null || { log "PostgreSQL failed to start"; exit 1; }
|
|
sleep 1
|
|
done
|
|
if [ "$(psql -h /run/postgresql -U warp -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = 'warp'")" != 1 ]; then
|
|
createdb -h /run/postgresql -U warp warp
|
|
fi
|
|
fi
|
|
|
|
# The signing key is created on first start and kept in the volume: losing
|
|
# it means other servers no longer recognise this one.
|
|
if [ ! -f "$WARP_PRIVATE_KEY" ]; then
|
|
warp generate-keys --output "$WARP_PRIVATE_KEY"
|
|
fi
|
|
|
|
warp serve &
|
|
warp_pid=$!
|
|
|
|
if [ "$WARP_AIO_ADMIN" = true ]; then
|
|
warp-admin &
|
|
admin_pid=$!
|
|
fi
|
|
if [ "$WARP_AIO_WEB" = true ]; then
|
|
warp-web &
|
|
web_pid=$!
|
|
fi
|
|
|
|
# Busybox sh has no `wait -n`, so check on the processes every second. The
|
|
# sleep runs in the background so a signal is handled at once.
|
|
while :; do
|
|
for entry in "postgres:$pg_pid" "warp:$warp_pid" "warp-admin:$admin_pid" "warp-web:$web_pid"; do
|
|
pid="${entry#*:}"
|
|
if [ -n "$pid" ] && ! kill -0 "$pid" 2>/dev/null; then
|
|
log "${entry%%:*} exited; stopping the rest"
|
|
shutdown 1
|
|
fi
|
|
done
|
|
sleep 1 &
|
|
wait $! || true
|
|
done
|