Step-by-step instructions for setting up the site on a VPS. Ensure that IPv6 is enabled (for Let's Encrypt).
-
Add the user account with a strong password:
sudo adduser kyle
-
Give the user sudo access:
sudo adduser kyle sudo
-
Switch to the new user:
sudo su kyle
-
Create new public and private SSH keys for the user:
ssh-keygen -t rsa
-
Create other files for SSH:
touch ~/.ssh/authorized_keys
touch ~/.ssh/known_hosts
touch ~/.ssh/config
-
(On local machine) Find and copy your SSH public key:
cat ~/.ssh/id_rsa.pub
-
Back on the server, open authorized_keys and paste in your public key:
vim ~/.ssh/authorized_keys
-
(If not done already), set the server to only allow key-based authentication. Open
sshd_config
:sudo vim /etc/ssh/sshd_config
-
Add the following line and save the file:
PasswordAuthentication no
-
Restart the SSH service to apply the change:
sudo service ssh restart
-
(On local machine) Test that key based authentication works.
ssh kyle@servername
-
Check that OpenSSH is in the ufw list:
sudo ufw app list
-
Ensure that we can log in via SSH after the Firewall is enabled:
sudo ufw allow OpenSSH
-
Enable ports 80 and 443 for the web application:
sudo ufw allow 80
sudo ufw allow 443
-
Enable to Firewall
sudo ufw enable
-
Check that SSH connections and port 80 and 443 are allowed:
sudo ufw status
-
Update the existing list of packages:
sudo apt update
-
Install some prerequisite packages which let apt use packages over HTTPS:
sudo apt install apt-transport-https ca-certificates curl software-properties-common
-
Add the GPG key for the official Docker repository to the server:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
-
Add the Docker repository to APT sources:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
-
Update the package database with the Docker packages from the newly added repo:
sudo apt update
-
Check that you are about to install from the Docker repo (instead of the default Ubuntu repo):
apt-cache policy docker-ce
-
Install Docker:
sudo apt install docker-ce
-
Check that Docker is running:
sudo systemctl status docker
-
To run the docker command without typing sudo, add your username to the docker group (log out and in again to apply this):
sudo usermod -aG docker kyle
-
Install Docker Compose (update the release number to use the latest on GitHub):
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
-
Apply executable permissions to the binary:
sudo chmod +x /usr/local/bin/docker-compose
-
Verify the installation:
docker-compose --version
-
Clone the git repo and change into the cloned directory:
cd /var
sudo git clone https://github.com/panzerdragoonlegacy/website.git cms
cd cms
pwd
(should show/var/cms
) -
Copy .env based on .example.env
sudo cp .example.env .env
-
Edit the .env to include the database and mail details.
sudo vim .env
RAILS_ENV=production DB_USER=panzerdragoonlegacy POSTGRES_PASSWORD=PASSWORDHERE DB_NAME=panzerdragoonlegacy DB_HOST=database SECRET_KEY_BASE=abcd1234 SMTP_ADDRESS=smtp.mailgun.org [email protected] SMTP_PASSWORD=PASSWORDHERE
-
If there is already an SSL certificate for this domain, copy an existing
certbot
directory into/var/cms
. Otherwise, temporarily change/var/cms/nginx/default.conf
to contain the following contents the first time that the app is built (see next step) to generate new certificate files:server { listen [::]:80; listen 80; server_name www.panzerdragoonlegacy.com panzerdragoonlegacy.com; location ~ /.well-known/acme-challenge { allow all; root /var/www/certbot; } }
-
Build and start the docker containers, which will also run certbot:
sudo docker-compose -f docker-compose.prod.yml up --build
If generating the SSL certificate, you should see a congratulations message and
certbot exited with code 0
. If certbot exits with a non-zero code, there's an error. -
Check that the SSL certificate files were generated successfully. These will exist in a subdirectory for the domain.
sudo ls -la /var/cms/certbot/conf/live/panzerdragoonlegacy.com
-
If you changed the
default.conf
in step 4, change it back to what it was and restart the app.sudo docker-compose -f docker-compose.prod.yml down
sudo docker-compose -f docker-compose.prod.yml up -d
-
Ensure that there are no errors in the output. If you go to https://panzerdragoonlegacy.com in your web browser you should see the custom 404 error page. Once the database and Paperclip attachments are restored into the volumes that were created by Docker Compose you can verify that the app is fully working (see next steps).
-
On the old server, log in as the web app user:
sudo su thewilloftheancients
-
Get the password for the database from
database.yml
:cat ~/thewilloftheancients/shared/config/database.yml
-
Create a dump of the database as a tar file, pasting in the password from
database.yml
when prompted:pg_dump thewilloftheancients > backup.sql
-
On the new server, get your public key:
cat ~/.ssh/id_rsa.pub
-
Back on the old server, paste the new web app user's public key into the
authorized_keys
file of the old web app user:vim ~/.ssh/authorized_keys
-
On the new server, copy the database dump from the old server to the home directory of the webapp user on the new server:
scp [email protected]:backup.sql ~
-
On the new server, copy the data files in the
system
directory from the old server. These must be copied at the same time as the database so that the record IDs remain in sync:rsync -av [email protected]:~/thewilloftheancients/shared/public/system ~/
-
Stop the app and start the database container only.
sudo docker-compose -f docker-compose.prod.yml stop
sudo docker-compose -f docker-compose.prod.yml start database
-
Open psql in an interactive terminal.
sudo docker exec -it database psql -U postgres
-
Create a user for the webapp that matches what is in the backup:
CREATE USER panzerdragoonlegacy WITH ENCRYPTED PASSWORD 'PASSWORDHERE';
-
Create a database (drop old database first if required):
DROP DATABASE panzerdragoonlegacy;
(if required)CREATE DATABASE panzerdragoonlegacy;
-
Give the user you created full access to the database:
GRANT ALL PRIVILEGES ON DATABASE panzerdragoonlegacy TO panzerdragoonlegacy;
-
Set the owner of the database to the user:
ALTER DATABASE panzerdragoonlegacy OWNER TO panzerdragoonlegacy;
-
Quit postgres:
\q
-
Restore the database from a backup.sql file:
cat ~/backup.sql | sudo docker exec -i database psql -U panzerdragoonlegacy
-
Restart the containers
sudo docker-compose -f docker-compose.prod.yml down
sudo docker-compose -f docker-compose.prod.yml up -d
-
Run any outstanding migrations on the restored database
sudo docker-compose -f docker-compose.prod.yml exec app bin/rails db:migrate
-
Copy the system folder from outside of the container into the volume:
sudo docker cp ~/system app:/cms/public
-
Inside the container, check that the system directory contains the files
sudo docker-compose -f docker-compose.prod.yml exec app bash
cd /cms/public/system
ls -la
exit
-
Restart the app
sudo docker-compose -f docker-compose.prod.yml down
sudo docker-compose -f docker-compose.prod.yml up -d
-
Open the crontab
sudo crontab -e
-
Add the following line to call the script every 5 minutes:
*/5 * * * * /var/cms/ssl_renew.sh >> /var/log/cron.log 2>&1
-
After 5 minutes, check the cron log to see if it succeeded.
tail -f /var/log/cron.log
-
Change the cron job to run every day at noon:
sudo crontab -e
0 12 * * * /var/cms/ssl_renew.sh >> /var/log/cron.log 2>&1
-
Clone the current version of the code repository into a local backup directory. This ensures that data can be restored to the same point in time as the code, if required:
mkdir ~/Backups
(calledBackups
here, but it could be anything)mkdir ~/Backups/cms-backup
cd ~/Backups/cms-backup
git clone https://github.com/panzerdragoonlegacy/website.git
-
On the server, back up the database to your home directory:
sudo docker exec -t database pg_dumpall -c -U postgres > ~/backup.sql
-
From your local machine, download the database backup from the server:
scp kyle@servername:~/backup.sql ~/Backups/cms-backup
-
On the server, delete the backup files:
sudo rm ~/backup.sql
-
Because the Paperclip attachments are quite large, there likely won't be enough disk space to back them up all at once. First, create a copy of the system directory on the server to put these in:
mkdir ~/system
-
Copy each non-main (other) pictures subdirectory from the Docker volume into the new system directory:
sudo docker cp app:/cms/public/system/avatars ~/system/avatars sudo docker cp app:/cms/public/system/category_pictures ~/system/category_pictures sudo docker cp app:/cms/public/system/download_pictures ~/system/download_pictures sudo docker cp app:/cms/public/system/illustrations ~/system/illustrations sudo docker cp app:/cms/public/system/music_track_pictures ~/system/music_track_pictures sudo docker cp app:/cms/public/system/news_entry_pictures ~/system/news_entry_pictures sudo docker cp app:/cms/public/system/page_pictures ~/system/page_pictures sudo docker cp app:/cms/public/system/tag_pictures ~/system/tag_pictures sudo docker cp app:/cms/public/system/video_pictures ~/system/video_pictures
-
Create a tarball of the other pictures:
tar cvzf ~/system-other-pictures.tar.gz ~/system
-
From your local machine, download the other pictures tarball:
scp kyle@servername:~/system-other-pictures.tar.gz ~/Backups
-
Once the download is complete, remove the other pictures from the server to free up space:
sudo rm -rf ~/system/*
sudo rm ~/system-other-pictures.tar.gz
-
Copy the main pictures subdirectory from the Docker volume into the system directory:
sudo docker cp app:/cms/public/system/pictures ~/system/pictures
-
Create a tarball of the main pictures:
tar cvzf ~/system-main-pictures.tar.gz ~/system
-
From your local machine, download the main pictures tarball:
scp kyle@servername:~/system-main-pictures.tar.gz ~/Backups
-
Once the download is complete, remove the main pictures from the server to free up space:
sudo rm -rf ~/system/*
sudo rm ~/system-main-pictures.tar.gz
-
On your local machine, untar the pictures into the system folder and delete the tarball.
mkdir ~/Backups/cms-backup/system
cd ~/Backups/cms-backup/system
tar -xvkf ~/Backups/system-other-pictures.tar.gz
tar -xvkf ~/Backups/system-main-pictures.tar.gz
rm ~/Backups/system-other-pictures.tar.gz
rm ~/Backups/system-main-pictures.tar.gz
-
On the server, copy the remaining files from the Docker volume in the same way:
sudo docker cp app:/cms/public/system/paperclip_attachments.yml ~/system/paperclip_attachments.yml sudo docker cp app:/cms/public/system/flac_music_tracks ~/system/flac_music_tracks sudo docker cp app:/cms/public/system/mp3_music_tracks ~/system/mp3_music_tracks sudo docker cp app:/cms/public/system/mp4_videos ~/system/mp4_videos sudo docker cp app:/cms/public/system/downloads ~/system/downloads
-
Since there are fewer large files, we will skip creating a tarball. Download each set of large files seperately:
scp -r kyle@servername:~/system/paperclip_attachments.yml ~/backups/cms-backup/system/paperclip_attachments.yml scp -r kyle@servername:~/system/flac_music_tracks ~/backups/cms-backup/system/flac_music_tracks scp -r kyle@servername:~/system/mp3_music_tracks ~/backups/cms-backup/system/mp3_music_tracks scp -r kyle@servername:~/system/mp4_videos ~/backups/cms-backup/system/mp4_videos scp -r kyle@servername:~/system/downloads ~/backups/cms-backup/system/downloads
-
Remove the copied files from the server, checking that there are no files remaining in your home directory taking up valuable space on the server:
sudo rm -rf ~/system
ls ~
-
Locally, confirm that the expected directories are present:
ls ~/Backups/cms-backup
backup.sql system website
ls ~/Backups/cms-backup/system
Expected output:
avatars illustrations page_pictures category_pictures mp3_music_tracks paperclip_attachments.yml download_pictures mp4_videos pictures downloads music_track_pictures tag_pictures flac_music_tracks news_entry_pictures video_pictures
-
Create a tarball of the folder containing the three parts of the backup:
cd ~/Backups
tar cvzf ~/Backups/cms-backup.tar.gz cms-backup
-
Rename the tarball to the date of the backup and archive it:
mv cms-backup.tar.gz panzer-dragoon-legacy-1998-01-29.tar.gz
-
On your local machine, remove the cms-backup directory to free up space:
rm -rf ~/Backups/cms-backup