A full-stack task management web application built with Django, containerized with Docker, and deployed on Google Cloud Platform with HTTPS and a complete CI/CD pipeline.
Live at: https://taskmanager-00015775.duckdns.org
- Username: admin
- Password: admin
Docker Image: https://hub.docker.com/repository/docker/00015775/taskmanager/ (under 200MB)
Video Demonstration: https://youtu.be/77sIR99Q45M
- User authentication (register, login, logout, profile management)
- Create, read, update, and delete tasks (full CRUD)
- Filter tasks by status, priority, and tag
- Tag management with custom colors
- Dashboard with real-time task statistics
- Admin panel for data management
- PostgreSQL database with many-to-one and many-to-many relationships
- Dockerized multi-service architecture (Django + PostgreSQL + Nginx)
- Automated CI/CD pipeline via GitHub Actions
- HTTPS enforced via Let's Encrypt (Certbot)
| Layer | Technology |
|---|---|
| Backend | Django 4.2, Python 3.11, Gunicorn |
| Database | PostgreSQL 15 |
| Frontend | Bootstrap 5, Font Awesome |
| Containerization | Docker, Docker Compose |
| Web Server | Nginx (reverse proxy + static files) |
| CI/CD | GitHub Actions |
| Cloud | Google Cloud Platform (GCP) — Ubuntu 24.04 LTS |
| SSL | Let's Encrypt (Certbot) |
| DNS | DuckDNS (free subdomain) |
- Python 3.11+
- Docker Desktop
- Git
- Clone the repository:
git clone https://github.com/00015775/taskmanager.git
cd taskmanager- Create your
.envfile from the example:
cp .env.example .env-
Edit
.envwith your values (see Environment Variables section below) -
Build and start all containers:
docker compose up --build-
Visit
http://localhostin your browser -
Create a superuser for admin access:
docker compose exec web python manage.py createsuperuser- Clone and enter the project:
git clone https://github.com/00015775/taskmanager.git
cd taskmanager- Create and activate virtual environment:
python3 -m venv venv
source venv/bin/activate- Install dependencies:
pip install -r requirements.txt- Run migrations:
python manage.py migrate- Start the development server:
python manage.py runserver- Visit
http://127.0.0.1:8000
Copy .env.example to .env and fill in the values:
| Variable | Description | Example |
|---|---|---|
SECRET_KEY |
Django secret key — keep this secret | your-50-char-random-key |
ALLOWED_HOSTS |
Comma-separated list of allowed hosts | localhost,127.0.0.1,yourdomain.duckdns.org |
POSTGRES_DB |
PostgreSQL database name | taskmanager |
POSTGRES_USER |
PostgreSQL username | taskmanager_user |
POSTGRES_PASSWORD |
PostgreSQL password | strongpassword |
POSTGRES_HOST |
PostgreSQL host (use db inside Docker) |
db |
POSTGRES_PORT |
PostgreSQL port | 5432 |
SECURE_SSL_REDIRECT |
Enable HTTPS redirect — True in production | False |
- Ubuntu 24.04 LTS (GCP VM)
- Docker + Docker Compose installed
- Ports 22, 80, 443 open in UFW and GCP firewall rules
- Domain pointed to server IP (DuckDNS or any DNS provider)
- SSH into your server:
ssh -i ~/.ssh/your_key username@your-server-ip- Install Docker:
sudo apt update && sudo apt install -y ca-certificates curl gnupg
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER- Clone the repository:
git clone https://github.com/00015775/taskmanager.git
cd taskmanager- Create production
.env:
cp .env.example .env
nano .env- Start containers:
docker compose up -d- Install SSL certificate via Certbot:
sudo apt install -y certbot
sudo systemctl stop nginx # stop system nginx if running
sudo certbot certonly --standalone -d yourdomain.duckdns.org \
--non-interactive --agree-tos --email your@email.com- Set
SECURE_SSL_REDIRECT=Truein.envand restart:
docker compose restart webEvery push to main automatically deploys to production. Required GitHub Secrets:
| Secret | Description |
|---|---|
DOCKERHUB_USERNAME |
Docker Hub username |
DOCKERHUB_TOKEN |
Docker Hub access token |
SSH_HOST |
GCP server IP address |
SSH_USERNAME |
Server SSH username |
SSH_PRIVATE_KEY |
Private SSH key for server access |
ALLOWED_HOSTS |
Production allowed hosts value |
taskmanager/
├── .github/
│ └── workflows/
│ └── deploy.yml # CI/CD pipeline
├── accounts/ # Authentication app (register, login, logout, profile)
├── tasks/ # Task management app (CRUD, tags, filtering)
├── core/ # Dashboard and shared views
├── taskmanager/ # Django project settings
│ └── settings/
│ ├── base.py # Shared settings
│ ├── development.py # Local development (SQLite)
│ └── production.py # Production (PostgreSQL, security headers)
├── templates/ # HTML templates
├── static/ # CSS, JS assets
├── nginx/
│ └── nginx.conf # Nginx reverse proxy + SSL config
├── docker/
│ └── entrypoint.sh # Container startup script
├── conftest.py # Pytest configuration
├── Dockerfile # Multi-stage build
├── docker-compose.yml # Production services
├── docker-compose.dev.yml # Development services
├── .env.example # Environment variable template
└── README.md
| Model | App | Relationships |
|---|---|---|
UserProfile |
accounts | OneToOne → User |
Task |
tasks | ManyToOne → User (owner) |
Tag |
tasks | ManyToMany ↔ Task |
# Run all tests locally
pytest --tb=short -v
# Run with coverage report
coverage run -m pytest
coverage report
# Run inside Docker
docker compose exec web pytest9 tests covering user registration and login, profile access control, task creation, listing, editing and deletion, task model creation, and tag creation functionality.
Every push to main branch automatically:
- Runs
flake8code quality checks - Runs 9 pytest tests
- Generates coverage report (minimum 60%)
- Builds Docker image (multi-stage, non-root user)
- Tags image with
latestand commit SHA - Pushes image to Docker Hub
- Deploys to GCP server via SSH
- Runs database migrations
- Collects static files
- Restarts services with zero downtime
# Without Docker
pytest
# With Docker
docker compose exec web pytestEvery push to main branch automatically:
- Runs code quality checks (flake8)
- Runs all tests (pytest)
- Builds Docker image
- Pushes image to Docker Hub
- Deploys to production server via SSH
- Runs migrations and restarts services
In case of errors at first stage of testing Run Tests & Linting, the most common reason are design related issues such as whitespace errors or blanks. To solve this, do as follows:
python3.11 -m venv venvsource venv/bin/activatepip install -r requirements.txt
First check locally if it is actuall whitespace or blank issues, to do this run:
flake8 . --max-line-length=120 \
--exclude=venv,migrations,staticfiles,__pycache__ \
--count --statistics
If you see whitespace/blank errors, then run:
# Auto-fix all whitespace issues across the whole project
autopep8 --in-place --recursive \
--select=W291,W292,W293,W391 \
--exclude=venv,migrations,staticfiles \
.





