Mr. Editor-in-chief Mr. Editor-in-chief February 17, 2024 Updated April 24, 2026

Deploy Django with MySQL on Amazon Linux 2023

Install MySQL database

  • sudo wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
  • sudo dnf install mysql80-community-release-el9-1.noarch.rpm -y
  • sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
  • sudo dnf install mysql-community-client -y # Maybe not needed
  • sudo dnf install mysql-community-server -y
  • sudo cat /var/log/mysqld.log | grep password # Generate && Get temporary password
  • ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Copy the code into the server and make it run

  • rsync -avz --exclude 'venv' . ec2-user@35.77.88.60:~/mdblog
  • sudo yum install gcc mysql-devel python3-devel # Some initial set up to install mysqlclient
  • Amazon Linux 3 is preinstalled with python, pip, and venv. Now you can create and activate a virtual environment && pip install -r requirement.txt

Gnunicorn set up

  • Install Gunicorn in the virtual environment
pip install gunicorn
  • Create a gunicorn configuration in your django project folder(e.g. ~/mdblog/gunicorn.conf.py)
bind = "localhost:8000"
workers = 4
keepalive = 5

wsgi_app = "blog.wsgi" # Replace 'blog' with your main app (the name of the directory that contains wsgi.py)
  • Create a systemd unit sudo nano /etc/systemd/system/gunicorn.service
[Install]
WantedBy=multi-user.target

[Unit]
Description=Gunicorn service
After=network.target

[Service]
WorkingDirectory=/home/ec2-user/mdblog   # /path/to/django_project/  
ExecStart=/home/ec2-user/mdblog/venv/bin/gunicorn # /path/to/django_project_venv/bin/gunicorn
  • Test Gunicorn
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn

Install Caddy && Config CaddyFile

  • Caddy Installation
# Download caddy binary file from https://caddyserver.com/download
sudo mv caddy_linux_amd64 caddy  # Rename
sudo mv caddy /usr/bin/ # Move
sudo chmod 755 /usr/bin/caddy
caddy --version
sudo groupadd --system caddy
sudo useradd --system \
    --gid caddy \
    --create-home \
    --home-dir /var/lib/caddy \
    --shell /usr/sbin/nologin \
    --comment "Caddy web server" \
    caddy
sudo nano /etc/systemd/system/caddy.service
# caddy.service
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
  • Caddy Configuration sudo mkdir -p /etc/caddy && sudo nano /etc/caddy/Caddyfile
mdblog.peng.works {

  handle_path /static/* {
        root * /home/ec2-user/mdblog/static/
        file_server
  }

  handle_path /media/* {
        root * /home/ec2-user/mdblog/media/
        file_server
  }

  reverse_proxy localhost:8000
}
  • Enable and start && restart Caddy
sudo systemctl daemon-reload
sudo systemctl enable --now caddy # --now == enable && start

sudo systemctl restart caddy
sudo systemctl status caddy
  • Note: Make sure the port 443 is open and 'mdblog.peng.works' is in the ALLOWED_HOSTS in Django settings.py if there is a problem opening the site. Also don't forget to set debug to False and close port 8000.

Dubugging Log Generating Errors

  • Problem: Caddy doesn't generate log file after the log directive configured
  • Caddy Configuration sudo nano /etc/caddy/Caddyfile
www.whatever.asia {
    log {
        output file /var/log/caddy/access.log
    }
    handle_path /media/* {
        root * "/home/ec2-user/mdblog/media/"
        file_server
    }
    reverse_proxy localhost:8000
}

whatever.asia {
    log {
        output file /var/log/caddy/access.log
    }
    handle_path /media/* {
        root * "/home/ec2-user/mdblog/media/"
        file_server
    }
    reverse_proxy localhost:8000
}

api.whatever.asia {
    reverse_proxy localhost:5000
}
journalctl -u caddy.service | tail
write error: error getting log file info: stat /var/log/caddy/access.log: permission denied
  • Solution
cd /var/log/
mkdir caddy
sudo chown -R caddy:caddy caddy
sudo systemctl restart caddy.service