Skip to main content
Deploy FootyCollect directly on an Ubuntu or Debian VPS using Nginx as a reverse proxy, Gunicorn as the application server, and systemd for service management.

Overview

Bare metal deployment installs FootyCollect directly on your server without containerization:
  • Nginx: Reverse proxy and SSL termination
  • Gunicorn: WSGI application server
  • Systemd: Service management and process supervision
  • PostgreSQL: Database server
  • Redis: Cache and Celery broker
  • Supervisor: Celery worker management (optional)
This guide is based on the deployment scripts in deploy/ including setup.sh, deploy.sh, nginx.conf, and gunicorn.service.

Prerequisites

  • Ubuntu 20.04+ or Debian 11+ server
  • Root or sudo access
  • Domain name with DNS pointing to your server
  • Minimum 2GB RAM, 20GB disk space

Initial Server Setup

Automated Setup Script

The repository includes an automated setup script (deploy/setup.sh:1) that configures your server:
1

Copy Setup Script

2

SSH into Server

3

Run Setup Script

This script will:
  • Update system packages
  • Install Python 3.12, PostgreSQL, Redis, Nginx
  • Install certbot for SSL certificates
  • Create footycollect user
  • Configure PostgreSQL database
  • Setup firewall (UFW)
  • Configure fail2ban
  • Setup log rotation
4

Set Database Password

The setup script creates a PostgreSQL user with a default password. Change it immediately:

Manual Setup (Alternative)

If you prefer manual setup or need to customize the installation:

Application Deployment

1. Clone Repository

Switch to the application user and clone the repository:

2. Setup Virtual Environment

The virtual environment must be created with Python 3.12 as specified in setup.sh:25.

3. Configure Environment Variables

Copy the environment template and configure production settings:
Required variables (from deploy/env.example:1):
.env
Generate a secure SECRET_KEY:
See the environment setup guide for all available variables.

4. Setup Database

Run migrations and create a superuser:

5. Configure Nginx

Copy and configure the Nginx reverse proxy (deploy/nginx.conf:1):
Update the domain in nginx.conf:
Enable the site:
The Nginx configuration includes:
  • HTTP to HTTPS redirect (nginx.conf:6)
  • Security headers (nginx.conf:40)
  • Gunicorn proxy on 127.0.0.1:8000 (nginx.conf:62)
  • Static/media file serving (nginx.conf:77)
  • Health check endpoints (nginx.conf:93)

6. Setup SSL Certificates

Obtain free SSL certificates from Let’s Encrypt:
Certbot will:
  • Obtain SSL certificates
  • Update Nginx configuration automatically
  • Setup auto-renewal via systemd timer
Certificates auto-renew via certbot.timer. Verify: sudo systemctl status certbot.timer

7. Configure Gunicorn Service

Setup systemd service for Gunicorn (deploy/gunicorn.service:1):
The service file configures:
Gunicorn configuration (gunicorn.service:11):
  • Workers: 3 (adjust based on CPU cores: (2 * cores) + 1)
  • Bind: 127.0.0.1:8000 (Nginx proxies to this)
  • Timeout: 120 seconds
  • Max requests: 1000 (workers restart after to prevent memory leaks)
Enable and start the service:

8. Verify Deployment

Check that everything is running:

Deployment Updates

Use the automated deployment script (deploy/deploy.sh:1) for updates:
The deployment script (deploy/deploy.sh:45) performs:
1

Backup Database

Creates timestamped database backup (deploy.sh:52)
2

Update Dependencies

Installs updated Python packages (deploy.sh:66)
3

Pull Latest Code

Updates from git repository (deploy.sh:76)
4

Run Migrations

Applies database migrations (deploy.sh:83)
5

Collect Static Files

Uploads static files to S3/R2 (deploy.sh:87)
6

Django Checks

Runs deployment validation (deploy.sh:91)
7

Restart Gunicorn

Restarts application server (deploy.sh:98)
8

Reload Nginx

Reloads reverse proxy (deploy.sh:107)
9

Health Check

Verifies application is running (deploy.sh:132)
Database backups are stored in /var/www/footycollect/backups/ and automatically rotated (keeps last 7 backups).

Service Management

Gunicorn Service

Nginx Service

PostgreSQL

Redis

Celery Workers (Background Tasks)

Setup Celery for background tasks (image downloads, scheduled tasks):

Using Supervisor

Create supervisor configuration:
Create log directory and start:

Database Backups

Manual Backup

Automated Backups (Cron)

Setup daily backups via cron:

Restore Backup

Always create a fresh backup before restoring from an old backup.

Static and Media Files

Production serves static/media from S3 or R2 (configured in .env).

Collect Static Files

For testing only, serve files locally via Nginx (already configured in nginx.conf:77):
Collect to local directory:
Use S3/R2 for production. Local storage doesn’t scale and complicates multi-server deployments.

Monitoring and Logs

Application Logs

Log Rotation

Log rotation is configured by setup.sh:93:
/etc/logrotate.d/footycollect

Troubleshooting

Gunicorn Won’t Start

Nginx 502 Bad Gateway

Database Connection Errors

Static Files Not Loading

SSL Certificate Issues

Security Hardening

Firewall Rules

SSH Security

Fail2ban Configuration

Automatic Security Updates

Next Steps

Environment Setup

Detailed guide to all production environment variables

Production Checklist

Complete the pre-deployment security checklist