Migrate a Django App to a New Server with Nginx, PostgreSQL, Celery & RabbitMQ

In this blog post, I’m documenting my step-by-step journey of migrating a production-ready Django application (with Celery and Gunicorn) and setting up a WordPress instance on the same server using Nginx as the web server, PostgreSQL for Django, and MariaDB for WordPress. This guide is ideal for developers looking to consolidate services efficiently on a single Ubuntu-based VPS.

Step 1: Provision the New Server

I created a new Ubuntu server on UpCloud with a public IP and root SSH access. This server would eventually host:

  • A Django + Gunicorn + Celery app
  • PostgreSQL (for Django)
  • Nginx (as reverse proxy)
  • MariaDB (for WordPress)
  • RabbitMQ as a message broker
  • A future WordPress website

Step 2: Migrate Django App with Systemd

My Django project is structured with:

  • A virtual environment
  • Gunicorn systemd service
  • Celery systemd service

I transferred it using rsync from the old server:

rsync -avz /home/myproject/ user@new-server:/home/myproject/

I copied over the Gunicorn and Celery systemd unit files:

rsync -avz /etc/systemd/system/myproject.service /etc/systemd/system/myprojectcelery.service user@new-server:/etc/systemd/system/

On the new server, I ensured:

  • All ownerships and permissions were set
  • Python dependencies were installed via requirements.txt
  • The virtual environment was re-created

Then I enabled and started both services:

sudo systemctl daemon-reload
sudo systemctl enable myproject myprojectcelery
sudo systemctl start myproject myprojectcelery

Step 3: Nginx Setup for Django

I configured Nginx to reverse proxy to the Gunicorn socket:

server {
    listen 80;
    server_name app.example.com;

    location /static/ {
        alias /home/myproject/static/;
    }

    location /media/ {
        alias /home/myproject/media/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/myproject/myproject.sock;
    }
}

Enabled the site:

ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
systemctl reload nginx

Step 4: PostgreSQL Migration for Django

Dumped the DB from old server:

pg_dump -U postgres myprojectdb > /root/myproject.sql

Transferred and restored on new server:

scp /root/myproject.sql user@new-server:/root/
psql -U postgres -c "CREATE DATABASE myprojectdb;"
psql -U postgres myprojectdb < /root/myproject.sql

Granted permissions to the myproject DB user:

GRANT ALL PRIVILEGES ON DATABASE myprojectdb TO myproject;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myproject;

Step 5: Set Up RabbitMQ

RabbitMQ was installed to support Celery as the task queue. Installation on Ubuntu:

sudo apt install rabbitmq-server -y

The broker was configured using environment variables in the Django project, pointing to:

amqp://myuser:mypassword@localhost:5672/myvhost

Access control and users were set up via:

rabbitmqctl add_user myuser mypassword
rabbitmqctl set_user_tags myuser administrator
rabbitmqctl set_permissions -p / myuser ".*" ".*" ".*"

Step 6: Set Up SSL with Let’s Encrypt

apt install certbot python3-certbot-nginx -y
certbot --nginx -d app.example.com

Automatically issued and configured HTTPS with redirection.


Step 7: Add a WordPress Site (MariaDB + Nginx)

Install MariaDB:

apt install mariadb-server mariadb-client -y
mysql_secure_installation

Create DB for WordPress:

CREATE DATABASE wp_db;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON wp_db.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;

Install WordPress:

wget https://wordpress.org/latest.tar.gz
mkdir -p /var/www/wordpress
cd /var/www && tar -xzf latest.tar.gz
chown -R www-data:www-data /var/www/wordpress

Configure Nginx for WordPress:

server {
    listen 80;
    server_name blog.example.com;
    root /var/www/wordpress;

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Enable and reload:

ln -s /etc/nginx/sites-available/blog.example.com /etc/nginx/sites-enabled/
systemctl reload nginx

Add SSL:

certbot --nginx -d blog.example.com

Conclusion

Now, my single Ubuntu VPS is successfully running:

  • A fully migrated Django app with Gunicorn, Celery, and PostgreSQL
  • RabbitMQ as the message broker
  • A new WordPress blog with Nginx + MariaDB
  • HTTPS for both domains

This setup gives me complete control, performance, and flexibility on a single cost-effective server.

If you’re looking to consolidate your apps or move to a cleaner architecture, this approach works great.

Let me know if you want my full deployment script or CircleCI integration setup next!

Full-stack developer, tech enthusiast, and server-side tinkerer. I share short dev notes, server setups, code snippets, and practical guides for beginners and fellow developers. Follow my journey and learn something new with every post. 🔗 GitHub: @meetsohail

Leave a Comment

Your email address will not be published. Required fields are marked *