358 lines
14 KiB
Markdown
358 lines
14 KiB
Markdown
# 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)
|
|
|
|
---
|
|
|
|
## Use of Artificial Intelligence
|
|
|
|
Artificial intelligence tools such as ChatGPT and Claude were used as a support tool during development for understanding Docker concepts and debugging scripts. Some configuration issues were also fixed by referring to AI. All implementation, testing, and integration were performed independently.
|
|
|
|
---
|
|
|
|
## 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
|
|
```
|