# Task Manager — Dockerized Web Application A modern task management web application deployed using Docker containers. The application consists of **5 services** running in isolated containers, communicating over virtual networks, with persistent storage for data durability. ## Table of Contents - [Description](#description) - [Prerequisites](#prerequisites) - [Architecture](#architecture) - [Services](#services) - [Networks](#networks) - [Volumes](#volumes) - [Container Configuration](#container-configuration) - [Quick Start](#quick-start) - [Usage Instructions](#usage-instructions) - [Viewing the Application](#viewing-the-application) - [Example Workflow](#example-workflow) - [Sources](#sources) - [AI Usage Declaration](#ai-usage-declaration) --- ## Description **Task Manager** is a full-stack web application for creating, managing, and tracking tasks. Users can: - **Create tasks** with a title and optional description - **Mark tasks** as completed or reopen them - **Delete tasks** they no longer need - **Filter tasks** by status (All / Active / Completed) - **View statistics** including total, active, and completed task counts - **Manage the database** via Adminer web interface The application uses a modern dark-themed UI served by Nginx, a Node.js/Express REST API backend, PostgreSQL for persistent data storage, and Redis for response caching. --- ## Prerequisites To deploy and run this application, you need: | Software | Minimum Version | Purpose | |----------|----------------|---------| | **Linux** | Any modern distribution | Host operating system | | **Docker** | 20.10+ | Container runtime | | **Docker Compose** | v2.0+ (plugin) | Multi-container orchestration | | **bash** | 4.0+ | Running management scripts | ### Verify installation: ```bash docker --version # Docker version 20.10+ docker compose version # Docker Compose version v2.0+ bash --version # GNU bash, version 4.0+ ``` --- ## Architecture ``` ┌─────────────────────────────────────────────────────────┐ │ Docker Host │ │ │ │ ┌──────────────── frontend-net ──────────────────┐ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ Nginx │ │ Adminer │ │ │ │ │ │ (frontend) │ │ (DB UI) │ │ │ │ │ │ :5000→:80 │ │ :5001→:5000│ │ │ │ │ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ │ │ └─────────┼────────────────────────┼──────────────┘ │ │ │ │ │ │ ┌─────────┼────────────────────────┼──────────────┐ │ │ │ │ backend-net │ │ │ │ │ ┌──────▼──────┐ │ │ │ │ │ │ Node.js │ │ │ │ │ │ │ (api) │ │ │ │ │ │ │ :3000 │ │ │ │ │ │ └──┬──────┬───┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌──▼────┐ ┌▼─────────┐ ┌──────▼──────┐ │ │ │ │ │ Redis │ │PostgreSQL │ │ (Adminer │ │ │ │ │ │ :6379 │ │ :5432 │ │ connects) │ │ │ │ │ └───────┘ └───────────┘ └─────────────┘ │ │ │ │ 📦 📦 │ │ │ │ redisdata pgdata │ │ │ └─────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────┘ ``` --- ## Services ### 1. Frontend (Nginx) - **Container name:** `taskapp-frontend` - **Image:** Custom (built from `frontend/Dockerfile` using `nginx:alpine`) - **Port:** `5000` (public) → `80` (container) - **Role:** Serves the static HTML/CSS/JS frontend and acts as a reverse proxy, forwarding `/api/` requests to the Node.js backend - **Networks:** `frontend-net`, `backend-net` ### 2. API (Node.js / Express) - **Container name:** `taskapp-api` - **Image:** Custom (built from `api/Dockerfile` using `node:20-alpine`) - **Port:** `3000` (virtual, not exposed to host) - **Role:** REST API server providing CRUD operations for tasks. Connects to PostgreSQL for data persistence and Redis for response caching - **Networks:** `backend-net` ### 3. PostgreSQL Database - **Container name:** `taskapp-postgres` - **Image:** `postgres:16-alpine` - **Port:** `5432` (virtual, not exposed to host) - **Role:** Primary relational database storing all task data - **Volume:** `taskapp-pgdata` mounted at `/var/lib/postgresql/data` - **Networks:** `backend-net` - **Initialization:** `db/init.sql` is automatically executed on first run to create the `tasks` table ### 4. Redis Cache - **Container name:** `taskapp-redis` - **Image:** `redis:7-alpine` - **Port:** `6379` (virtual, not exposed to host) - **Role:** In-memory cache for API responses. Reduces database load by caching task list queries for 30 seconds. Configured with append-only persistence - **Volume:** `taskapp-redisdata` mounted at `/data` - **Networks:** `backend-net` ### 5. Adminer (Database Web Interface) - **Container name:** `taskapp-adminer` - **Image:** `adminer:latest` - **Port:** `5001` (public) → `5000` (container) - **Role:** Web-based database management tool. Allows direct SQL queries, table browsing, and data export - **Networks:** `frontend-net`, `backend-net` --- ## Networks | Network Name | Driver | Connected Services | Purpose | |-------------|--------|-------------------|---------| | `taskapp-frontend-net` | bridge | frontend, adminer | Isolates user-facing services | | `taskapp-backend-net` | bridge | frontend, api, postgres, redis, adminer | Connects backend services for internal communication | **Why two networks?** - Services on `frontend-net` are publicly accessible - Services on `backend-net` handle internal communication - The `frontend` and `adminer` services bridge both networks since they need public access while communicating with backend services --- ## Volumes | Volume Name | Mount Point | Service | Purpose | |------------|-------------|---------|---------| | `taskapp-pgdata` | `/var/lib/postgresql/data` | postgres | Persists database files across container restarts | | `taskapp-redisdata` | `/data` | redis | Persists Redis append-only file for cache durability | **Data persistence:** Stopping and restarting the application (`./stop-app.sh` then `./start-app.sh`) preserves all data. Only `./remove-app.sh` deletes the volumes. --- ## Container Configuration All containers are configured with: - **Restart policy:** `unless-stopped` — containers automatically restart on failure or system reboot - **Health checks:** PostgreSQL and Redis have health checks; the API and frontend wait for healthy dependencies before starting - **Dependencies:** `docker compose` ensures services start in the correct order: 1. PostgreSQL + Redis (database layer) 2. API (depends on healthy postgres and redis) 3. Frontend + Adminer (depends on api and postgres respectively) - **Environment variables:** Database credentials and connection parameters are passed via environment variables in `docker-compose.yaml` --- ## Quick Start ```bash # 1. Prepare the application (build images, create networks/volumes) ./prepare-app.sh # 2. Start the application ./start-app.sh # 3. Open in browser # Task Manager: http://localhost:5000 # Adminer: http://localhost:5001 ``` --- ## Usage Instructions ### Preparing the application ```bash ./prepare-app.sh ``` This script builds the custom Docker images (frontend, api), and creates the required networks and volumes. ### Starting the application ```bash ./start-app.sh ``` Starts all 5 containers in detached mode. Prints the URLs for accessing the application. ### Stopping the application ```bash ./stop-app.sh ``` Stops all containers **without removing data**. Your tasks and database state are preserved in the persistent volumes. ### Restarting after stop ```bash ./start-app.sh ``` Simply run the start script again. All your data will be intact. ### Removing the application ```bash ./remove-app.sh ``` **⚠️ Warning:** This removes ALL traces of the application including: - All containers - All networks - All persistent volumes (data is lost) - All locally built images --- ## Viewing the Application ### Task Manager (Main Application) - **URL:** [http://localhost:5000](http://localhost:5000) - Features: Create, complete, delete, and filter tasks ### Adminer (Database Management) - **URL:** [http://localhost:5001](http://localhost:5001) - **Login credentials:** - System: PostgreSQL - Server: `postgres` - Username: `taskuser` - Password: `taskpass` - Database: `taskmanager` --- ## Example Workflow ```bash # Prepare the application $ ./prepare-app.sh ============================================= Preparing Task Manager Application... ============================================= [1/3] Building Docker images... ✓ Images built successfully [2/3] Creating networks... ✓ Networks created [3/3] Creating volumes... ✓ Volumes created ============================================= ✓ Application prepared successfully! Run ./start-app.sh to start the application ============================================= # Start the application $ ./start-app.sh ============================================= Starting Task Manager Application... ============================================= [1/2] Starting containers... [2/2] Waiting for services to be ready... ============================================= ✓ Application is running! 🌐 Task Manager: http://localhost:5000 🗄️ Adminer (DB): http://localhost:5001 ============================================= # Open http://localhost:5000 in a web browser and work with the application # Create tasks, mark them complete, delete them, etc. # Stop the application (data is preserved) $ ./stop-app.sh ============================================= Stopping Task Manager Application... ============================================= ✓ Application stopped. Data is preserved in persistent volumes. Run ./start-app.sh to restart. # Start again - all tasks are still there! $ ./start-app.sh # When done, remove everything $ ./remove-app.sh ============================================= Removing Task Manager Application... ============================================= ✓ Application completely removed. ``` --- ## Sources 1. **Docker Documentation** — [https://docs.docker.com/](https://docs.docker.com/) 2. **Docker Compose Documentation** — [https://docs.docker.com/compose/](https://docs.docker.com/compose/) 3. **Nginx Docker Image** — [https://hub.docker.com/_/nginx](https://hub.docker.com/_/nginx) 4. **Node.js Docker Image** — [https://hub.docker.com/_/node](https://hub.docker.com/_/node) 5. **PostgreSQL Docker Image** — [https://hub.docker.com/_/postgres](https://hub.docker.com/_/postgres) 6. **Redis Docker Image** — [https://hub.docker.com/_/redis](https://hub.docker.com/_/redis) 7. **Adminer Docker Image** — [https://hub.docker.com/_/adminer](https://hub.docker.com/_/adminer) 8. **Express.js Documentation** — [https://expressjs.com/](https://expressjs.com/) 9. **node-postgres (pg) Documentation** — [https://node-postgres.com/](https://node-postgres.com/) 10. **Node Redis Client** — [https://github.com/redis/node-redis](https://github.com/redis/node-redis) --- ## Project Structure ``` z1/ ├── docker-compose.yaml # Main orchestration configuration ├── prepare-app.sh # Build images, create networks/volumes ├── start-app.sh # Start all services ├── stop-app.sh # Stop without data loss ├── remove-app.sh # Remove all traces ├── README.md # This documentation ├── frontend/ # Nginx + Static frontend │ ├── Dockerfile # Nginx container build │ ├── nginx.conf # Nginx configuration │ └── public/ │ ├── index.html # Task Manager HTML │ ├── style.css # Styles (dark theme) │ └── app.js # Frontend JavaScript ├── api/ # Node.js REST API │ ├── Dockerfile # API container build │ ├── package.json # Node.js dependencies │ ├── server.js # Express API server │ └── db.js # PostgreSQL connection └── db/ └── init.sql # Database initialization ```