Install Ghost on ServerPilot and Digital Ocean in 2022
Start by creating a new app (eg. ghost_app
). PHP version doesn't matter since we run NodeJS anyway. I used an existing serverpilot
user. If you choose a different name for the app and a different user remember that PATH will change later on in the guide: /srv/users/USERNAME/apps/APPNAME/
Login is as root and install or update NodeJS to v 16.17.0. which is the lates supported version for Ghost.
ssh root@YOUR_IP_ADDRESS
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash
sudo apt-get install -y nodejs
node -v
And you will get the version
> 16.17.0
While you are logged in as root create a ghost user:
adduser ghostinstall
usermod -aG sudo ghostinstall
And install Ghost-CLI (or update if you already have it installed like I did)
npm install -g ghost-cli@latest
Now log in with the new user ghostinstall
(this is a different/second user name than the serverpilot
user we used creating the app. You will now chown the folder to the new user and remove index.php in the public folder. The public folder needs to be completely empty!
ssh ghostinstall@YOUR_IP_ADDRESS
cd /srv/users/serverpilot/apps/ghost_app/
sudo chown -R ghostinstall:ghostinstall .
cd public
rm index.php
Create a new Database in Serverpilot and call it ghost_db and write down the username and password which be generated for you (a long hex value). You will need all the info in the next step.
Now while in /srv/users/serverpilot/apps/ghost_app/public
ghost install
You will need to provide some info in the last step. If you for some reason make blunder you can run ghost setup
to correct the info.
? Enter your blog URL: https://YOURDOMAIN
? Enter your MySQL hostname: localhost
? Enter your MySQL username: SOME_HEX_VALUE
? Enter your MySQL password: [hidden] SOME_HEX_VALUE
? Enter your Ghost database name: ghost_db
✔ Configuring Ghost
✔ Setting up instance
+ sudo chown -R ghost:ghost /srv/users/serverpilot/apps/ghost_App/public/content
? Sudo Password [hidden]
✔ Setting up "ghost" system user
ℹ Setting up "ghost" mysql user [skipped]
Nginx is not installed. Skipping Nginx setup.
ℹ Setting up Nginx [skipped]
Nginx setup task was skipped, skipping SSL setup
ℹ Setting up SSL [skipped]
? Do you wish to set up Systemd? Yes
? Do you want to start Ghost? Yes
And the final steps
Check which port your ghost is running (2368 is default) but I have two other ghost instances running already so my port is 2370.
cd /srv/users/serverpilot/apps/ghost_app/public
cat config.production.json
>
{
"url": "https://YOURDOMAIN",
"server": {
"port": 2370,
"host": "127.0.0.1"
},
nano .htaccess
And paste this, save and exit (Ctrl+X and Yes) and use the portnumber from above.
RewriteRule index.html http://localhost:2370/ [P]
RewriteRule (.*) http://localhost:2370/$1 [P]
And at last you need the serverpilot
to own the .htaccess
file
sudo chown -R serverpilot:serverpilot .htaccess
Troubleshooting
Permission error when running ghost run
ghost run
>
node:internal/modules/cjs/loader:959
throw err;
^
Error: Cannot find module '/srv/users/serverpilot/apps/ghost_app/public/current/index.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:956:15)
at Function.Module._load (node:internal/modules/cjs/loader:804:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Fix (if you you are logged in as ghostinstall and run ghost run
)
sudo chown -R ghostinstall:ghostinstall ./content
Remove the bootstrap-socket
section in config.production.json
nano config.production.json
Use Ctrl+K to remove one line in nano
"bootstrap-socket": {
"port": 8000,
"host": "localhost"
}
Don't forget to remove the comma to make it a valid JSON
"process": "systemd",
"paths": {
"contentPath": "/srv/users/serverpilot/apps/ghost_app/public/content"
}, <--- REMOVE THE COMMA
}
Change permission of the content
folder. (Ghost will tell you to run with ghost:ghost - that is wrong if your ghostinstall. (Same as the error with ghost run
)
sudo chown -R ghostinstall:ghostinstall ./content
Make sure systemd uses the correct User ID for ghostinstall
cat /etc/passwd | grep ghostinstall
>
ghostinstall:x:1006:1006:Ghost Install,,,:/home/ghostinstall:/bin/bash
sudo cat /lib/systemd/system/ghost_example-com.service
>
[Unit]
Description=Ghost systemd service for blog: newii-se
Documentation=https://ghost.org/docs/
[Service]
Type=simple
WorkingDirectory=/srv/users/serverpilot/apps/ghost_app/public
------------------------------------------
User=1003 <- THIS NUMBER MUST MATCH
------------------------------------------
Environment="NODE_ENV=production"
ExecStart=/usr/bin/node /usr/bin/ghost run
Restart=always
[Install]
WantedBy=multi-user.target
Start the service deamon manually instead of ghost run
sudo systemctl start ghost_example-com
Ghost assumes the User ID in /lib/systemd/system/ghost_example-com.service
must be ghost
✖ Starting Ghost: newii-se
A SystemError occurred.
Message: Systemd process manager has not been set up or is corrupted.
Help: Run ghost setup linux-user systemd and try again.
Fix: Just start the deamon instead of ghost run
sudo systemctl start ghost_example-com
Use useful commands (note the use of dash instead of the dot, and small-caps)
systemctl cat ghost_example-com.service
journalctl -u ghost_example-com -n 50
stat --format '%a' <file>
Links