I'm currently running blog.alexgittings.co.uk from an AWS Ubuntu instance which runs multiple blogs and websites with the use of VESTA panel.

The bill for my AWS 1GB instance is becoming too much to pay as I go back to being a full-time student after returning from placement (I've used all my student AWS credit).

However, I have been playing with Docker a little bit and learning from David I have been able to migrate my Ghost blogs over to Docker.

I will be hosting my Docker instance with DigitalOcean as its relatively cheap plus I have a little credit ;).

Getting Started

I will presume you already have Docker installed. If not check out the Docker site for more info...

I will also be using Docker-Compose for this install too. Docker-Compose is a neat way of starting and maintaining multiple Docker containers at the same time with a single .YML file. To learn more about this and how to install it check it out here.

To migrate docker we will need to backup the contents folder from your current install. I have mine backing up to AWS S3 Storage nightly so I will pull mine from there.

Prep

I will be setting up a folder structure to keep all my valuable information such as docker-compose.yml as well as my blog contents folders and my Nginx config.

It will look like this:
/opt/docker/ /opt/docker/ghost /opt/docker/nginx

Use the following commands to make this file structure:

mkdir -p /opt/docker/nginx
mkdir -p /opt/docker/ghost

Copy docker contents to ghost directory

In my case, I will be downloading my contents from an FTP server and using the unzip command to unpack the archive. But any method will work.

ftp example.com port-number
*credentials*
get ghost-blog.zip
unzip ghost-blog.zip

Now we should have a folder within /opt/docker/ghost called content.

The contents directory holds all the files that are valuable such as themes, images and the database. Speaking of the database we need to rename it a little. The environment I'm moving it from using the production database which is named ghost.db where as the docker image by default uses the dev database named ghost-dev.db this is simple to do simply use mv /opt/docker/ghost/content/data/ghost.db /opt/docker/ghost/content/data/ghost-dev.db.

Create Nginx container for the default files

To get the Nginx container started we need to download some files. To do this we need to create a tempory container, copy the files and then remove it.

docker run --rm -it -v /opt/docker:/tmp/nginx nginx cp -rv /etc/nginx/ /tmp/nginx/ 

Once this is completed we will have all the files we need to get started in /opt/docker/nginx.

Configuring Nginx

To route traffic to the blog we need to edit the default site within the NGINX configuration.

nano /opt/docker/nginx/conf.d/default.conf

Paste this config in:
upstream blog
{
    server blog:2368;
}

server
{
    listen 80 default;

    server_name blog1.alexgittings.co.uk;

    location /
    {
        proxy_pass http://blog;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server_name = domain name
proxy_pass = http://container-name

Docker Compose

We can now put together our docker file to see if it works!!

cd /opt/docker
nano docker-compose.yml

version: '3.2'
services:
 blog:
  container_name: blog
  restart: always
  image: ghost:alpine
  volumes:
   - /opt/docker/ghost/content:/var/lib/ghost

 nginx:
  container_name: nginx
  restart: always
  image: nginx:alpine
  volumes:
   - /opt/docker/nginx/:/etc/nginx/
  ports:
   - "80:80"

Run the docker container using docker-compose up -d

you should see an output of:

root@Docker:/opt/docker# docker-compose up -d
Pulling blog (ghost:alpine)...
alpine: Pulling from library/ghost
90f4dba627d6: Pull complete
302ce48cc185: Pull complete
e1c17ba3935d: Pull complete
1a86fd5d5e80: Pull complete
e6139c361248: Pull complete
8a700ec450ff: Pull complete
e8db228789f6: Pull complete
5b4133c4fb9c: Pull complete
c97fdc920c32: Pull complete
Digest: sha256:acda68ca051787139a162b8748dfd5efbccb45f98899ad0d76f30220c65dd47b
Status: Downloaded newer image for ghost:alpine
Pulling nginx (nginx:alpine)...
alpine: Pulling from library/nginx
019300c8a437: Pull complete
a3fe4a77433d: Pull complete
a5443900e7f5: Pull complete
0ae275323c0f: Pull complete
Digest: sha256:24a27241f0450b465f9e9deb30628c524aa81a1aa6936daa41ef7c4345515272
Status: Downloaded newer image for nginx:alpine
Creating blog ...
Creating nginx ...
Creating blog
Creating nginx ... done
root@Docker:/opt/docker#

navigating to the domain of blog1.alexgittings.co.uk we are greeted with the migrated website. Success!!!!

Adding more Ghost blogs!

Adding more blogs doesn't take much more effort.

Copy the content folder as done previously into a folder.

Add another service to the docker-compose.yaml

version: '3.2'
services:
 blog:
  container_name: blog
  restart: always
  image: ghost:alpine
  volumes:
   - /opt/docker/ghost/content:/var/lib/ghost

 blog2:
  container_name: adjarvis
  restart: always
  image: ghost:alpine
  volumes:
   - /opt/docker/ghost/blog2/content:/var/lib/ghost

 nginx:
  restart: always
  image: nginx:alpine
  volumes:
   - /opt/docker/nginx/:/etc/nginx/
  ports:
   - "80:80"

create another file within /opt/docker/nginx/conf.d

nano adjarvis.conf

pstream adjarvis
{
    server adjarvis:2368;
}

server
{

    listen 80;

    server_name blog2.alexgittings.co.uk;

    location /
    {
        proxy_pass http://adjarvis;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

run docker-compose up -d again and navigate to blog2.alexgittings.co.uk and you will be greeted with another blog. This can be done multiple times until resources run out obviously!!