Ghost 2.0 blog on Dokku as NPM package + MYSQL + S3
I recently updated my Ghost blog to version 2.0, which is running on a Dokku server. I couldn't see any instructions on how to do this with NPM packages, so here's how I managed to do it.
I did find some help in setting up the MYSQL database on this blog.
I'm going to call the blog myblog
, but you should replace that with whatever you want to call yours.
Setup Ghost 2 and deploy to a Dokku server
In the first part, we create the NPM package blog, connected to a MYSQL database running on our Dokku server.
Set up the Dokku app
If you don't already have the dokku-mysql
package installed, follow the installation instructions.
SSH into your Dokku server, then
dokku apps:create myblog
dokku mysql:create myblog
# mysql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:3306/<DB_NAME>
dokku mysql:link myblog myblog
dokku mysql:expose myblog
# -----> Service myblog exposed on port(s) [container->host]: 3306-><EXTERNAL_PORT>
dokku config:set --no-restart myblog NODE_ENV=production \
database__connection__password=<DB_PASSWORD>
Take note of your DB_
configs & <EXTERNAL_PORT>
for later.
Create your blog repo
This is how to create the blog repo from scratch. You will need to have Node.js (with NPM) installed.
mkdir myblog
cd myblog
# initalise the package.json
npm init
# add your own description
# entry point will be "node_modules/ghost/index.js"
# there's no "test" command
# use the defaults, or add your own preferences
Edit package.json
to add the "start" script and "engines".
...
"scripts": {
"start": "node node_modules/ghost/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"engines": {
"node": "10.16.0"
},
...
Install Ghost
npm i ghost
Link the casper theme using a symlink
mkdir -p content/themes
cd content/themes
ln -s ../../node_modules/ghost/content/themes/casper casper
cd ../..
Create the development config
Create a new file called config.development.json
in the root of your project, and add the following, replacing the DB info from earlier and your Dokku server domain.
{
"url": "http://localhost:2368/",
"server": {
"port": 2368,
"host": "127.0.0.1"
},
"database": {
"client": "mysql",
"connection": {
"host": "<DOKKU_SERVER_HOST>",
"user": "mysql",
"password": "<DB_PASSWORD>",
"database": "<DB_NAME>",
"port": "<EXTERNAL_PORT>"
}
},
"mail": {
"transport": "Direct"
},
"logging": {
"transports": ["stdout"]
},
"process": "local",
"paths": {
"contentPath": "../../content/"
}
}
Running locally
You should now be able to run your blog locally
npm start
Your database tables will be set up, and your blog will be running at http://localhost:2368/. You can check it out, and even set up your username and password at http://localhost:2368/ghost.
Deploying to Dokku server
Copy the config
cp config.development.json config.production.json
and edit it, removing the password, adding the Dokku server details, and using the DB_HOST
from earlier.
{
"url": "http://myblog.<DOKKU_DOMAIN>/",
"server": {
"port": 5000,
"host": "0.0.0.0"
},
"database": {
"client": "mysql",
"connection": {
"host": "<DB_HOST>",
"user": "mysql",
"database": "<DB_NAME>",
"port": "3306"
}
},
"mail": {
"transport": "Direct"
},
"logging": {
"transports": ["stdout"]
},
"process": "local",
"paths": {
"contentPath": "../../content/"
}
}
Setup the Git repo and deploy
(You will need to have Git installed).
git init
# we don't want to add the passwords
echo "config.development.json" >> .gitignore
git add .
git commit -m "Initial commit with Ghost."
git remote add dokku dokku@<DOKKU_DOMAIN>:myblog
git push dokku master
So now you have a blog, with the default, Casper theme, connected to a MYSQL.
You can connect to it at http://myblog.<DOKKU_DOMAIN>/ghost
and start writing posts.
Add S3 Storage
If you upload any photos, and then deploy an update, all your images will be gone. To make them stick around, they need to be stored somewhere that's going to stick around – like Amazon Web Services S3.
Setup your AWS account, if you haven't already, and create a new S3 bucket. Let's call ours myblog
. There are some regions which don't work out of the box, but eu-west-1
(Ireland) and us-east-1
(N. Virginia) work fine.
In the AWS console again, create an IAM user, eg. myblog-s3
, and select Programatic Access. On the permissions page, select Attach existing policies directly and click to Create policy. For the policy click on the JSON editor and add the following policy. (Replace where it says myblog
with the name of your S3 bucket.)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::myblog"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:PutObjectVersionAcl",
"s3:DeleteObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::myblog/*"
}
]
}
Save it with a name like myblog-s3-access
, then go back to the IAM user. Refresh the list, and search and choose your new policy.
You should see your new Access Key
and Secret Access Key
Copy the access key, SSH into your your Dokku server, and add it to your app's config.
dokku config:set myblog storage__s3__secretAccessKey=<SECRET_ACCESS_KEY>
Update Config
Now update your config.development.json
...
"storage": {
"active": "s3",
"s3": {
"accessKeyId": "<ACCESS_KEY>",
"secretAccessKey": "<SECRET_ACCESS_KEY>",
"bucket": "myblog",
"region": "<AWS_REGION>"
}
}
And your config.production.json
, without the secret.
...
"storage": {
"active": "s3",
"s3": {
"accessKeyId": "<ACCESS_KEY>",
"bucket": "myblog",
"region": "<AWS_REGION>"
}
}
Install an S3 storage adapter
npm i ghost-storage-adapter-s3
mkdir -p content/adapters/storage
cd content/adapters/storage
ln -s ../../../node_modules/ghost-storage-adapter-s3 s3
cd ../../..
Update Git, and push to redeploy
git add .
git commit -m "Added s3 storage."
git push dokku master
And now you can upload pretty pictures to your blog.
Increase your file size limit
By default, Nginx on Dokku only allows you to upload a max of 1MB. You can increase this by adding an Nginx config template to your repo. Copy the template file from the Dokku repo, and add it to your project root. Then edit it, adding a line just before the location
in the server
block. (I had two with HTTPS enabled).
# nginx.conf.sigil
...
client_max_body_size 3m;
location / {
...
Update Git and push to deploy
git add .
git commit -m "Increased file upload limit."
git push dokku master
Add Gmail
If you want your server to be able to send emails, you can add Gmail settings. But don't use your regular password – set up an App Password.
Preparing Gmail config
- From Gmail, click your icon in the top right and choose Google Account
- Choose Security
- Under Signing into Google, follow the steps to enable 2-Step Verification
- Back in Security, follow the steps to create an App password
- Copy this password to use as
<GMAIL_APPLICATION_PASSWORD>
below
Add config to Dokku
SSH into your Dokku server, then
dokku config:set --no-restart myblog mail__options__auth__pass="<GMAIL_APPLICATION_PASSWORD>"
Update Config
Now update your config.development.json
...
"mail": {
"transport": "SMTP",
"options": {
"service": "Gmail",
"auth": {
"user": "<GMAIL_USER>",
"pass": "<GMAIL_APPLICATION_PASSWORD>"
}
}
},
And your config.production.json
, without the secret.
...
"mail": {
"transport": "SMTP",
"options": {
"service": "Gmail",
"auth": {
"user": "<GMAIL_USER>",
}
}
},
Update Git and push to deploy
git add .
git commit -m "Added Gmail settings."
git push dokku master
Adding a theme
You can added a theme using NPM too. I'm using Massively here.
npm i github:TryGhost/Massively#32a8a6c # latest commit on GitHub
cd content/themes
ln -s ../../node_modules/massively massively
cd ../..
Update Git and push to deploy
git add .
git commit -m "Added Theme settings."
git push dokku master
Then log in to your blog at /ghost
, go to Settings > Design and make the new theme active