Deploy a Ghost Blog with Docker

Tags: docker, ghost, tutorial, programming
Published: 2022-01-03 12:51:39

> This tutorial was originally posted [here](https://tobyhagan.com/blog/deploy-a-ghost-blog-with-docker)

## From 0 to blog in under 5 minutes

Docker can be an amazing tool for deploying and managing applications, and can streamline many tasks that used to be tedious and time-consuming. This tutorial will show you how to use set up docker in your local environment to develop a blog application. For this tutorial we will be using [Ghost](https://ghost.org/) as our blog application. Ghost is a free, open-source, and easy-to-use blogging platform with powerful features like real-time search, RSS, and email notifications.

### Lets get started

First, we need to install [Docker](https://docker.com) on our local machine. If you don't have docker installed, you can install it with the following command:

```bash
sudo apt-get update
sudo apt-get upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
sudo usermod -aG docker $USER
```

Lets break this down a little.

- `sudo apt-get update` updates the package database.
- `sudo apt-get upgrade -y` upgrades all packages currently installed on the system.
- `-y` flag tells apt to automatically answer yes to any questions it asks, which can save you time.

The  These commands are necessary to ensure that the system is up to date before installing docker.

-  `curl -fsSL https://get.docker.com -o get-docker.sh` uses curl to download a convenience script that installs docker and all necessary dependencies.
- The `-fsSl` flag tells curl to follow any redirects that the server sends.
- We're also using `-o` to tell curl to write the output to a file called `get-docker.sh`
- `sh get-docker.sh` runs the bash script and installs docker.
- And finally, `sudo usermod -aG docker $USER` To make sure that the current user can access the docker daemon, by adding them to the group "docker"

### Verify the installation

The convenience script automatically installs the latest version of docker compatible with your system. To verify that everything went smoothly, we can run the following command:

```bash
docker run hello-world
```

This command will try to find the hello-world image locally, if it is unable to do so, the image will be pulled from docker hub. Once the image has completed downloading, the hello-world program will run, printing the following to the terminal:

```bash
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1sd6541851z: Pull complete
Digest: sha256:##HASH##
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```

Success! Docker is installed and running.

### Install Ghost

Now that Docker is up and running, we're ready to install our blogging platform. This is where docker really shines, as the install can be as simple as running a single command and utilizing the built-in SQLite database. For larger applications, it is recommended to use a database like MySQL or PostgreSQL, which will allow you to store data in a more robust, secure, and scalable way. For this demonstration, we'll be sticking with SQLite. To get started we'll run the following command:

```bash
docker run -d --name ghost-blog -p 2368:2368 -v /ghost-data:/var/lib/ghost/content ghost:alpine
```

In this command there are quite a few flags, so we'll go over each in more detail.

- `-d` runs the container in the background. This detaches the container from the terminal, allowing you to run further commands.
- `--name` gives the container a name. This is useful for referencing the container later.
- `-p` exposes a port on the host machine. In this case, we're binding port 2368 on the local host to port 2368 within the container. Port 2368 is the default port for Ghost.
- `-v` mounts a volume. This is neseccary to persist data. Without this, Ghost will create a new database file every time it starts. We're using the `/ghost-data` directory as the volume on the host machine. And it will mirror the content directory in the container.

We're also specifying an alpine image, which is a lightweight, minimalistic image that is optimized for running Ghost. Once the image has been pulled, it will begin running in the background. You can confirm this with the following command:

```bash
docker ps
```

after which you should see the following output:

```bash
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                    NAMES
00cc984651as   ghost:alpine   "docker-entrypoint.s…"   33 minutes ago   Up 33 minutes   0.0.0.0:2368->2368/tcp   ghost-blog
#NOTE: Your container ID will be different.
```

### Check it out

At this point, you can access your blog at http://localhost:2368. If you've never used Ghost before, you'll need to create a new user by visiting http://localhost:2368/ghost and clicking "Create your account". Once you've created your own account, you'll be able return to http://localhost:2368/ghost and log in to the dashboard. To clear out the sample data, you'll need to delete the user "Ghost". To do this, click the cog icon on the bottom left of the page and select "Staff". Select the user "Ghost" and click the cog icon on the top right of the page, then click "Delete User". You'll be prompted to confirm the deletion. Once you've confirmed, you'll have cleared out the sample data and now have a fresh slate to work with!


<img src="https://storage.googleapis.com/tobyhagan_post_images/clear-data.webp" width="1000" height="602" alt="Welcome to Ghost Page">

### Make a post

Ghost has made authoring posts amazingly simple. To create a post, simply click the "New Post" button on the dashboard. You'll be greeted by Ghost's new post editor, which gives you a clean interface for Authoring. For this demonstration, we'll just be creating a test post. Input some test data and click "Publish", Ghost will ask if you want to publish now or later. Click "Publish Now" and your post is instantly available. To view your post, click the "View Post" button on the right sidebar.

### Check data persistence

Once you are satisfied with the test post, go ahead and stop the docker image by running the following command:

```bash
docker stop ghost-blog
```

then restart it with the following command:

```bash
docker start ghost-blog
```

and visit http://localhost:2368/ to see your post. You should be greeted with the test post you created in the previous step. If your post is still there, you've successfully installed Ghost and are ready to go!

<img src="https://storage.googleapis.com/tobyhagan_post_images/screencapture-localhost-2368-2022-01-02-15_47_44.webp" width="1000" height="550" alt="Test post persisted by Docker">

If you'd like to learn more about Ghost, check out the [official documentation](https://docs.ghost.org/), or the [community forum](https://forum.ghost.org/).