# Task Manager - Docker Web Application A simple task manager web application deployed as a multi-container Docker system. Users can create, complete, and delete tasks through a web interface. ## Prerequisites - **Linux** with Docker installed (Docker Engine 20.10+) - **Docker Compose** v2 (optional, for `docker compose` deployment) - Ports **80** must be available on the host machine ## Application Description The Task Manager is a web-based CRUD application for managing personal tasks. It consists of three services working together: - A **frontend** web interface served by Nginx where users interact with the application - A **backend** REST API built with Flask (Python) that handles business logic - A **PostgreSQL database** that stores task data persistently Users can: - Add new tasks - Mark tasks as completed (toggle checkbox) - Delete tasks - View all tasks in a list sorted by creation date ## Architecture ``` Browser (port 80) | v +--------+ +-------+ +------------+ | Nginx | ----> | Flask | ----> | PostgreSQL | | :80 | API | :5000 | SQL | :5432 | +--------+ proxy +-------+ +------------+ static REST API persistent files (gunicorn) volume ``` ## Virtual Networks | Network Name | Driver | Purpose | |-------------------|--------|------------------------------------------------------| | taskapp-network | bridge | Connects all 3 containers so they can communicate | All containers are attached to `taskapp-network`. Only Nginx exposes a port (80) to the host. Flask and PostgreSQL are accessible only within the Docker network. ## Named Volumes | Volume Name | Mount Point | Purpose | |----------------|------------------------------------|----------------------------------| | taskapp-pgdata | /var/lib/postgresql/data (in db) | Persists database data across container restarts and stops | Stopping and restarting the application preserves all task data thanks to this volume. ## Containers ### 1. taskapp-nginx (Frontend) - **Image:** Custom, built from `nginx:alpine` - **Port:** 80 (host) -> 80 (container) - **Role:** Serves static HTML/CSS/JS files and reverse-proxies `/api/*` requests to the Flask backend - **Restart policy:** `unless-stopped` - **Configuration:** Custom `nginx.conf` with `proxy_pass` directive for API routing and `large_client_header_buffers 4 32k` for handling large cookies ### 2. taskapp-flask (Backend) - **Image:** Custom, built from `python:3.12-slim` - **Port:** 5000 (internal only, not exposed to host) - **Role:** REST API server handling task CRUD operations - **Restart policy:** `unless-stopped` - **Configuration:** Environment variables for database connection (`DB_HOST`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`) - **WSGI server:** Gunicorn with 2 workers - **Auto-initialization:** Creates the `tasks` table on startup if it does not exist ### 3. taskapp-db (Database) - **Image:** `postgres:15` (from Docker Hub) - **Port:** 5432 (internal only, not exposed to host) - **Role:** Stores task data (id, title, completed status, creation timestamp) - **Restart policy:** `unless-stopped` - **Configuration:** Environment variables (`POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`) - **Volume:** `taskapp-pgdata` mounted at `/var/lib/postgresql/data` ## Container Configuration Details - **Nginx** is configured via `frontend/nginx.conf` which sets up static file serving and reverse proxy rules - **Flask** reads database credentials from environment variables passed at container runtime - **PostgreSQL** is configured via standard Postgres environment variables; data is stored on a named volume ## Usage Instructions ### Prepare the Application Build images and create Docker resources: ```bash ./prepare-app.sh ``` ### Start the Application Run all containers: ```bash ./start-app.sh ``` Output: ``` Starting app... App is running! The app is available at http://localhost:80 ``` ### View in Web Browser Open your web browser and navigate to: ``` http://localhost:80 ``` You will see the Task Manager interface where you can add, complete, and delete tasks. ### Stop the Application Stop all containers (data is preserved): ```bash ./stop-app.sh ``` ### Remove the Application Remove all containers, images, networks, and volumes: ```bash ./remove-app.sh ``` ### Alternative: Docker Compose You can also use Docker Compose instead of the shell scripts: ```bash # Start docker compose up -d --build # Stop (preserves data) docker compose down # Remove everything including volumes docker compose down -v --rmi all ``` ## API Endpoints | Method | Endpoint | Description | |--------|-------------------|------------------------| | GET | /api/tasks | List all tasks | | POST | /api/tasks | Create a new task | | PUT | /api/tasks/:id | Toggle task completion | | DELETE | /api/tasks/:id | Delete a task | ## Project Structure ``` . ├── backend/ │ ├── Dockerfile # Python/Flask image definition │ ├── requirements.txt # Python dependencies │ └── app.py # Flask REST API application ├── frontend/ │ ├── Dockerfile # Nginx image definition │ ├── nginx.conf # Nginx configuration (static files + reverse proxy) │ ├── index.html # Main HTML page │ ├── style.css # Styles │ └── app.js # Frontend JavaScript (fetch API calls) ├── docker-compose.yaml # Docker Compose configuration ├── prepare-app.sh # Script to build images and create resources ├── start-app.sh # Script to start all containers ├── stop-app.sh # Script to stop all containers ├── remove-app.sh # Script to remove all traces of the app └── README.md # This file ``` ## Example of Working with the Application ```bash # Prepare everything needed for the application ./prepare-app.sh # Output: # Preparing app... # Building backend image... # Building frontend image... # Creating network... # Creating volume... # App prepared successfully. # Start the application ./start-app.sh # Output: # Starting app... # Starting database... # Starting backend... # Starting frontend... # # App is running! # The app is available at http://localhost:80 # Open web browser and work with the application at http://localhost:80 # - Add tasks using the input field # - Mark tasks as completed by clicking the checkbox # - Delete tasks by clicking the X button # Stop the application (data is preserved) ./stop-app.sh # Output: # Stopping app... # App stopped. # Start again - all tasks are still there ./start-app.sh # Remove everything related to the application ./remove-app.sh # Output: # Removing app... # App removed. ``` ## Sources - [Docker Documentation](https://docs.docker.com/) - [Nginx Docker Image](https://hub.docker.com/_/nginx) - [PostgreSQL Docker Image](https://hub.docker.com/_/postgres) - [Python Docker Image](https://hub.docker.com/_/python) - [Flask Documentation](https://flask.palletsprojects.com/) - [Gunicorn Documentation](https://gunicorn.org/) - [Nginx Reverse Proxy Guide](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) ## Use of Artificial Intelligence This application was designed and implemented with the assistance of **Claude** (Anthropic), an AI assistant. Claude was used for: - Designing the application architecture and service composition - Writing application source code (Python/Flask backend, HTML/CSS/JS frontend) - Writing Dockerfiles and Docker Compose configuration - Writing shell scripts for application lifecycle management - Writing this documentation **AI agent used:** Claude Opus 4.6 (Anthropic) via Claude Code CLI