Files
Warp/Docker-AIO/entrypoint.sh
T
tajniak81andClaude Opus 5.5 89f89b5d36 Docker-AIO: one image per database
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>
2026-10-22 20:22:24 +02:00

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