Overview
With the launch of Ghost 6.0 we are also previewing a new suite of tooling for self-hosters built on Docker with Compose. We invite you to be one of the first to try hosting Ghost with this new tooling, which comes with full support for self-hosting both the Social Web (ActivityPub) and Web Analytics (Tinybird) features.Why Docker?
So that we can continue adding advanced features to Ghost without creating bloat, we’re starting to build some features as separate services.Using Docker and Docker Compose takes all the pain out of managing different services and their dependencies, meaning we can keep Ghost’s architecture simple
without passing on complexity to our self-hosting community. All services are Open Source and can be self-hosted.
What’s included?
The Docker tooling will setup and run the usual Ghost service, along with Caddy for a webserver, MySQL, and if enabled, all the services needed for running ActivityPub and/or Analytics. There are two pathways:Install Ghost
This section will get you a fresh setup of a working Ghost instance. It will install the Ghost service, Caddy as a webserver and MySQL for the database.Prerequisites
- A Linux-based server (E.g. DigitalOcean 2GB/1CPU droplet)
- Docker 20.10.13 or higher installed (See: docker install guide)
- A domain name with a DNS A-Record pointing to the server’s IP address
- An SMTP email service for transactional mail (See: email config docs)
- (Optional) A Tinybird account for web analytics
Clone the repo
Make a local copy of our docker tooling repository in/opt/ghost
:
Setup your config
Copy the example config files for Ghost and Caddy:.env
file and change:
DOMAIN
: this is your custom domain for your Ghost site e.g. mysite.comADMIN_DOMAIN
: a separate domain for your Ghost admin e.g. admin.mysite.com (Optional, recommended)DATABASE_ROOT_PASSWORD
: generate a random password withopenssl rand -hex 32
DATABASE_PASSWORD
: generate a random password usingopenssl rand -hex 32
- SMTP Email section : your chosen SMTP service’s configuration (See: email config docs)
DOMAIN
, you’ll need to do option 3 in the next section to ensure ActivityPub works correctly.
(Optional) Domain setup in Caddy
The Caddyfile is setup for various domain setups. You can get to your desired setup by uncommenting the relevant blocks. Edit theCaddyfile
in caddy/Caddyfile
:
- For separate admin domains (recommended), uncomment the “Separate admin domains” block
- If you’re using a root or “naked” domain like mysite.com for
DOMAIN
in.env
: Redirect the www variant to your root domain by setting up DNS for both domains and then uncomment the “Redirect www -> root domain” block. - If you’re using a www domain for
DOMAIN
in.env
: Redirect your root domain to the www variant by setting up DNS for both domains, then uncomment the “Redirect root -> www domain” block” and setCHANGE_ME
to your root domain without the www. This is required for ActivityPub to work correctly with www domains.
CHANGE_ME
. All the other variables come from .env
and should be left as-is.
Install and run Ghost
Use Docker Compose commands to install and run your Ghost site. These commands may each take a little while:/ghost
to complete your setup 🎉
Enabling Web Analytics
This section assumes you’ve completed a fresh setup from the section above or have migrated an existing site to Docker.Get Tinybird setup
Make sure you have a Tinybird account with a workspace. You can choose any cloud and region. Then, making sure you’re still inside of/opt/ghost
, run the following 4 commands:
Edit the .env file
Paste the values from the previous step into the “Tinybird configuration” section. Addanalytics
to the COMPOSE_PROFILES
variable at the top. This automatically includes the analytics
profile when running docker compose
commands:
Install and run Ghost with Web Analytics
Use Docker Compose to install new images and run Ghost with Web Analytics:Enabling Social Web (ActivityPub)
By default, all new Ghost installs are configured to use the Ghost(Pro) hosted ActivityPub Service, meaning the Social Web features work out of the box. This hosted service is free to use for all self-hosters, with some usage limits. If you would like to host the ActivityPub Service yourself, follow these steps:Edit the .env file
Addactivitypub
to the COMPOSE_PROFILES
variable at the top. This automatically includes the activitypub
profile when running docker compose
commands:
ACTIVITYPUB_TARGET
line to point to your local install. It should look like this:
Install and run Ghost with ActivityPub
Usedocker compose
to install new images and run Ghost with ActivityPub:
Hosted ActivityPub Usage Limits
Self-hosters are free to use the hosted ActivityPub service, up to the following limits:- 2000 max. followers
- 2000 max. following
- max. 100 interactions per day (interactions include: create a post/note, reply, like, repost)
Future maintenance
Updating Ghost
Usedocker compose
to update Ghost regularly:
Updating config
When changing your Ghost config in.env
you’ll need to recreate the Ghost container.
DOMAIN
, ADMIN_DOMAIN
or ACTIVITYPUB_TARGET
are changed in the .env
file, the Caddy container also needs recreating:
.env
that are used in the compose.yml
the service using the variable will also need recreating in the same way.
The single exception is the DATABASE_xxx
variables. These must not be changed
once the database has been initialised, as it will change the config, but not the
actual values the database expects, thefore causing connection errors.
Migrating a Ghost-CLI Install
Using our migration assistant, you can migrate a Ghost-CLI site over to the new Docker Compose setup in place on the same sever. The migration assistant performs the following actions:- Copies your Ghost content directory to a new folder that is bind mounted into the Ghost Docker container
- Dump your existing Ghost database and imports it in to a Docker based MySQL container
- Stops and disables your existing Ghost site
- Stops your Nginx instance
- Starts a Caddy webserver which handles TLS termination for you
- Provides a rollback option if anything goes wrong
Prerequisites
- A Ghost-CLI install that you’d like to migrate
- Docker 20.10.13 or higher installed (See: docker install guide)
- A domain name with a DNS A-Record pointing to the server’s IP address
- An SMTP email service for transactional mail (See: email config docs)
- (Optional) A Tinybird account for web analytics
Get started
To get started, SSH into your server as root. Next, follow the first 3 sections from “Install Ghost” above, stopping before installing and running Ghost with the Docker Compose commands:Run the migration assistant
Be aware that the migration assistant will ask to stop your existing Nginx install which will take your site offline. If you have other sites running on the same server you will want to answer No to this option.CTRL+C
and then running bash recovery_instructions.sh
to restore your original Ghost site. The migration script can be run multiple times if it errors without issue.
The migration script doesn’t delete any data. After you’ve migrated you should remove your existing installation once you’re happy.
Enable additional services
If you want to enable Web Analytics or ActivityPub, you can now follow the relevant sections from above:Troubleshooting Docker
If this setup doesn’t “just work” out of the box, there’s likely a configuration error or server incompatibility issue that needs tracking down. Usedocker compose logs caddy
to see the webserver logs. Try this first if you get an error like “This site can’t be reached”.
Use docker compose logs ghost
to see the Ghost logs as the next step.
If your issue is clearly with a different service, docker compose logs [service]
will show you more details.
If you get really stuck, post the details on https://forum.ghost.org.
Tinybird Integration
Note: there are no additional steps required for Tinybird to work, provided you’ve completed the initial setup steps for traffic analytics.Configuration
Since Tinybird is a third party service that is running outside the Docker Compose network, we need to provide Ghost and the Traffic Analytics service a few pieces of configuration, so they can integrate properly with your Tinybird workspace. The initial setup of these configuration parameters is covered in the initial setup steps. The following provides some more information on what each required configuration parameter is, why it’s needed, and where you can find it.TINYBIRD_API_URL
: This is the API url for your Tinybird workspace, which Ghost uses to make requests to your Tinybird workspace’s endpoints. The value will vary depending on which cloud / region your workspace is hosted in. You can find this value by runningtb info
from the Tinybird CLI and using the value of theapi
key, or in the Tinybird UI by going to Endpoints, selecting any endpoint, and finding the full URL of the endpoint.TINYBIRD_ADMIN_TOKEN
: This is a token that is automatically created by Tinybird, which enables any operation in your workspace. You can find it in your Tinybird workspace’s UI under the “Tokens” tab, named “Workspace admin token”. Ghost uses the admin token to sign JWTs, which Ghost and Admin use to authenticate with Tinybird’s API endpoints.TINYBIRD_WORKSPACE_ID
: This is a unique identifier for your workspace generated by Tinybird. You can find it in your Tinybird workspace’s UI under Settings. Ghost also uses this value to sign JWTs to authenticate with Tinybird’s API endpoints.TINYBIRD_TRACKER_TOKEN
: This is a token that grants write access to the mainanalytics_events
datasource in Tinybird. You can find this value in the Tinybird UI under “Tokens”. This is passed to thetraffic-analytics
service, which adds it to each request that is proxied to Tinybird.
Deployments (”Migrations”)
The Ghost service itself contains the Tinybird datafiles, which define the schema of our datasources and the query logic that generates the materialized views, pipes and endpoints in the Tinybird workspace. When new versions of Ghost are shipped, there may be changes made to these files, and those changes will need to be deployed to your Tinybird workspace to be compatible with the incoming new version of Ghost. Theghost-docker
repo includes handling for these “migrations” to run automatically when running docker compose up
. Provided you’ve followed the initial setup instructions for traffic analytics, there shouldn’t be any intervention required to update your Tinybird workspace when updating to a new version of Ghost.
How it works
Here’s an overview of what all is happening behind the scenes when updating to a new version of Ghost with changes to the Tinybird datafiles:- When you run
docker compose pull
anddocker compose up -d
as part of the normal upgrade process, this will pull the latest version of the Ghost container to your host. This container includes the Tinybird datafiles. - The
tinybird-login
container will run. Assuming you’ve already logged in to Tinybird as part of your initial setup, this service will noop. If you’re not logged in to Tinybird already for any reason, this service will fail, which means the Tinybird migrations did not run.- If you’re not logged in, run
docker compose run --rm tinybird-login
first, then rundocker compose up -d
again.
- If you’re not logged in, run
- After
tinybird-login
has completed successfully, thetinybird-sync
service will run in the new Ghost container. This service copies the Tinybird files from the Ghost container into thetinybird_files
volume, then exits. - After the
tinybird-sync
service completes successfully, thetinybird-deploy
service will run. This service will create and promote a new deployment in your workspace with the changes (if any) to the files in thetinybird_files
volume to Tinybird, using thetb --cloud deploy
command of the Tinybird CLI.
What is a deployment?
Thetb --cloud deploy
command technically doesn’t run “migrations” in the traditional sense at all. Instead it compares your local Tinybird datafiles with what is currently deployed to your workspace to figure out what needs to change (if anything). If your workspace isn’t up-to-date with your local Tinybird datafiles, the CLI will create a new deployment with the changes. Once the new deployment is complete and healthy, Tinybird will promote it to be the current “Live” deployment, and remove the previous deployment.
You can view all the deployments in your workspace in the Tinybird UI under “Deployments” in the left sidebar, or use the tb deployment
commands to interact with deployments via the CLI. For more information on what deployments are and how they work, read Tinybird’s docs on deployments.
What if a deployment fails?
If a new version of Ghost includes changes to the Tinybird files, and any of thetinybird-*
services fail, don’t panic! The previous deployment in your Tinybird workspace should still be live and healthy. If a deployment fails for any reason, you’ll need to diagnose what went wrong, fix it, then run docker compose up -d
to try again.
Here are a few steps you can take to start troubleshooting:
- Check the logs of the
tinybird-login
service usingdocker compose logs tinybird-login
. If this service was successful, you should see “Tinybird already logged in” in the logs. If this service failed for any reason, try authenticating with Tinybird again usingdocker compose run --rm tinybird-login
. - Check the logs of the
tinybird-sync
service usingdocker compose logs tinybird-sync
. If this service was successful, you should see “Tinybird files synced into shared volume.” - Check the logs of the
tinybird-deploy
service usingdocker compose logs tinybird-deploy
. This will show the complete logs from the latest attempt to deploy changes to your Tinybird workspace, which should hopefully tip you off to what went wrong. - Check the “Deployments” section of your Tinybird UI (Tinybird Worksapce > Deployments on the left side bar). This will show you which Deployment is currently live, and may provide some hints if the latest deployment failed for any reason.