Production Deployment Guide

This guide describes how to deploy SmallBlock CMS for production use on Linux using Gunicorn (or Uvicorn for async apps) behind Nginx.

Note

The development server (smallblock runserver) is not suitable for production. It’s single-threaded and does not handle concurrent requests efficiently.

System Overview

Production deployments typically consist of:

  • Nginx as a reverse proxy and TLS terminator

  • Gunicorn (or Uvicorn) as the application server

  • systemd for process management and automatic restarts

  • PostgreSQL or MariaDB as the database backend

Step 1 — Verify Prerequisites

You should have completed the Quick Setup and have:

  • Python 3.10+ installed

  • SmallBlock CMS installed (smallblock –version)

  • Database configured and migrated

  • Static and media directories created: /srv/smallblock/static and /srv/smallblock/media

Step 2 — Create a Dedicated Service User

sudo useradd --system --home /srv/smallblock --shell /sbin/nologin smallblock
sudo mkdir -p /srv/smallblock/{app,run,logs,static,media}
sudo chown -R smallblock:smallblock /srv/smallblock

Step 3 — Create a systemd Service

Create the file /etc/systemd/system/smallblock.service:

[Unit]
Description=SmallBlock CMS application service
After=network.target

[Service]
Type=simple
User=smallblock
Group=smallblock
WorkingDirectory=/srv/smallblock/app
EnvironmentFile=-/srv/smallblock/app/.env
ExecStart=/usr/bin/python3 -m gunicorn --bind unix:/srv/smallblock/run/smallblock.sock wsgi:app
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Reload systemd and start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now smallblock
systemctl status smallblock --no-pager

Step 4 — Configure Nginx

Create an Nginx site definition in /etc/nginx/conf.d/smallblock.conf:

server {
    listen 80;
    server_name smallblockcms.com;

    location / {
        proxy_pass http://unix:/srv/smallblock/run/smallblock.sock:;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /static/ {
        alias /srv/smallblock/static/;
        access_log off;
        expires 1h;
    }

    location /media/ {
        alias /srv/smallblock/media/;
        access_log off;
        expires 1h;
    }
}

Test configuration and reload:

sudo nginx -t
sudo systemctl reload nginx

You should now be able to visit your server’s IP or domain and see your live site.

Step 5 — Enable HTTPS with Let’s Encrypt

Install Certbot:

# RHEL/Fedora/CentOS
sudo dnf install -y certbot python3-certbot-nginx

# Ubuntu/Debian
sudo apt install -y certbot python3-certbot-nginx

Obtain and install a certificate:

sudo certbot --nginx -d smallblockcms.com

Certbot will: 1. Verify domain ownership 2. Obtain certificates 3. Configure Nginx for HTTPS 4. Set up automatic renewal

Step 6 — Collect Static Files

Run from your project directory:

smallblock collectstatic --noinput
sudo chown -R smallblock:smallblock /srv/smallblock/static

Then reload your service:

sudo systemctl restart smallblock
sudo systemctl reload nginx

Step 7 — Verify Deployment

Run a quick check:

curl -I https://smallblockcms.com/

Expected response:

HTTP/2 200
server: nginx
content-type: text/html; charset=utf-8

You can also inspect logs for startup confirmation:

journalctl -u smallblock -e --no-pager
tail -f /var/log/nginx/access.log

Step 8 — Secure the Environment

Action

Description

Firewall

Allow only ports 80/443.

SELinux

Label socket directory with httpd_var_run_t.

Permissions

/srv/smallblock owned by smallblock:smallblock.

Backups

Schedule nightly DB and media backups.

Updates

Apply regular security updates (dnf update / apt upgrade).

Verification Checklist

  • [x] smallblock systemd service is running

  • [x] nginx -t returns OK

  • [x] HTTPS responds with valid certificate

  • [x] Static and media files load properly

  • [x] Logs show no errors

Next Steps

Your production instance is live! Next, review: