Skip to content
Alexander Holbreich
Go back

Docker image for Ghost blog

I’ve created a new Golden Docker image for the Ghost Blogging blogging platform.

Warning: Attention. I do not maintaining these images actively anymore.

Why

Ghost documentation states that it’s better to use production configuration for live environments:

Essentially, production mode gives priority to performance, whereas development mode gives priority to information.

Since the official container for Ghost is fine for running in development mode, but it has some limitations for running in production. That, and the config file doesn’t have any easy way to tweak.

The main feature of the Golden Image is to enable production-ready use, with more configuration options[^1] build in backup and robust releases.

Usage of the image

For a quick test, do the following:

docker run --name some-ghost -p 80:2368 -d gold/ghost

It starts a new Ghost container and makes it available at http://localhost. For production, you need something more robust.

Production-ready example

Let’s create Host based volume ghost, that survives updates, and flexible in the configuration:

#Prepare host folder to keep Ghost data
sudo mkdir -p /var/lib/ghost
sudo chown 1000:1000 /var/lib/ghost
# Run container
docker run --name ghost1 --env-file /etc/default/ghost -p 80:2368 -v /var/lib/ghost:/var/lib/ghost -d gold/ghost npm start --production

This will run ghost in production mode by using host wired volume. Configuration is provided by /etc/default/ghost. Here an example of the configuration file.

# Ghost environment example
# Place in /etc/default/ghost

GHOST_URL=http://www.example.com
MAIL_FROM='"Webmaster" <[email protected]>'
MAIL_HOST=mail.example.com
PROD_FORCE_ADMIN_SSL=true

Keep in mind you can switch between development and production modes whenever you like by using or not --production argument. My image uses same database file in both environments.

Docker-Compose example

I prefer to use docker-compose for such use case

ghost:
  image: gold/ghost:0.7.3
  command: npm start --production
  restart: always  
  ports: 
   - "2368:2368"
  volumes:
   - /var/containerdata/ghost/blog/:/var/lib/ghost
  environment:
   - GHOST_URL=http://example.com
   - PROD_FORCE_ADMIN_SSL=true
   - MAIL_FROM='"Webmaster" <[email protected]>'
   - MAIL_HOST=mail.example.com
   - PROD_FORCE_ADMIN_SSL=false 

Here PROD_FORCE_ADMIN_SSL disables https for admin pages, assuming you use it via frontend load balancer like nginx.

Also, I prefer to use explicit versions gold/ghost:0.7.3 to prevent unintended updates.

Backups

Currently, backups can be done via:

docker run --rm --volumes-from some-ghost -v $(pwd)/backups:/backups gold/ghost /backup.sh

This will place the backup file in $(pwd)/backups directory of the host machine…

What next

For now, I’ve focused on volume on host pattern. In this scenario I have full access to data and configuration, as well restore of backups is not a problem, so this is not included in the image so far.

However, I plan to improve the image in sense of

  • Backup and restore functions for ==data-container scenario==
  • More config option if needed
  • Include more UI Themes, to give you more build in flexibility
  • Your ideas…

Archived comments (11)

These comments were migrated from Disqus and are no longer accepting replies.

  • Brian Christner

    Another idea is to put your database in a separate container. Also, you could load balance and scale your Ghost containers as well.

  • AlexH

    Hmm.. Actually there are a lot of database containers out there, but indeed i could provide properties to make easy connectivity to them. For example MYSQL properties. Is it something you would like to see?

    But is horizontal scaling is really a need, i mean single instance can handle thousands and much more visitors per day... with front end LB tuning maybe far more.. Is there really need for horizontal balancing?
    If, so its maybe not so easy... Could you provide more details on load you deal with..?

  • Brian Christner

    I always like running everything I can in separate containers. This allows upgrading application containers independent of the DB container. My blog is also running with a LB and Ghost scaled containers. Use case? Just because it's nice to have :)

    Since you are building everything with docker-compose might as well put a proxy in front of your ghost container(NGINX or HAProxy). With a proxy in place it makes upgrades a lot easier or blue-green deployments with an option for a rollback.

    The guys at Tutum wrote a great article about how to accomplish this - http://blog.tutum.co/2015/0...

  • AlexH

    I also of course use Loadbalancer . Thank you for reminding me of blue green deployments , they are very useful.
    However my ghost image does not prevent you of using LB in front of it.

    And even more of course you can use separate container with --volumes-from option


    docker create -v /var/lib/ghost --name host-content busybox
    docker run --name ghost -p 80:2368 --volumes-from ghost-content -d gold/ghost npm start --production


    That gives you the possibility to scale or to upgrade Ghost, but not touching host system on environments where everything should be i containers (like tutum). But if we talk of scaling on one machine i see no benefits.
    And scaling over several host demand the solution to problems with sticky sessions, distribution of static content like images. Separate container for DB is not a big problem then.

    Even if it looks a bit that we talking about premature optimization (anti-pattern), i'm interested to know how to improve this ghost images to help people with such problems... One thing that seems useful to me: making easy external DB connection possible...

    I don't have clear idea how to do it now.

  • Brian Christner

    Another possibility is to minimize your image. I would recommend to use Alpine Linux to get the the smallest footprint possible.

    What do you mean by external DB connections?

  • AlexH

    By external DB i mean DB that is not included to this image. E.g. MySQL running i another image.

    P.S. Alpine is good idea.

  • Brian Christner

    Interesting write up. I'm also using ghost with a compose file and AWS S3 as my backup solution.

  • Caleb Sotelo

    Cool! I just did some similar work, the main differences being support for pulling in your ghost theme as NPM package, and volume-mounting the theme source code for live editing. http://paislee.io/how-to-de...

  • AlexH

    He Caleb... I'll take i look

  • AlexH

    Regarding Alpine: If you like my brand new experimental branch "alpine"
    https://github.com/aholbrei...
    run it with
    docker run --name alpine-ghost -p 8080:2368 -d gold/ghost:alpine

  • Brian Christner

    Very cool! Well done.