-
-
Notifications
You must be signed in to change notification settings - Fork 86
Lightweight tinybird setup wizard and Coolify Docker support for Ghost-6 #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e3fcc92
1077c57
6058bf0
c5621d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| .git | ||
| .gitignore | ||
| **/.DS_Store | ||
| **/node_modules |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,45 @@ | ||
| # Ghost Docker | ||
| # Ghost Docker for Coolify | ||
|
|
||
| Configuration to run Ghost and its services with Docker Compose | ||
|
|
||
| # Copyright & License | ||
| - [docker-compose.5.yml] - Original Coolify 5 Ghost configuration available from coolify as a template (for reference / backwards compatibility) | ||
|
|
||
| Copyright (c) 2013-2026 Ghost Foundation - Released under the [MIT license](LICENSE). | ||
| - [docker-compose.6.local.yml] - Modifications that allow running ghost 6 (with tinybird analytics and wizard) locally. `docker compose up -f coolify/docker-compose.6.yml -f coolify/docker-compose.6.local.yml` | ||
|
|
||
| - [docker-compose.6.yml] - For use with coolify, see setup below. | ||
|
|
||
|
Comment on lines
+5
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Convert bracketed filenames to real Markdown links or code spans. Line 5, Line 7, and Line 9 use Suggested fix-- [docker-compose.5.yml] - Original Coolify 5 Ghost configuration available from coolify as a template (for reference / backwards compatibility)
+- [`coolify/docker-compose.5.yml`](coolify/docker-compose.5.yml) - Original Coolify 5 Ghost configuration available from coolify as a template (for reference / backwards compatibility)
-- [docker-compose.6.local.yml] - Modifications that allow running ghost 6 (with tinybird analytics and wizard) locally. `docker compose -f coolify/docker-compose.6.yml -f coolify/docker-compose.6.local.yml up`
+- [`coolify/docker-compose.6.local.yml`](coolify/docker-compose.6.local.yml) - Modifications that allow running ghost 6 (with tinybird analytics and wizard) locally. `docker compose -f coolify/docker-compose.6.yml -f coolify/docker-compose.6.local.yml up`
-- [docker-compose.6.yml] - For use with coolify, see setup below.
+- [`coolify/docker-compose.6.yml`](coolify/docker-compose.6.yml) - For use with coolify, see setup below.🤖 Prompt for AI Agents |
||
| ## Ghost 6 with Tinybird Analytics | ||
|
|
||
| ### New Install | ||
|
|
||
| Requirements: Coolify UI v4, host with at least 5GB disk space and 2GB RAM | ||
|
|
||
| Primary purpose was to make it easy to configure a new / existing ghost 6 instance to run from coolify, still requires tinybird at this time, but there is a useful setup tool built in (Wizard) which also functions as a gateway after configuration. | ||
|
|
||
| 1. In Coolify UI Project: Add Resource | ||
| 2. As Public Repository: https://github.com/BadPirate/ghost-docker.git | ||
| 3. Select Build Pack: "Docker Compose" | ||
| 4. Docker Compose Location: `/coolify/docker-compose.6.yml` | ||
|
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the canonical repository URL in deployment steps. Line 20 and Line 32 currently point users to a personal fork ( Also applies to: 32-34 🤖 Prompt for AI Agents |
||
| 5. General -> Domains for wizard: https://<your coolify domain>:3989 | ||
| 6. Deploy | ||
| 7. After deployment, visit (From links for ghost-gate or at the URL) and configure tinybird | ||
| 8. Stop deployment, paste the tinybird config variables into Environment section of your deployment and relaunch | ||
| 9. Profit! (?) | ||
|
|
||
| ### Upgrade existing coolify ghost 5 template based install | ||
|
|
||
| 1. In Coolify UI Project: Add Resource | ||
| 2. As Public Repository: https://github.com/BadPirate/ghost-docker.git | ||
| 3. Select Build Pack: "Docker Compose" | ||
| 4. Docker Compose Location: `/coolify/docker-compose.6.yml` | ||
| 5. General -> Domains for wizard: https://<your coolify domain>:3989 | ||
| 6. Deploy | ||
| 7. Stop the deployment after it successfully opens | ||
| 8. On your server, cd into docker volumes `/var/lib/docker/volumes/` find the app ID for your old version ghost blog, and the app ID for the new version, and replace new empty content with existing older content: | ||
| - `rm -rf ${NEWID}_ghost-content-data; cp -r ${OLDID}_ghost-content-data ${NEWID}_ghost-content-data` | ||
| - `rm -rf ${NEWID}_ghost-mysql-data; cp -r ${OLDID}_ghost-mysql-data ${NEWID}_ghost-mysql-data` | ||
| 9. In Coolify UI, copy the environment variables (including passwords for mysql) from the old template based app and put them into your new docker compose based app | ||
| 10. Deploy again, ghost-gate will migrate your database | ||
| 11. After deployment, visit (From links for ghost-gate or at the URL) and configure tinybird | ||
| 12. Stop deployment, paste the tinybird config variables into Environment section of your deployment and relaunch | ||
| 13. Profit! (?) | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||||
| # Ghost Docker for Coolify | ||||||||||||||||||
|
|
||||||||||||||||||
| Configuration to run Ghost and its services with Docker Compose | ||||||||||||||||||
|
|
||||||||||||||||||
| - [docker-compose.5.yml] - Original Coolify 5 Ghost configuration available from coolify as a template (for reference / backwards compatibility) | ||||||||||||||||||
|
|
||||||||||||||||||
| - [docker-compose.6.local.yml] - Modifications that allow running ghost 6 (with tinybird analytics and wizard) locally. `docker compose up -f coolify/docker-compose.6.yml -f coolify/docker-compose.6.local.yml` | ||||||||||||||||||
|
|
||||||||||||||||||
| - [docker-compose.6.yml] - Ghost 6 + Tinybird for analytics + router and wizard to ease in setup. For use with coolify, see setup below. | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Ghost 6 with Tinybird Analytics | ||||||||||||||||||
|
|
||||||||||||||||||
| ### New Install | ||||||||||||||||||
|
|
||||||||||||||||||
| Requirements: Coolify UI v4, host with at least 5GB disk space and 2GB RAM | ||||||||||||||||||
|
|
||||||||||||||||||
| Primary purpose was to make it easy to configure a new / existing ghost 6 instance to run from coolify, still requires tinybird at this time, but there is a useful setup tool built in (Wizard) which also functions as a gateway after configuration. | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. In Coolify UI Project: Add Resource | ||||||||||||||||||
| 2. As Public Repository: https://github.com/BadPirate/ghost-docker.git | ||||||||||||||||||
| 3. Select Build Pack: "Docker Compose" | ||||||||||||||||||
| 4. Docker Compose Location: `/coolify/docker-compose.6.yml` | ||||||||||||||||||
| 5. General -> Domains for wizard: https://<your coolify domain>:3989 | ||||||||||||||||||
| 6. Deploy | ||||||||||||||||||
| 7. After deployment, visit (From links for ghost-gate or at the URL) and configure tinybird | ||||||||||||||||||
| 8. Stop deployment, paste the tinybird config variables into Environment section of your deployment and relaunch | ||||||||||||||||||
| 9. Profit! (?) | ||||||||||||||||||
|
Comment on lines
+13
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Document required SMTP/mail env vars before final deploy. Please add a short “production checklist” note requiring Based on learnings: "Email configuration is critical even without newsletter features as it is used for admin notifications". Also applies to: 41-45 🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| ### Upgrade existing coolify ghost 5 template based install | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. In Coolify UI Project: Add Resource | ||||||||||||||||||
| 2. As Public Repository: https://github.com/BadPirate/ghost-docker.git | ||||||||||||||||||
| 3. Select Build Pack: "Docker Compose" | ||||||||||||||||||
| 4. Docker Compose Location: `/coolify/docker-compose.6.yml` | ||||||||||||||||||
| 5. General -> Domains for wizard: https://<your coolify domain>:3989 | ||||||||||||||||||
| 6. Deploy | ||||||||||||||||||
| 7. Stop the deployment after it successfully opens | ||||||||||||||||||
| 8. On your server, cd into docker volumes `/var/lib/docker/volumes/` find the app ID for your old version ghost blog, and the app ID for the new version, and replace new empty content with existing older content: | ||||||||||||||||||
| - `rm -rf ${NEWID}_ghost-content-data; cp -r ${OLDID}_ghost-content-data ${NEWID}_ghost-content-data` | ||||||||||||||||||
| - `rm -rf ${NEWID}_ghost-mysql-data; cp -r ${OLDID}_ghost-mysql-data ${NEWID}_ghost-mysql-data` | ||||||||||||||||||
|
Comment on lines
+38
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard destructive volume-copy commands with variable checks. The current Suggested safer command block- - `rm -rf ${NEWID}_ghost-content-data; cp -r ${OLDID}_ghost-content-data ${NEWID}_ghost-content-data`
- - `rm -rf ${NEWID}_ghost-mysql-data; cp -r ${OLDID}_ghost-mysql-data ${NEWID}_ghost-mysql-data`
+ - `test -n "${OLDID}" && test -n "${NEWID}" || (echo "OLDID/NEWID required" && exit 1)`
+ - `test "${OLDID}" != "${NEWID}" || (echo "OLDID and NEWID must differ" && exit 1)`
+ - `rm -rf "/var/lib/docker/volumes/${NEWID}_ghost-content-data" && cp -a "/var/lib/docker/volumes/${OLDID}_ghost-content-data" "/var/lib/docker/volumes/${NEWID}_ghost-content-data"`
+ - `rm -rf "/var/lib/docker/volumes/${NEWID}_ghost-mysql-data" && cp -a "/var/lib/docker/volumes/${OLDID}_ghost-mysql-data" "/var/lib/docker/volumes/${NEWID}_ghost-mysql-data"`📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| 9. In Coolify UI, copy the environment variables (including passwords for mysql) from the old template based app and put them into your new docker compose based app | ||||||||||||||||||
| 10. Deploy again, ghost-gate will migrate your database | ||||||||||||||||||
| 11. After deployment, visit (From links for ghost-gate or at the URL) and configure tinybird | ||||||||||||||||||
| 12. Stop deployment, paste the tinybird config variables into Environment section of your deployment and relaunch | ||||||||||||||||||
| 13. Profit! (?) | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| COOLIFY_DIR=$(dirname $0) | ||
|
|
||
| docker compose --project-directory $COOLIFY_DIR/.. -f $COOLIFY_DIR/docker-compose.6.yml -f $COOLIFY_DIR/docker-compose.6.local.yml up $@ | ||
|
Comment on lines
+3
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quote path/arg expansions to avoid shell splitting bugs.
Suggested patch #!/usr/bin/env bash
+set -euo pipefail
-COOLIFY_DIR=$(dirname $0)
+COOLIFY_DIR="$(dirname "$0")"
-docker compose --project-directory $COOLIFY_DIR/.. -f $COOLIFY_DIR/docker-compose.6.yml -f $COOLIFY_DIR/docker-compose.6.local.yml up $@
+docker compose \
+ --project-directory "$COOLIFY_DIR/.." \
+ -f "$COOLIFY_DIR/docker-compose.6.yml" \
+ -f "$COOLIFY_DIR/docker-compose.6.local.yml" \
+ up "$@"🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| --- | ||
| # Legacy Ghost 5 Coolify template, kept for migrations from the old built-in Ghost | ||
| # service in Coolify. No analytics, no ActivityPub, no ghost-gate. For a new install | ||
| # prefer coolify/docker-compose.6.yml. See coolify/README.md. | ||
| services: | ||
| ghost: | ||
| image: 'ghost:5' | ||
| volumes: | ||
| - 'ghost-content-data:/var/lib/ghost/content' | ||
| environment: | ||
| - SERVICE_URL_GHOST_2368 | ||
| - url=$SERVICE_URL_GHOST | ||
| - database__client=mysql | ||
| - database__connection__host=mysql | ||
| - database__connection__user=$SERVICE_USER_MYSQL | ||
| - database__connection__password=$SERVICE_PASSWORD_MYSQL | ||
| - 'database__connection__database=${MYSQL_DATABASE-ghost}' | ||
| - mail__transport=SMTP | ||
| - 'mail__options__auth__pass=${MAIL_OPTIONS_AUTH_PASS}' | ||
| - 'mail__options__auth__user=${MAIL_OPTIONS_AUTH_USER}' | ||
| - 'mail__options__secure=${MAIL_OPTIONS_SECURE:-true}' | ||
| - 'mail__options__port=${MAIL_OPTIONS_PORT:-465}' | ||
| - 'mail__options__service=${MAIL_OPTIONS_SERVICE:-Mailgun}' | ||
| - 'mail__options__host=${MAIL_OPTIONS_HOST}' | ||
| depends_on: | ||
| mysql: | ||
| condition: service_healthy | ||
| healthcheck: | ||
| test: | ||
| - CMD | ||
| - echo | ||
| - ok | ||
|
Comment on lines
+28
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace placeholder Ghost healthcheck with a real probe.
Suggested patch healthcheck:
test:
- - CMD
- - echo
- - ok
+ - CMD-SHELL
+ - wget -q -S -T 3 --spider http://127.0.0.1:2368/ 2>&1 | grep -q 'HTTP/'
interval: 5s
timeout: 20s
retries: 10🤖 Prompt for AI Agents |
||
| interval: 5s | ||
| timeout: 20s | ||
| retries: 10 | ||
| mysql: | ||
| image: 'mysql:8.0' | ||
| volumes: | ||
| - 'ghost-mysql-data:/var/lib/mysql' | ||
| environment: | ||
| - 'MYSQL_USER=${SERVICE_USER_MYSQL}' | ||
| - 'MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}' | ||
| - 'MYSQL_DATABASE=${MYSQL_DATABASE}' | ||
| - 'MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}' | ||
| healthcheck: | ||
| test: | ||
| - CMD | ||
| - mysqladmin | ||
| - ping | ||
| - '-h' | ||
| - 127.0.0.1 | ||
| interval: 5s | ||
| timeout: 20s | ||
| retries: 10 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| services: | ||
| ghost-gate: | ||
| ports: | ||
| - "3989:3989" | ||
| environment: | ||
| SERVICE_URL_GHOST_GATE_3989: | ||
| SERVICE_URL_GHOST_GATE: http://localhost:3989 | ||
| MYSQL_USER: ${SERVICE_USER_MYSQL:-localuser} | ||
| MYSQL_PASSWORD: ${SERVICE_PASSWORD_MYSQL:-changeme} | ||
| MYSQL_ROOT_PASSWORD: ${SERVICE_PASSWORD_MYSQLROOT:-changemeroot} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,196 @@ | ||
| services: | ||
| ghost-gate: | ||
| build: | ||
| context: . | ||
| dockerfile: ghost-gate/Dockerfile | ||
| args: | ||
| GHOST_VERSION: ${GHOST_VERSION:-6-alpine} | ||
| depends_on: | ||
| mysql: | ||
| condition: service_healthy | ||
| environment: | ||
| SERVICE_URL_GHOST_GATE_3989: | ||
| SERVICE_URL_GHOST_GATE: | ||
| PROXY_GHOST_UPSTREAM: http://ghost:2368 | ||
| PROXY_ANALYTICS_UPSTREAM: http://traffic-analytics:3000 | ||
| PROXY_ACTIVITYPUB_UPSTREAM: http://activitypub:8080 | ||
| MYSQL_HOST: mysql | ||
| MYSQL_PORT: "3306" | ||
| MYSQL_ROOT_PASSWORD: ${SERVICE_PASSWORD_MYSQLROOT} | ||
| MYSQL_USER: ${SERVICE_USER_MYSQL} | ||
| MYSQL_PASSWORD: ${SERVICE_PASSWORD_MYSQL} | ||
| MYSQL_MULTIPLE_DATABASES: ${MYSQL_MULTIPLE_DATABASES:-activitypub} | ||
| MAIL_OPTIONS_AUTH_PASS: ${MAIL_OPTIONS_AUTH_PASS:-mailgun_smtp_user_password} | ||
| MAIL_OPTIONS_AUTH_USER: ${MAIL_OPTIONS_AUTH_USER:-local@localhost} | ||
| MAIL_OPTIONS_PORT: ${MAIL_OPTIONS_PORT:-465} | ||
| MAIL_OPTIONS_SECURE: ${MAIL_OPTIONS_SECURE:-true} | ||
| MAIL_OPTIONS_SERVICE: ${MAIL_OPTIONS_SERVICE:-Mailgun} | ||
| MAIL_OPTIONS_HOST: ${MAIL_OPTIONS_HOST:-smtp.mailgun.org} | ||
| # ghost-gate serves the setup page until all four TINYBIRD_* vars are set; after | ||
| # that it switches to reverse-proxy mode on next start. | ||
| TINYBIRD_API_URL: ${TINYBIRD_API_URL:-} | ||
| TINYBIRD_WORKSPACE_ID: ${TINYBIRD_WORKSPACE_ID:-} | ||
| TINYBIRD_ADMIN_TOKEN: ${TINYBIRD_ADMIN_TOKEN:-} | ||
| TINYBIRD_TRACKER_TOKEN: ${TINYBIRD_TRACKER_TOKEN:-} | ||
| expose: | ||
| - "3989" | ||
| restart: unless-stopped | ||
| healthcheck: | ||
| test: | ||
| - "CMD-SHELL" | ||
| - "wget -q -S -T 3 --spider http://127.0.0.1:3989/__ghost_gate/health 2>&1 | grep -q 'HTTP/1.1 200'" | ||
| interval: 5s | ||
| timeout: 5s | ||
| retries: 24 | ||
| start_period: 30s | ||
|
|
||
| ghost: | ||
| image: ghost:${GHOST_VERSION:-6-alpine} | ||
| environment: | ||
| url: ${SERVICE_URL_GHOST_GATE} | ||
| NODE_ENV: production | ||
| admin__url: ${SERVICE_URL_GHOST_GATE} | ||
| database__client: mysql | ||
| database__connection__host: mysql | ||
| database__connection__user: ${SERVICE_USER_MYSQL} | ||
| database__connection__password: ${SERVICE_PASSWORD_MYSQL} | ||
| database__connection__database: ${MYSQL_DATABASE-ghost} | ||
| mail__transport: SMTP | ||
| mail__from: ${MAIL_FROM} | ||
| mail__options__auth__pass: ${MAIL_OPTIONS_AUTH_PASS} | ||
| mail__options__auth__user: ${MAIL_OPTIONS_AUTH_USER} | ||
| mail__options__secure: ${MAIL_OPTIONS_SECURE:-true} | ||
| mail__options__port: ${MAIL_OPTIONS_PORT:-465} | ||
| mail__options__service: ${MAIL_OPTIONS_SERVICE:-Mailgun} | ||
| mail__options__host: ${MAIL_OPTIONS_HOST} | ||
|
Comment on lines
+59
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make
Based on learnings: "Email configuration is critical even without newsletter features as it is used for admin notifications". 🤖 Prompt for AI Agents |
||
| # Same-origin tracker (no CORS). ghost-gate strips /.ghost/analytics and forwards | ||
| # to traffic-analytics:3000/api/v1/page_hit. | ||
| tinybird__tracker__endpoint: ${SERVICE_URL_GHOST_GATE}/.ghost/analytics/api/v1/page_hit | ||
| labs__publicAPI: "true" | ||
| tinybird__adminToken: ${TINYBIRD_ADMIN_TOKEN} | ||
| tinybird__workspaceId: ${TINYBIRD_WORKSPACE_ID} | ||
| tinybird__tracker__datasource: analytics_events | ||
| # Admin/stats read from Tinybird API directly (not via traffic-analytics). | ||
| tinybird__stats__endpoint: ${TINYBIRD_API_URL:-https://api.tinybird.co} | ||
| volumes: | ||
| - 'ghost-content-data:/var/lib/ghost/content' | ||
| depends_on: | ||
| mysql: | ||
| condition: service_healthy | ||
| ghost-gate: | ||
| condition: service_healthy | ||
| activitypub: | ||
| condition: service_started | ||
| required: false | ||
| # Ghost redirects `/` to its public URL, so `wget --spider` follows the redirect | ||
| # out of the container. Instead, treat "server answered with any HTTP status line" | ||
| # as alive (busybox wget prints `HTTP/1.1 …` on stderr with -S even for redirects). | ||
| healthcheck: | ||
| test: | ||
| - "CMD-SHELL" | ||
| - "wget -q -S -T 3 --spider http://127.0.0.1:2368/ 2>&1 | grep -q 'HTTP/'" | ||
| interval: 10s | ||
| timeout: 5s | ||
| retries: 18 | ||
| start_period: 120s | ||
|
|
||
| mysql: | ||
| image: mysql:8.0.44@sha256:f37951fc3753a6a22d6c7bf6978c5e5fefcf6f31814d98c582524f98eae52b21 | ||
| restart: always | ||
| environment: | ||
| MYSQL_USER: ${SERVICE_USER_MYSQL} | ||
| MYSQL_PASSWORD: ${SERVICE_PASSWORD_MYSQL} | ||
| MYSQL_DATABASE: ${MYSQL_DATABASE} | ||
| MYSQL_ROOT_PASSWORD: ${SERVICE_PASSWORD_MYSQLROOT} | ||
| volumes: | ||
| - 'ghost-mysql-data:/var/lib/mysql' | ||
| healthcheck: | ||
| test: mysqladmin ping -p$$MYSQL_ROOT_PASSWORD -h 127.0.0.1 | ||
| interval: 1s | ||
| start_period: 30s | ||
| start_interval: 5s | ||
| timeout: 20s | ||
| retries: 10 | ||
|
|
||
| traffic-analytics: | ||
| image: ghost/traffic-analytics:1.0.196@sha256:f93abf4134db41d94d90bb0ef6e4fcc67dfd91162f6ad15423c51e3c49f9c3a7 | ||
| restart: always | ||
| depends_on: | ||
| ghost-gate: | ||
| condition: service_healthy | ||
| expose: | ||
| - "3000" | ||
| volumes: | ||
| - traffic_analytics_data:/data | ||
| environment: | ||
| NODE_ENV: production | ||
| # Behind Traefik/Coolify; client IP from X-Forwarded-For (see TryGhost/TrafficAnalytics). | ||
| TRUST_PROXY: "true" | ||
| PROXY_TARGET: ${TINYBIRD_API_URL:-https://api.tinybird.co}/v0/events | ||
| SALT_STORE_TYPE: ${SALT_STORE_TYPE:-file} | ||
| SALT_STORE_FILE_PATH: /data/salts.json | ||
| TINYBIRD_TRACKER_TOKEN: ${TINYBIRD_TRACKER_TOKEN:-} | ||
| LOG_LEVEL: debug | ||
| healthcheck: | ||
| test: | ||
| - "CMD-SHELL" | ||
| - "wget -q -S -T 3 --spider http://127.0.0.1:3000/ 2>&1 | grep -q 'HTTP/'" | ||
| interval: 10s | ||
| timeout: 5s | ||
| retries: 6 | ||
| start_period: 15s | ||
|
|
||
| activitypub: | ||
| image: ghcr.io/tryghost/activitypub:1.2.2@sha256:128f0d08d872930b4ab37c9fc1fe8042fefd44622316b05f3885bd068be7cc43 | ||
| restart: always | ||
| expose: | ||
| - "8080" | ||
| volumes: | ||
| - 'ghost-content-data:/opt/activitypub/content' | ||
| environment: | ||
| NODE_ENV: production | ||
| MYSQL_HOST: mysql | ||
| MYSQL_USER: ${SERVICE_USER_MYSQL} | ||
| MYSQL_PASSWORD: ${SERVICE_PASSWORD_MYSQL} | ||
| MYSQL_DATABASE: activitypub | ||
| LOCAL_STORAGE_PATH: /opt/activitypub/content/images/activitypub | ||
| LOCAL_STORAGE_HOSTING_URL: ${SERVICE_URL_GHOST_GATE}/content/images/activitypub | ||
| depends_on: | ||
| mysql: | ||
| condition: service_healthy | ||
| activitypub-migrate: | ||
| condition: service_completed_successfully | ||
| # activitypub (alpine + BusyBox wget) has no documented health URL; accept any HTTP | ||
| # response on :8080 as "process listening". | ||
| healthcheck: | ||
| test: | ||
| - "CMD-SHELL" | ||
| - "wget -q -S -T 3 --spider http://127.0.0.1:8080/ 2>&1 | grep -q 'HTTP/'" | ||
| interval: 10s | ||
| timeout: 5s | ||
| retries: 6 | ||
| start_period: 30s | ||
|
|
||
| activitypub-migrate: | ||
| image: ghcr.io/tryghost/activitypub-migrations:1.2.2@sha256:2af8a0726ac4362cdcab59c308ed612140478d43011ec8d3475bb2634b96d108 | ||
| environment: | ||
| MYSQL_DB: mysql://${SERVICE_USER_MYSQL}:${SERVICE_PASSWORD_MYSQL}@tcp(mysql:3306)/activitypub | ||
| depends_on: | ||
| mysql: | ||
| condition: service_healthy | ||
| ghost-gate: | ||
| condition: service_healthy | ||
| restart: no | ||
| # One-shot job with no HTTP server; report healthy unconditionally. Downstream | ||
| # services gate on service_completed_successfully, not service_healthy. | ||
| healthcheck: | ||
| test: ["CMD-SHELL", "true"] | ||
| interval: 10s | ||
| timeout: 3s | ||
| retries: 1 | ||
| start_period: 5s | ||
|
|
||
| volumes: | ||
| ghost-content-data: | ||
| ghost-mysql-data: | ||
| traffic_analytics_data: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| node_modules | ||
| npm-debug.log |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Docker Compose CLI -f flag order before or after subcommand syntax💡 Result:
In Docker Compose V2 (the
docker composeCLI), global options like-f/--filecome before the subcommand. The documented option syntax isdocker compose [OPTIONS] COMMAND [ARG...], and examples show-fplaced before commands such asrun(e.g.,docker compose -f compose.yaml -f compose.admin.yaml run backup_db). [1][2] So for your question (“-f flag order before or after subcommand syntax”): put-fbefore the subcommand (the command likeup,run,ps, etc.). Also note: Compose supports specifying multiple compose files by repeating-f; later files override earlier ones, and Compose “builds the configuration in the order you supply the files.” [1]Citations:
Fix the
docker composecommand option order.In Docker Compose V2, global options like
-fmust come before the subcommand. The current command on line 7 won't work. Reorder to:docker compose -f coolify/docker-compose.6.yml -f coolify/docker-compose.6.local.yml upSuggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents