Setting Up Staging for Personal Purposes
Like many developers, I often face the task of quickly deploying a test/showcase environment for a project.
A couple of years ago, I came up with a simple solution that saves time and money based on Ubuntu, Nginx, and Docker Compose.
Choosing a platform for staging
For a while now, I have been using VPS for such tasks. Just a month ago, I reevaluated the price-quality ratio and settled on the option of https://www.hetzner.com/cloud CX21.
For 5.88 euros, you get a 2-core CPU, 4GB of RAM, and a 40GB SSD. Compared to, for example, DigitalOcean, it’s affordable. And for an additional 1.18 euros, you can ensure regular backups.
What will be on staging
We will deploy a VPS, set up a firewall, install Nginx, Certbot for certificates, and Docker Compose.
Basic server setup
Firewall configuration
$ ssh root@your_server
$ ufw app list
$ ufw allow OpenSSH
$ ufw status
Key-based access only
Edit the file:$ vim /etc/ssh/sshd_config
and set the value no
for PasswordAuthentication no
Then restart SSH:$ systemctl restart ssh
Installing Docker and Docker-Compose
Installing Docker
$ apt update
$ apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
$ apt-cache policy docker-ce
$ apt install docker-ce
$ systemctl status docker
Installing docker-compose
Choose the desired version from the page https://github.com/docker/compose/releases.
$ 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
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
Installing and configuring Nginx
$ apt update
$ apt install nginx
$ ufw app list
$ ufw allow "Nginx Full"
$ ufw status
Instructions for installing Certbot from Let’s Encrypt: https://certbot.eff.org/instructions
Preparing basic authentication for future projects (optional)
$ apt install apache2-utils
$ htpasswd -c /etc/nginx/htpasswd YOUR_LOGIN
To update the password:$ htpasswd /etc/nginx/htpasswd YOUR_LOGIN
To create a separate user for managing Docker Compose
$ adduser deployer --disabled-password
$ sudo usermod -aG docker deployer
$ sudo usermod -aG docker deployer
$ su - deployer
$ groups
If desired, you can set up key-based authentication for the deployer user to enable deployment from CI.
How to deploy an application (using Strapi as an example)
$ vim /etc/nginx/sites-enabled/strapi
Insert the following content:
server {
server_name strapi.YOUR_DOMAIN;
# Uncomment the lines below if you want to restrict access using the previously set up basic authentication
# auth_basic "Restricted";
# auth_basic_user_file /etc/nginx/htpasswd;
access_log syslog:server=[2001:db8::1]:1234,facility=local7,tag=nginx,severity=info;
location / {
proxy_pass http://127.0.0.1:1337;
}
}
Then restart Nginx:
$ service nginx restart
To issue a certificate, run certbot
and follow the instructions.
Next, switch to su - deployer
and create a docker-compose.yml
file.
version: '3'
services:
strapi:
image: strapi/strapi
environment:
DATABASE_CLIENT: postgres
DATABASE_NAME: strapi
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_USERNAME: strapi
DATABASE_PASSWORD: strapi
volumes:
- ./app:/srv/app
ports:
- '1337:1337'
depends_on:
- postgres
postgres:
image: postgres:13-alpine
environment:
POSTGRES_DB: strapi
POSTGRES_USER: strapi
POSTGRES_PASSWORD: strapi
volumes:
- ./data:/var/lib/postgresql/data
Then run docker-compose up -d
Update from 2022-07-14
I have created an Ansible playbook for setting up staging: https://github.com/deeravenger/ansible-staging-example