Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/README.coolify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Ghost on Coolify

Ghost 6 CMS packaged for one-shot deploys on [Coolify](https://coolify.io), with
optional Tinybird analytics and ActivityPub federation. Forked from
[`TryGhost/ghost-docker`](https://github.com/TryGhost/ghost-docker) and synced
daily; the Coolify-specific patch lives in
[`.github/scripts/patch.py`](.github/scripts/patch.py).

## Deploy

1. In Coolify: **New Resource → Public Repository**, point at this repo,
build pack **Docker Compose**, compose file `compose.yml`.
2. On the `ghost` service, set the primary **Domain (FQDN)** to the URL
you want (e.g. `https://blog.example.com`). Coolify fills in
`SERVICE_URL_GHOST` automatically and wires Traefik to port 2368.
3. Set SMTP env vars on the resource: `mail__options__host`,
`mail__options__port`, `mail__options__auth__user`,
`mail__options__auth__pass`, `mail__from`. Transactional email is
required by Ghost for staff invites and password resets.
4. **Deploy**. MySQL credentials generate on first boot via
`SERVICE_USER_MYSQL` / `SERVICE_PASSWORD_MYSQL` / `SERVICE_PASSWORD_MYSQLROOT` —
you don't enter them manually.

## Optional: separate admin domain

Set `ADMIN_DOMAIN=admin.example.com` on the resource and add the same value
as a second FQDN on the `ghost` service in Coolify. Upstream's
`${ADMIN_DOMAIN:+https://${ADMIN_DOMAIN}}` expression means Ghost sees
`admin__url` only when the variable is non-empty.

## Optional: analytics (Tinybird)

Enable the `analytics` profile on the resource
(`COMPOSE_PROFILES=analytics`). Set a second FQDN on the `traffic-analytics`
service (e.g. `analytics.example.com`) — Coolify fills
`SERVICE_URL_ANALYTICS` and proxies port 3000. Populate
`TINYBIRD_*` env vars per [`TINYBIRD.md`](TINYBIRD.md).

## Optional: ActivityPub

Enable the `activitypub` profile (`COMPOSE_PROFILES=analytics,activitypub`
if combined). Set a third FQDN on the `activitypub` service.

Fediverse discovery via `@user@your-primary-domain` additionally requires
routing `/.well-known/webfinger` on the Ghost FQDN to the ActivityPub
service. In Coolify, add this custom label to the `ghost` service:

```
traefik.http.routers.ghost-webfinger.rule=Host(`blog.example.com`) && PathPrefix(`/.well-known/webfinger`)
traefik.http.routers.ghost-webfinger.service=activitypub-http
traefik.http.services.activitypub-http.loadbalancer.server.port=8080
```

## Upgrades

Ghost's version floats on `${GHOST_VERSION:-6-alpine}`. Pin explicitly by
setting `GHOST_VERSION=6.2-alpine` on the resource if you need a specific
release. Renovate tracks MySQL patch updates within 8.0.x and the
analytics/ActivityPub image digests; Ghost itself is not pinned.

## Running locally (without Coolify)

Because the patched `compose.yml` targets Coolify's magic vars, local
`docker compose up` needs those vars set in `.env`:

```
SERVICE_URL_GHOST=http://localhost:2368
SERVICE_USER_MYSQL=ghost
SERVICE_PASSWORD_MYSQL=localdev
SERVICE_PASSWORD_MYSQLROOT=localrootdev
SERVICE_URL_ANALYTICS=http://localhost:3000
```

For a bare-metal Ghost CLI → Docker migration, see
[`scripts/migrate.sh`](scripts/migrate.sh) (not intended for Coolify hosts).

## License

MIT — see [LICENSE](LICENSE).
7 changes: 4 additions & 3 deletions .github/scripts/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ def patch_env_example() -> None:


def overwrite_readme() -> None:
src = pathlib.Path("README.coolify.md")
if src.exists():
pathlib.Path("README.md").write_text(src.read_text())
src = pathlib.Path(".github/README.coolify.md")
if not src.exists():
fail(f"{src} missing — the sync workflow should back it up under .github/")
pathlib.Path("README.md").write_text(src.read_text())


def main() -> None:
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/test-patch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ cd "$SCRATCH"
echo "→ fetching upstream"
curl -fsSL https://raw.githubusercontent.com/TryGhost/ghost-docker/main/compose.yml -o compose.yml
curl -fsSL https://raw.githubusercontent.com/TryGhost/ghost-docker/main/.env.example -o .env.example
mkdir -p caddy/snippets
mkdir -p caddy/snippets .github
touch caddy/Caddyfile.example caddy/snippets/Logging .env
cp "$REPO_ROOT/README.coolify.md" .
cp "$REPO_ROOT/.github/README.coolify.md" .github/
cp "$REPO_ROOT/.github/scripts/patch.py" .

echo "→ run 1: apply patch"
Expand Down
Loading