253 lines
7.8 KiB
Markdown
253 lines
7.8 KiB
Markdown
# 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
|