Skip to main content

Deployment Guide

This guide covers the deployment process for the Rhea Agripad backend on a production server.

Deployment Overview

The Rhea Agripad backend is deployed using Docker containers on DigitalOcean. The deployment process is automated using GitHub Actions.

GitHub Actions Deployment Pipeline

When code is pushed to the main branch, a GitHub Actions workflow builds a Docker image, tags it with a hash value, and pushes it to the DigitalOcean container registry.

GitHub Action Secrets

The following secrets are used in the GitHub Actions workflow:

  • CREATE_CONTAINER_IMAGE: Set to 'true' to enable image creation, 'false' to disable
  • DIGITALOCEAN_TOKEN: Access token for DigitalOcean
  • SSH_PRIVATE_KEY: Private key for connecting to the droplet
  • ENV: Environment to deploy the infrastructure
  • AGE_PRIVATE_KEY: Key used to decrypt the Terraform state file

Disabling Container Image Creation

To disable container image creation when pushing to the main branch, set the CREATE_CONTAINER_IMAGE secret to 'false'.

Docker Image creation

To create the image, you need to push to the Agripad Backend repository (https://github.com/Rhea-Africa/agripad-multitenant-backend). If you have enabled image creation, the image will be built and pushed to the DigitalOcean container registry.

tip

Before creating new images, its good to delete the old images after backing up them locally to avoid high space usage.

Updating the image tag

  1. Go to Digital ocean
  2. Go to Container Registry
  3. Identify you images for either backend or frontend
  4. Copy the result image tag and update the docker-compose.yml file in this repository https://github.com/Rhea-Africa/agripad-backend-cloud

Actual Deployment

To deploy the application, you need to push to the agripad-backend-cloud repository (https://github.com/Rhea-Africa/agripad-backend-cloud) main branch

Docker Compose Deployment

The application is deployed using Docker Compose on the DigitalOcean droplet.

Updating the Application

To update the application to a new version:

  1. Update the image tag in the docker-compose.yml file with the new hash value
  2. Push the changes to the main branch

Example docker-compose.yml update:

# Current version
app1:
image: prod-rhea-container-registry/app1:f2ef4211cf5e3b068484f7dfb5d770fa6ee8f04b
env_file:
- .env.app1
ports:
- "8000:80"
networks:
- container-network
# Updated version
app1:
image: prod-rhea-container-registry/app1:8484f7dfb5d770fa6ee8f04bf2ef4211cf5e3b06
env_file:
- .env.app1
ports:
- "8000:80"
networks:
- container-network

Important: Always check if services are running after deployment!

Managing Services on the Droplet

Checking Service Status

To check if services are running:

docker ps -a

Starting Services

To start all services:

docker-compose up

To start a specific service:

docker-compose up <service_name>

Stopping Services

To stop all services:

docker-compose down

To stop a specific service:

docker-compose down <service_name>

Troubleshooting Failed Services

If a service fails to start:

  1. Check if the service is running:

    docker ps -a
  2. Try to start the service manually to see error messages:

    docker-compose up <service-name>
  3. Check container logs:

    docker logs <container-name>

EMQX Configuration

Creating Swap Memory for EMQX

EMQX may require additional memory. Create a swap file:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

To make the swap permanent:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Restart EMQX after configuring swap:

sudo systemctl restart emqx

Creating Tenants in Production

To create tenants in the production environment:

# Create Main Tenant
docker exec -it <container_id> sh -c "python manage.py create_tenant --domain-domain=main.api.rhea-agripad.xyz --schema=main --name=Main"

# Create Rhea Tenant
docker exec -it <container_id> sh -c "python manage.py create_tenant --domain-domain=rhea.api.rhea-agripad.xyz --schema=rhea --name=Rhea"

# Create Kilimo Tenant
docker exec -it <container_id> sh -c "python manage.py create_tenant --domain-domain=kilimo.api.rhea-agripad.xyz --schema=kilimo --name=Kilimo --no-input"

Replace <container_id> with the actual container ID of your Django application.