Conduit Deployment (Docker & CI/CD)
Table of Contents
- Introduction
- Project Structure
- Quickstart
- Environment Variables
- CI/CD Deployment
- Usage
- Logging
- Checklist
Introduction
This repository contains the deployment and CI/CD setup for the
Conduit full-stack application (Angular frontend + Django REST backend).
The main focus of this project is:
- containerization using Docker
- orchestration with Docker Compose
- automated build & deployment via GitHub Actions
- secure handling of configuration and secrets
The frontend and backend are integrated as Git submodules and are built automatically during the CI pipeline.
Project Structure
conduit-deployment/
├── docker-compose.yaml
├── .gitmodules
├── backend/ # Django backend (git submodule)
├── frontend/ # Angular frontend (git submodule)
├── .github/
│ └── workflows/
│ └── deployment.yaml # GitHub Actions CI/CD pipeline
├── .env.template
└── README.md
Quickstart
1. Clone the repository (including submodules)
git clone --recurse-submodules https://github.com/BenjaminTietz/conduit-deployment.git
cd conduit-deployment
If submodules were not cloned:
git submodule update --init --recursive
The submodule configuration does not rely on the default branches of the included repositories
2. Create your environment file
All backend and frontend configuration values are defined in a single .env
file located in the project root.
cp .env.template .env
Modify if needed.
3. Start the application locally
docker compose up
docker compose (with a space) is Compose V2, the Docker CLI plugin. The older docker-compose command is Compose V1, which Docker stopped supporting after June 2023. On Debian/Ubuntu the plugin comes from the docker-compose-v2 package, or from docker-compose-plugin in Docker's official repository.
Backend → http://localhost:8000
Frontend → http://localhost:8282
Environment Variables
The container uses .env to configure Django and PostgreSQL:
# =====================
# Frontend (Angular)
# =====================
BACKEND_API_URL=http://backend:8000/api
# =====================
# Backend (Django)
# =====================
DJANGO_SECRET_KEY=changeme
DJANGO_DEBUG=True
DJANGO_ALLOWED_HOSTS=*
CORS_ALLOWED_ORIGINS=http://localhost:8282,http://127.0.0.1:8282
POSTGRES_NAME=conduit
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=db
POSTGRES_PORT=5432
CI/CD Deployment
The deployment pipeline is implemented using GitHub Actions.
Workflow responsibilities:
- Build frontend and backend Docker images
- Inject frontend configuration at build time
- Push images to GitHub Container Registry (GHCR)
- Deploy containers to a remote VM via SSH
- Start services using Docker Compose in detached mode
No build steps are executed on the target VM.
This pipeline puts the application on a VM, but it does not set up transport encryption — the NGINX container serves the frontend over plain HTTP and the Django admin login and its session cookie would travel the network unprotected. The missing piece on the VM is a reverse proxy (nginx, Caddy, Traefik) that terminates TLS with a certificate from a public CA (Let's Encrypt) and forwards to the containers, while the container ports themselves are published on the loopback interface only (127.0.0.1: prefix on the host side of the ports: mapping) so nothing but the proxy can reach them. Django additionally needs SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https"), SECURE_SSL_REDIRECT, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE and the public HTTPS origin in CSRF_TRUSTED_ORIGINS.
Usage
Backend (Django)
Run inside the backend container:
docker exec -it conduit_backend bash
python manage.py createsuperuser
Frontend (Angular)
The production build is embedded in an NGINX container and served at:
http://localhost:8282
Logging
All services log to stdout/stderr and are managed by Docker's json-file logging driver. Log rotation is enabled to prevent excessive disk usage.
Logs can be accessed via:
docker logs conduit_backend
docker logs conduit_frontend
Logs can optionally be persisted by redirecting Docker logs to a file.
docker logs conduit_backend > conduit_backend-logs.txt
docker logs conduit_frontend > conduit_frontend-logs.txt