diff --git a/compose.yaml b/compose.yaml index cb80a8d..a928f49 100644 --- a/compose.yaml +++ b/compose.yaml @@ -17,7 +17,7 @@ services: retries: 20 minio: - image: quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e + image: docker.io/pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372 restart: unless-stopped command: server /data --console-address :9001 environment: diff --git a/deploy/dokploy/blueprints/blogfactory/docker-compose.yml b/deploy/dokploy/blueprints/blogfactory/docker-compose.yml index 682f9a5..32639e0 100644 --- a/deploy/dokploy/blueprints/blogfactory/docker-compose.yml +++ b/deploy/dokploy/blueprints/blogfactory/docker-compose.yml @@ -17,7 +17,7 @@ services: retries: 20 minio: - image: quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e + image: docker.io/pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372 restart: unless-stopped command: server /data --console-address :9001 environment: diff --git a/deploy/railway/README.md b/deploy/railway/README.md index 7e9b6ab..c85a3f0 100644 --- a/deploy/railway/README.md +++ b/deploy/railway/README.md @@ -7,7 +7,7 @@ The public template maps the canonical Compose stack to five Railway services so | `web` | `ghcr.io/blogfactoryhq/blogfactory-web:v0.1.0` | yes | `PORT=80`; `API_UPSTREAM=http://${{api.RAILWAY_PRIVATE_DOMAIN}}:3000` | | `api` | `ghcr.io/blogfactoryhq/blogfactory-api:v0.1.0` | no | pre-deploy `bun run src/init-s3-bucket.ts`; variables below; health path `/api/ready` | | `Postgres` | Railway managed PostgreSQL | no | managed service defaults | -| `minio` | `quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e` | no | command `/usr/bin/minio server /data --address :9000 --console-address :9001`; volume mounted at `/data` | +| `minio` | `docker.io/pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372` | no | command `/usr/bin/minio server /data --address :9000 --console-address :9001`; volume mounted at `/data` | | `cron` | `ghcr.io/blogfactoryhq/blogfactory-api:v0.1.0` | no | command `bun run src/run-cron-once.ts`; cron `0 */6 * * *`; restart `NEVER` | The template asks only for `ADMIN_EMAILS`. It generates independent values for `JWT_SECRET`, `API_KEY_ENCRYPTION_SECRET`, `CRON_SECRET`, and `MINIO_ROOT_PASSWORD` with Railway template variable functions. Do not publish a template with literal defaults. @@ -34,7 +34,7 @@ S3_BUCKET=blogfactory S3_REGION=us-east-1 ``` -MinIO uses `MINIO_ROOT_USER=blogfactory`, a generated `MINIO_ROOT_PASSWORD`, and port `9000`. Mount a 500 MB persistent volume at `/data` on Railway Hobby. Before each API deployment, Railway runs the following idempotent pre-deploy command with the API's `S3_*` variables: +The `minio` image is the AGPL-3.0 community fork `pgsty/minio` (`RELEASE.2026-08-04T00-00-00Z`), because upstream MinIO images are no longer pullable. MinIO uses `MINIO_ROOT_USER=blogfactory`, a generated `MINIO_ROOT_PASSWORD`, and port `9000`. Mount a 500 MB persistent volume at `/data` on Railway Hobby. Before each API deployment, Railway runs the following idempotent pre-deploy command with the API's `S3_*` variables: ```sh bun run src/init-s3-bucket.ts diff --git a/docs/self-hosting.md b/docs/self-hosting.md index 1a17451..4e036ef 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -157,6 +157,10 @@ docker compose up -d If the older application is incompatible with the migrated schema, restore the pre-upgrade PostgreSQL dump and matching MinIO copy instead of trying to reverse migrations. +### MinIO image source + +Upstream MinIO no longer publishes pullable images: `quay.io/minio/minio` and Docker Hub `minio/minio` return `unauthorized`, and the `minio/minio` repository is archived. Compose, Dokploy, and Railway pin the AGPL-3.0 community fork [`pgsty/minio`](https://github.com/pgsty/minio) by digest. It is the same server and bundled `mc` client with the same environment variables, health endpoint, and on-disk format, so an existing `minio-data` volume starts unchanged. After a verified backup, pick up the new pin with `docker compose pull minio && docker compose up -d`. + ## Dokploy runbook The upstream-compatible blueprint is in [`deploy/dokploy/blueprints/blogfactory`](../deploy/dokploy/blueprints/blogfactory). It creates web, API, scheduler, PostgreSQL, and MinIO services with persistent database and object-storage volumes. Only web receives a Dokploy domain. The API initializes the S3 bucket and runs locked additive migrations before serving. diff --git a/scripts/self-host-backup-restore-smoke.sh b/scripts/self-host-backup-restore-smoke.sh index 5cf9e7f..d5f6ebb 100755 --- a/scripts/self-host-backup-restore-smoke.sh +++ b/scripts/self-host-backup-restore-smoke.sh @@ -47,7 +47,7 @@ storage_path="$(jq -er '.storagePath // .storage_path' "$tmp_dir/upload.json")" "${source_compose[@]}" stop api scheduler "${source_compose[@]}" exec -T postgres pg_dump -U blogfactory -d blogfactory -Fc > "$tmp_dir/blogfactory.dump" mkdir "$tmp_dir/objects" -docker run --rm --user "$(id -u):$(id -g)" --network "${source_project}_default" -e MC_CONFIG_DIR=/tmp/.mc -v "$tmp_dir/objects:/backup" --entrypoint /bin/sh quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e -c \ +docker run --rm --user "$(id -u):$(id -g)" --network "${source_project}_default" -e MC_CONFIG_DIR=/tmp/.mc -v "$tmp_dir/objects:/backup" --entrypoint /bin/sh docker.io/pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372 -c \ 'mc alias set local http://minio:9000 blogfactory minio-backup-0123456789abcdef0123456789abcdef && mc mirror local/blogfactory /backup' "${source_compose[@]}" down --volumes --remove-orphans @@ -55,7 +55,7 @@ docker run --rm --user "$(id -u):$(id -g)" --network "${source_project}_default" for _ in {1..90}; do curl --fail --silent "$base_url/api/ready" >/dev/null && break; sleep 2; done "${target_compose[@]}" stop api scheduler "${target_compose[@]}" exec -T postgres pg_restore -U blogfactory -d blogfactory --clean --if-exists < "$tmp_dir/blogfactory.dump" -docker run --rm --network "${target_project}_default" -v "$tmp_dir/objects:/backup:ro" --entrypoint /bin/sh quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e -c \ +docker run --rm --network "${target_project}_default" -v "$tmp_dir/objects:/backup:ro" --entrypoint /bin/sh docker.io/pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372 -c \ 'mc alias set local http://minio:9000 blogfactory minio-backup-0123456789abcdef0123456789abcdef && mc mirror /backup local/blogfactory' "${target_compose[@]}" start api scheduler for _ in {1..60}; do curl --fail --silent "$base_url/api/ready" >/dev/null && break; sleep 2; done