Overview of the context in three points:
- The objective of this series is to facilitate (automate) the spawning of Ghost blogs
- This blog comes after part I - localhost, where I focused on one's computer
- The targeted audience are developers/ops who wish to build / wipe out ghost instances in a breeze
Would you be interested, please take a seat and make yourself at home, I will try 1) to make your reading comfortable, 2) to lead you to the magic world where Ghosts appear from thin air... and 3) to give you the magic wand that will pop out:
Appetizer: the repo(s)
In order to fulfil my promises, I will make use of two repositories:
- prod-stack, which I have already introduced in the first blog. This repo will act as router and proxy for free, including the discussions with Let's Encrypt
- ghost-in-a-shell, which basically is the material behind the blogs.
By cloning those two guys, and setup a few variables, you will be able to create your ghost instances with our old pal make
Quick setup for prod-stack
Just to save you a return ticket to the first blog, here are the few steps necessary to get the prod-stack up and serving:
$ git clone git@github.com:ebreton/prod-stack.git
Cloning into 'prod-stack'...
...
$ cd prod-stack
$ make
cp etc/traefik.toml.sample etc/traefik.toml
cp etc/db.sample.env etc/db.env
sed -i s/password/auMr9jsMrPnX0Oatb9j4yX2AYBN2jTQV/g etc/db.env
Generated etc/db.env
docker-compose pull
Pulling nginx-entrypoint ...
...
Once the logs stabilize, you can Ctrl-C
to get back on the command line, and docker ps
to check that the stack is running.
The Traefik dashboard will be available on http://localhost:8081 "protected" by Basic Authentication with the user test/test
Quick setup for ghost-in-a-shell
Well, you should have make, docker and the prod-stack installed at this point.
You are ready to spawn a blog on http://localhost:3001 with make
, or on http://localhost/ghost-local with make traefik
.
Let's see how to do better!
from here on, running a container with
make
will be called the standalone mode. Running a container withmake traefik
will be called the traefik mode (how original!)
Starters: environment variables
The two modes make use of environment variables, with default values defined in the (well commented) .env file.
If you happen to delete this file, make
will complain
$ rm .env
$ make
.env file is missing
make: *** [check-env] Error 1
If .env is found, you will be able to check its values with make vars
$ make vars
# values that will be used to create the blog URL
NAME=ghost-local
PROTOCOL=http
DOMAIN=localhost
PORT=3001
URI=ghost-local
Changing the configuration of the instance is a matter of changing those variables:
- either directly in the .env file
- or in your environment, e.g. adding
export NAME=blog
in your terminal (or in your .bashrc when it comes to some other variables that will vary less in time, e.g PROTOCOL) - or in the command line, e.g.
PORT=3002 make
$ export NAME=blog
$ PORT=3002 make vars
# values that will be used to create the blog URL
NAME=blog
PROTOCOL=http
DOMAIN=localhost
PORT=3002
URI=ghost-local
The variables should be self explanatory, especially if you think PROTOCOL://DOMAIN:PORT/URI, but it never hurts to spell the words, so here is a quick summary of the variables, with their default values and which mode uses them
Variable | Description | default value | used by standalone / traefik mode |
---|---|---|---|
NAME |
for the docker container and the data folder | ghost-local | both |
PROTOCOL |
to build the URL | http | traefik |
DOMAIN |
to build the URL | localhost | both |
PORT |
to build the URL | 3001 | standalone |
URI |
to build the URL | ${NAME} | traefik |
The Main Dish: HTTPs
So here we are, we wish to run an instance on http://my.domain.com/my-blog
I guess the following command is not going to be too much of a shock for you:
DOMAIN=my.domain.com URI=my-blog make traefik
You might actually have jumped straight to http*S*://my.domain.com/my-blog with PROTOCOL=https DOMAIN=my.domain.com URI=my-blog make traefik
That's fine, if you had also anticipated
- The DNS configuration, i.e my.domain.com is already pointing to your server
- The traefik configuration, and in particular if you have setup your own email address in the traefik.toml file as directed in prod-stack/README.
By the way, do not forget to change the Basic Authentication used to access Traefik dashboard (also pointed out in prod-stack/README)
In this case, you could actually export PROTOCOL=https
and export DOMAIN=my.domain.com
in your environment, and simply run URI=my-other-blog make traefik
.
If you hadn't anticipated... well... you now know what to do :
- Set DNS config at your preferred provider
- Adapt Traefik config in prod-stack
- Ease your process by adding some variables to your environment
As a bonus, you can also force the redirection of http to http*s* (and raw domain.com to www.domain.com as an extra bonus). This is done by Nginx, and through the configuration sample in the repo, which you just have to move to the ./etc/conf.d folder, and then restart the stack
$ cd /path/to/prod-stack
$ mv ./etc 002-redirect-to-https.conf.sample ./etc/conf.d/002-redirect-to-https.conf
$ make
...
Doing all of this will
- redirect http://domain.com/blog to https://www.domain.com/blog (which go well beyond our initial objectives, but hey! that's nice and free, and optional)
- get a certificate from Let's Encrypt for www.domain.com
- serve the blog
But there is more...
Digestive: helpers
We have already used make vars
that listed the values of the environment variables.
There is a few other helpers command, which are listed in the table below:
Command | Description | Variables used |
---|---|---|
make vars |
Display the values of all env vars | All |
make ps |
Display the running containers | None |
make shell |
Connect to given Ghost container | NAME |
make logs |
Tail and follow the logs of given Ghost container | NAME |
make stop |
Stop given Ghost container | NAME |
There is really few to say here, they are just convenient wrappers around standard docker commands.
Dessert (conclusion)
I must admit that I am quite satisfied with the outcome of this second blog.
We just have one tiny little bit of work to cope with now: the technical debt !
More seriously, the choices made so far are shortcuts for most of them.
- Ghost is running in development mode,
- and still uses sqlite.
- Not to mention there is no monitoring neither backup of anything (by the way, do not forget that you have Ghost(Pro) to relieve you from those burdens).
It is therefore a very appropriate time for a very big red disclaimer:
do NOT use this stack in production
Next?
I will look more deeply into Ghost setup in next blog: its running mode and the DB to start with...
Top comments (1)
I love to be part of a culture where a consequent number of people like ghost in the shell and evangelion :)