For anyone interested - these instructions should get a Ghost/MySQL instance up and running in production mode on the Opalstack platform. Here are the variables you need to know in order to use the guide (replace them with the values you choose to assign to each):
MYGHOST = new shell user name
GHOSTAPP = nginx proxy app 1, note assigned port = GAPORT
GHOSTDB = nginx proxy app 2, note assigned port = DBPORT
GHOSTDBNAME = ghost database name
GHOSTDBUSER = ghost db user name
GHOSTDBUSERPWD = ghost db user password
GHOSTDBROOTPWD = ghost db root user password
YOURDOMAIN.COM = domain to use for the app
Pre-installation
- Create a new shell user, e.g. MYGHOST
- Create two NXINX proxy apps GHOSTAPP and GHOSTDB, noting the assigned ports for each
- Create a site record in dashboard assigning GHOSTAPP and YOURDOMAIN.COM, enabling HTTPS too
- SSH to your server using shell user MYGHOST
Setup MySQL Instance
**#Create the MySQL config file**
cd ~/apps/GHOSTDB
mkdir -p {etc,var,tmp}
echo -e "[client]\nport = DBPORT\nsocket = /home/MYGHOST/apps/GHOSTDB/var/mysql.sock\n\n[mysqld]\nport = DBPORT\nsocket = /home/MYGHOST/apps/GHOSTDB/var/mysql.sock\ntmpdir = /home/MYGHOST/apps/GHOSTDB/tmp\ndatadir = /home/MYGHOST/apps/GHOSTDB/data\ninnodb_log_group_home_dir = /home/MYGHOST/apps/GHOSTDB/data\nlog_error = /home/MYGHOST/apps/GHOSTDB/maria.log\npid_file = /home/MYGHOST/apps/GHOSTDB/var/pid\nsql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\n\n[mysqld_safe]\nlog-error = /home/MYGHOST/apps/GHOSTDB/maria.log\npid-file = /home/MYGHOST/apps/GHOSTDB/var/pid" > ~/apps/GHOSTDB/etc/my.cnf
**#Download and setup MySQL**
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.32-el7-x86_64.tar.gz
tar xzf mysql-8.0.32-el7-x86_64.tar.gz --strip-components=1
~/apps/GHOSTDB/bin/mysqld --defaults-file=/home/MYGHOST/apps/GHOSTDB/etc/my.cnf --initialize-insecure --user=$USER --datadir=$PWD/data --tmpdir=$PWD/tmp
**#Start the MySQL instance, login and set up root and new user:**
nohup $HOME/apps/GHOSTDB/bin/mysqld_safe --defaults-file=$HOME/apps/GHOSTDB/etc/my.cnf --socket=$HOME/apps/GHOSTDB/var/mysql.sock > $HOME/apps/GHOSTDB/nohup.out 2>&1 &
~/apps/GHOSTDB/bin/mysql -P DBPORT -S $HOME/apps/GHOSTDB/var/mysql.sock -u root
ALTER USER 'root'@'localhost' IDENTIFIED BY 'GHOSTDBROOTPWD';
create database GHOSTDBNAME;
create user 'GHOSTDBUSER'@'localhost' identified by 'GHOSTDBUSERPWD';
grant usage on *.* to 'ghostdbuser'@'localhost';
grant all on GHOSTDBNAME.* to 'GHOSTDBUSER'@'localhost';
FLUSH PRIVILEGES;
EXIT;
**#How to start/stop database**
Start: nohup $HOME/apps/GHOSTDB/bin/mysqld_safe --defaults-file=$HOME/apps/GHOSTDB/etc/my.cnf --socket=$HOME/apps/GHOSTDB/var/mysql.sock > $HOME/apps/ghostdb/nohup.out 2>&1 &
Stop: $HOME/apps/GHOSTDB/bin/mysqladmin -u root -P DBPORT -S $HOME/apps/GHOSTDB/var/mysql.sock -p shutdown
Setup Ghost Instance w/MySQL -- NOTE: Node v16 support has been dropped as of Ghost 5.71.0 so you will have to compile Node v18.12.1 instead, see the updated official guide here.
**#Get and unpack Nodejs v16.20.0**
cd ~/apps/GHOSTAPP/
wget https://nodejs.org/download/release/latest-v16.x/node-v16.20.0-linux-x64.tar.xz
tar xf node-v16.20.0-linux-x64.tar.xz --strip 1 -C $PWD
**#Export for Node PATH, update NPM and install some Ghost requirements via SCL**
export PATH=$HOME/apps/GHOSTAPP/bin:$HOME/apps/GHOSTAPP/node_modules/.bin:$PATH
scl enable devtoolset-10 -- npm install -g npm@9.8.1
scl enable devtoolset-10 -- npm install --prefix=~/apps/GHOSTAPP @vscode/sqlite3
scl enable devtoolset-10 -- npm install --prefix=~/apps/GHOSTAPP ghost-cli@latest
**#Install the Ghost instance**
mkdir ./instance && cd ./instance
~/apps/GHOSTAPP/node_modules/.bin/ghost install local --port GAPORT --log file --no-start
**#Replace the sqlite3 package**
rm -r ~/apps/GHOSTAPP/instance/current/node_modules/sqlite3
cp -r ~/apps/GHOSTAPP/node_modules/@vscode/sqlite3 ~/apps/ghostapp/instance/current/node_modules/
**#Create the Ghost config file for production, disable default config files**
echo -e '{ \n\t"url": "https://YOURDOMAIN.COM", \n\t"server": { \n\t\t"host": "127.0.0.1", \n\t\t"port": GAPORT }, \n\t"database": { \n\t\t"client": "mysql", \n\t\t"connection": { \n\t\t\t"host": "127.0.0.1", \n\t\t\t"port": DBPORT, \n\t\t\t"user": "GHOSTDBUSER", \n\t\t\t"password": "GHOSTDBUSERPWD", \n\t\t\t"database": "GHOSTDBNAME" \n\t\t} \n\t}, \n\t"paths": { \n\t\t"contentPath": "/home/MYGHOST/apps/GHOSTAPP/instance/content/" \n\t}, \n\t"logging": { \n\t\t"level": "info", \n\t\t"rotation": { \n\t\t\t"enabled": true \n\t\t}, \n\t\t"transports": [\n\t\t\t"file", \n\t\t\t"stdout"\n\t\t], \n\t\t"path": "/home/MYGHOST/logs/apps/GHOSTAPP/"\n\t} \n}' > ~/apps/GHOSTAPP/instance/config.production.json
find ~/apps/GHOSTAPP/instance/versions/X.XX.X/core/shared/config/env/ -type f -name "*.json" -exec sh -c 'mv "$1" "${1%.json}.json-backup"' _ {} \;
**#NOTE**: Replace X.XX.X with the version number that got installed when you used 'ghost install' prior
**#Create start and stop scripts**
echo '#!/bin/bash' > ~/apps/GHOSTAPP/start; echo "PATH=~/apps/GHOSTAPP/bin:\$PATH" >> ~/apps/GHOSTAPP/start; echo "NODE_ENV=production ~/apps/GHOSTAPP/node_modules/.bin/ghost start -d ~/apps/GHOSTAPP/instance --no-setup-linux-user" >> ~/apps/GHOSTAPP/start; chmod +x ~/apps/GHOSTAPP/start; echo '#!/bin/bash' > ~/apps/GHOSTAPP/stop; echo "PATH=~/apps/GHOSTAPP/bin:\$PATH" >> ~/apps/GHOSTAPP/stop; echo "~/apps/GHOSTAPP/node_modules/.bin/ghost stop -d ~/apps/GHOSTAPP/instance --no-setup-linux-user" >> ~/apps/GHOSTAPP/stop; chmod +x ~/apps/GHOSTAPP/stop
**#Start Ghost**
~/apps/GHOSTAPP/start
Post setup instructions
**#Set domain you want to serve the Ghost app with**
cd ~/apps/GHOSTAPP/instance
~/apps/GHOSTAPP/node_modules/.bin/ghost config url https://YOURDOMAIN.COM
~/apps/GHOSTAPP/node_modules/.bin/ghost restart
**#Immediately visit your Ghost admin URL and create the admin user when it's available, e.g.**
https://YOURDOMAIN.COM/ghost/
**#NOTE**: If this process appears to stall, after about 15-20 seconds or so just click the black button you just did again and it should take you to a login page. I haven't seen any problems that stem from this issue yet and the logs were not clear why this was happening.
**#Add cron to keep the app up**
(crontab -l 2>/dev/null; echo "0,10,20,30,40,50 * * * * ~/apps/GHOSTAPP/start > /dev/null 2>&1") | crontab -
**#How to start/stop/restart Ghost app**
~/apps/GHOSTAPP/start
~/apps/GHOSTAPP/stop
export PATH=$HOME/apps/GHOSTAPP/bin:$HOME/apps/GHOSTAPP/node_modules/.bin:$PATH && cd ~/apps/GHOSTAPP/instance && ~/apps/GHOSTAPP/node_modules/.bin/ghost restart
**#Don't forget to setup mail!**
https://ghost.org/docs/config/#mail (note: you have to restart Ghost after modifying any of the config json files)
Updates and maintenance
To run the ghost
command for updates and other maintenance tasks, first set your shell path by running the following command:
export PATH=$HOME/apps/GHOSTAPP/bin:$HOME/apps/GHOSTAPP/node_modules/.bin:$PATH
You'll then be able to run ghost
for updates etc, for example:
export PATH=$HOME/apps/GHOSTAPP/bin:$HOME/apps/GHOSTAPP/node_modules/.bin:$PATH
cd $HOME/apps/GHOSTAPP/instance
ghost backup --no-setup-linux-user
ghost update --no-setup-linux-user
More ghost commands are documented at: https://ghost.org/docs/ghost-cli/
I hope this has been helpful in leui of the current Ghost installer issues! πππ