I assume that you have an account on AWS. Log in, go to Amazon Lightsail and click Create Instance. During this process, you can choose where your instance should be located (region and availability zone) and which system should be installed. I chose Frankfurt (eu-central-1a) and Ubuntu Linux.
We won’t need launch scripts but we will have to create SSH key pair. We will need it later for connecting to the instance. Click Change SSH key pair and click Create new. Type a name, click Generate key pair, download keys and put them in
~/.ssh directory. We have to change key permissions before use.
chmod 400 ~/.ssh/eshlox-net.pem
Next, choose a plan. I choose the cheapest plan, it’s enough for me.
The last step, name your instance and click Create button.
We have to wait for the instance to be ready. When the instance has a status Running, we can log in.
We should attach a static IP. Go to AWS Lightsail, select Create static IP button, choose the same region and zone which were chosen for your instance, attach it to your instance, select IP address name, and click Create. From now on, you can use the newly created IP address and your blog will be accessible under it.
We can log in to the instance in two ways. We can use web SSH client or use SSH from our system. I choose the second one. Select Your instance and get the public IP address. In my case, the SSH command looks like this:
ssh -i ~/.ssh/eshlox-net.pem [email protected]
First thing after login, let’s update our system.
sudo apt update && sudo apt upgrade
Now, let’s install Docker. You can check Docker documentation if you want to read more about Docker installation. I will post here only required commands without description.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt update sudo apt install docker-ce
We want to execute Docker commands without sudo, let’s add
ubuntu user to the docker group.
sudo groupadd docker sudo usermod -aG docker $USER
Configure Docker to start on boot.
sudo systemctl enable docker
Log out, log back and run
docker info to check if Docker works.
Time to install Ghost blog. In this post I will use Ghost in version 0.11.11. If you read this post in the future, change version to the newest one.
Create the directory where you will keep blog data.
The command below will do this:
- download Ghost in version 0.11.11
- run Docker container
- mount our
/var/lib/ghostinside Docker container and store blog data there
- map port 2368 to 80 so we will be able to access our blog on port 80
Of course, you can change the name of the container.
docker run --name eshlox-net -v /home/ubuntu/blog_content:/var/lib/ghost -p 80:2368 ghost:0.11.11-alpine
The output of the command should look like this:
[[email protected] ~]$ docker run --name eshlox-net -v /home/ubuntu/blog_content:/var/lib/ghost -p 80:2368 ghost:alpine Unable to find image 'ghost:alpine' locally 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 npm info it worked if it ends with ok npm info using [email protected] npm info using [email protected] npm info prestart [email protected] npm info start [email protected] > [email protected] start /usr/src/ghost > node index WARNING: Ghost is attempting to use a direct method to send email. It is recommended that you explicitly configure an email service. Help and documentation can be found at https://docs.ghost.org/v0.11.9/docs/mail-config. Migrations: Creating tables... Migrations: Creating table: posts Migrations: Creating table: users Migrations: Creating table: roles Migrations: Creating table: roles_users Migrations: Creating table: permissions Migrations: Creating table: permissions_users Migrations: Creating table: permissions_roles Migrations: Creating table: permissions_apps Migrations: Creating table: settings Migrations: Creating table: tags Migrations: Creating table: posts_tags Migrations: Creating table: apps Migrations: Creating table: app_settings Migrations: Creating table: app_fields Migrations: Creating table: clients Migrations: Creating table: client_trusted_domains Migrations: Creating table: accesstokens Migrations: Creating table: refreshtokens Migrations: Creating table: subscribers Migrations: Running fixture populations Migrations: Creating owner Ghost is running in development... Listening on 0.0.0.0:2368 Url configured as: http://localhost:2368 Ctrl+C to shut down
Now, you can access your blog using public IP address which is attached to your instance.
Now, we have to set up Docker container to run it automatically when the system starts.
Ctrl+C to kill container with Ghost blog.
/etc/systemd/system/[email protected] file. Of course, change
eshlox-net to your container name. File content:
[Unit] Description=Docker Container %I Requires=docker.service After=docker.service [Service] Restart=always ExecStart=/usr/bin/docker start -a %i ExecStop=/usr/bin/docker stop -t 2 %i [Install] WantedBy=default.target
Now, let’s edit this service and configure our container.
systemctl edit [email protected]
This command will open a text editor. Put this content there:
[Service] ExecStart= ExecStart=/usr/bin/docker run -v /home/ubuntu/blog_content:/var/lib/ghost -p 80:2368 -e NODE_ENV=production --name %i ghost:0.11.11-alpine ExecStopPost=/usr/bin/docker rm -f %i
Notice that the line which starts with
ExecStart contains similar parameters as our previous command.
Reload systemctl to apply our changes.
Start our container.
sudo systemctl start [email protected]
Enable newly created service to start our container on system boot.
sudo systemctl enable [email protected]
Go to your public IP and check if Ghost blog works. You can also restart the instance and check if it automatically starts on boot.
How to update Ghost?
It’s very simple.
Edit our service configuration.
systemctl edit [email protected]
Change the Ghost version, for example, change
ExecStart=/usr/bin/docker run -v /home/ubuntu/blog_content:/var/lib/ghost -p 80:2368 -e NODE_ENV=production --name %i ghost:0.11.10-alpine
ExecStart=/usr/bin/docker run -v /home/ubuntu/blog_content:/var/lib/ghost -p 80:2368 -e NODE_ENV=production --name %i ghost:0.11.11-alpine
sudo systemctl restart [email protected]
It will automatically download new Ghost image and use it when the container starts.
How to check container logs?
It useful when you want to debug issues with Ghost or Docker container.
journalctl -u [email protected] -b
As always, change your
eshlox-net.service to your service name.
AWS Lightsail allows us to create a backup which I recommend to do at least before every system update and Ghost blog update. If something breaks, you can use a snapshot to restore the system.