Pull MinIO and Caddy instead of compiling them on the server
Both images had to be compiled where the stack runs - MinIO from source because upstream publishes no image for the security release, Caddy through xcaddy for the caddy-l4 module. On a small VM that failed: the Go builds run out of disk and memory, and an install that has to compile two programs is a poor way to start a database. They are now built once, for amd64 and arm64, and published to Docker Hub as luciolelii/minio and luciolelii/caddy-l4. Each tag is the version its Dockerfile pins, read from the Dockerfile by publish-images.sh so the two cannot drift: RELEASE.2025-10-15T17-29-55Z for MinIO, and 2.11.4-l4-v0.1.2 (Caddy, then the module) for Caddy. docker-compose.yml names those tags, overridable with MINIO_IMAGE and CADDY_IMAGE. The Dockerfiles stay, as the source of the images. The MinIO image still runs as 1000:1000, so what the README says about the data directory's owner stands. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
169ad32f0b
commit
c576a44e6f
|
|
@ -33,6 +33,11 @@ PGADMIN_DEFAULT_PASSWORD=replace-with-a-third-independent-random-password
|
|||
# Optional image override. Keep the same major version when upgrading an existing volume.
|
||||
POSTGRES_IMAGE=postgres:17.11-alpine
|
||||
|
||||
# The other two images are pinned in docker-compose.yml to the versions their Dockerfiles build,
|
||||
# and pulled from Docker Hub (luciolelii/minio, luciolelii/caddy-l4). Override only to test another:
|
||||
# MINIO_IMAGE=luciolelii/minio:RELEASE.2025-10-15T17-29-55Z
|
||||
# CADDY_IMAGE=luciolelii/caddy-l4:2.11.4-l4-v0.1.2
|
||||
|
||||
# Where the two big data sets live. Leave both unset to keep them in Docker volumes, under
|
||||
# /var/lib/docker. To use a larger disk, give an absolute path to a directory ON it - a
|
||||
# subdirectory, never the mount point itself, which on ext4 holds lost+found and makes PostgreSQL
|
||||
|
|
|
|||
40
README.md
40
README.md
|
|
@ -21,12 +21,19 @@ point; traffic from Caddy to the services stays on an internal Docker network. C
|
|||
ACME account, certificates and private keys in `caddy-data`, so restarts do not trigger unnecessary
|
||||
certificate reissuance.
|
||||
|
||||
The Caddy image is built with the pinned `caddy-l4` module because stock Caddy only proxies HTTP.
|
||||
The module understands PostgreSQL's initial `SSLRequest`, terminates TLS with Caddy's automatically
|
||||
managed certificate, and sends the decrypted connection to PostgreSQL only on the private network.
|
||||
Two of the images are not stock ones, so they are built once, from `caddy.Dockerfile` and
|
||||
`minio.Dockerfile`, and published to Docker Hub; the server only pulls them and compiles nothing.
|
||||
|
||||
The MinIO server is built from its latest upstream security release. Upstream did not publish a
|
||||
container for that release, so the included multi-stage Dockerfile builds the pinned source tag.
|
||||
- `luciolelii/caddy-l4` is Caddy with the pinned `caddy-l4` module, because stock Caddy only proxies
|
||||
HTTP. The module understands PostgreSQL's initial `SSLRequest`, terminates TLS with Caddy's
|
||||
automatically managed certificate, and sends the decrypted connection to PostgreSQL only on the
|
||||
private network.
|
||||
- `luciolelii/minio` is MinIO built from its latest upstream security release. Upstream did not
|
||||
publish a container for that release, so the Dockerfile builds the pinned source tag.
|
||||
|
||||
Each image's tag is the version its Dockerfile pins (`RELEASE.2025-10-15T17-29-55Z`, and
|
||||
`2.11.4-l4-v0.1.2` for Caddy version then module version), and `docker-compose.yml` names that tag.
|
||||
Both are built for amd64 and arm64.
|
||||
|
||||
pgAdmin is pinned to version 9.18 and runs in server mode. Its users, sessions, preferences and
|
||||
saved server definitions live in the `pgadmin-data` volume.
|
||||
|
|
@ -43,7 +50,8 @@ saved server definitions live in the `pgadmin-data` volume.
|
|||
cp .env.example .env
|
||||
openssl rand -base64 36
|
||||
docker compose config --quiet
|
||||
docker compose up -d --build
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
4. Follow certificate issuance and startup:
|
||||
|
|
@ -116,7 +124,7 @@ The two are independent: set one or both. Unset (or empty) means the named volum
|
|||
sudo chown 1000:1000 /mnt/bigdisk/minio # MinIO, see minio.Dockerfile
|
||||
```
|
||||
|
||||
2. **A new installation** needs nothing more: set the variables and `docker compose up -d --build`.
|
||||
2. **A new installation** needs nothing more: set the variables and `docker compose up -d`.
|
||||
|
||||
3. **An installation that already holds data** must copy it first. Do not use `-v` anywhere:
|
||||
|
||||
|
|
@ -125,7 +133,7 @@ The two are independent: set one or both. Unset (or empty) means the named volum
|
|||
docker run --rm -v humainflow-data-stack_postgres-data:/from -v /mnt/bigdisk/postgres:/to alpine cp -a /from/. /to/
|
||||
docker run --rm -v humainflow-data-stack_minio-data:/from -v /mnt/bigdisk/minio:/to alpine cp -a /from/. /to/
|
||||
# set the two variables in .env, then
|
||||
docker compose up -d --build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The volume names carry the project name from `name:` in the compose file. Keep the old volumes
|
||||
|
|
@ -145,5 +153,19 @@ Cautions:
|
|||
An earlier version used `POSTGRES_DOMAIN`, `MINIO_API_DOMAIN`, `MINIO_CONSOLE_DOMAIN` and
|
||||
`PGADMIN_DOMAIN`. Replace them in `.env` with a single `DATA_DOMAIN` (any one of the old names will
|
||||
do, as long as it resolves to this server), open ports `9443` and `5443`, and run
|
||||
`docker compose up -d --build`. Data volumes are untouched. Addresses change: the console moves from
|
||||
`docker compose up -d`. Data volumes are untouched. Addresses change: the console moves from
|
||||
its own name to `:9443`, pgAdmin to `:5443`, and PostgreSQL clients connect to `DATA_DOMAIN`.
|
||||
|
||||
## Publishing the MinIO and Caddy images
|
||||
|
||||
Only needed to change a version. Edit the version in the Dockerfile (`ARG MINIO_VERSION` in
|
||||
`minio.Dockerfile`; the `caddy:` tag and the `caddy-l4@` version in `caddy.Dockerfile`), then, from a
|
||||
machine with Docker and a Docker Hub login (`docker login -u luciolelii`, with an access token that can
|
||||
write):
|
||||
|
||||
```sh
|
||||
./publish-images.sh # both; or: ./publish-images.sh minio ./publish-images.sh caddy
|
||||
```
|
||||
|
||||
and set the new tag in `docker-compose.yml` (or `MINIO_IMAGE` / `CADDY_IMAGE` in `.env`). If the Docker
|
||||
Hub repositories are private, run `docker login` on the server before `docker compose pull`.
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ services:
|
|||
logging: *default-logging
|
||||
|
||||
minio:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: minio.Dockerfile
|
||||
# Pinned to the version minio.Dockerfile builds. Upstream publishes no image for this release, so
|
||||
# the image is built and pushed by publish-images.sh; the server only pulls it.
|
||||
image: ${MINIO_IMAGE:-luciolelii/minio:RELEASE.2025-10-15T17-29-55Z}
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${MINIO_ROOT_USER:?set MINIO_ROOT_USER in .env}
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?set MINIO_ROOT_PASSWORD in .env}
|
||||
|
|
@ -105,9 +105,9 @@ services:
|
|||
logging: *default-logging
|
||||
|
||||
caddy:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: caddy.Dockerfile
|
||||
# Caddy with the caddy-l4 module, built from caddy.Dockerfile by publish-images.sh. The tag is the
|
||||
# Caddy version followed by the module's.
|
||||
image: ${CADDY_IMAGE:-luciolelii/caddy-l4:2.11.4-l4-v0.1.2}
|
||||
environment:
|
||||
TLS_CONTACT: ${TLS_CONTACT:?set TLS_CONTACT in .env}
|
||||
DATA_DOMAIN: ${DATA_DOMAIN:?set DATA_DOMAIN in .env}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#!/bin/sh
|
||||
# Builds the two images this stack would otherwise compile on the server - MinIO and Caddy with the
|
||||
# caddy-l4 module - for amd64 and arm64 and pushes them to Docker Hub.
|
||||
# Usage: ./publish-images.sh [minio] [caddy] (default: both)
|
||||
#
|
||||
# The tag is the version the Dockerfile pins, read from it, so the two cannot drift apart:
|
||||
# luciolelii/minio:RELEASE.2025-10-15T17-29-55Z
|
||||
# luciolelii/caddy-l4:2.11.4-l4-v0.1.2 (Caddy version, then the caddy-l4 version)
|
||||
# "latest" is pushed too, but docker-compose.yml names the version tag. Changing a version in a
|
||||
# Dockerfile and re-running this is how an upgrade is published.
|
||||
set -eu
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
REGISTRY="${REGISTRY:-luciolelii}"
|
||||
PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
|
||||
BUILDER="${BUILDER:-mcp-publisher}"
|
||||
|
||||
# A multi-platform build needs a builder that can run both architectures; Docker's default one
|
||||
# cannot push a multi-platform image.
|
||||
docker buildx inspect "$BUILDER" >/dev/null 2>&1 \
|
||||
|| docker buildx create --name "$BUILDER" --driver docker-container --bootstrap
|
||||
|
||||
publish() {
|
||||
name="$1"; dockerfile="$2"; tag="$3"
|
||||
echo "==> $REGISTRY/$name:$tag ($PLATFORMS)"
|
||||
docker buildx build --builder "$BUILDER" --platform "$PLATFORMS" -f "$dockerfile" \
|
||||
-t "$REGISTRY/$name:$tag" -t "$REGISTRY/$name:latest" --push .
|
||||
}
|
||||
|
||||
minio_tag() { sed -n 's/^ARG MINIO_VERSION=//p' minio.Dockerfile; }
|
||||
caddy_tag() {
|
||||
caddy="$(sed -n 's/^FROM caddy:\(.*\)-builder-alpine.*/\1/p' caddy.Dockerfile)"
|
||||
l4="$(sed -n 's/.*caddy-l4@\(v[0-9.]*\).*/\1/p' caddy.Dockerfile)"
|
||||
echo "$caddy-l4-$l4"
|
||||
}
|
||||
|
||||
targets="${*:-minio caddy}"
|
||||
for target in $targets; do
|
||||
case "$target" in
|
||||
minio) publish minio minio.Dockerfile "$(minio_tag)" ;;
|
||||
caddy) publish caddy-l4 caddy.Dockerfile "$(caddy_tag)" ;;
|
||||
*) echo "Unknown image: $target (expected minio or caddy)" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
Loading…
Reference in New Issue