Notes App — Docker Assignment
What the application does
A simple Notes web application where users can create, view, and delete short text notes. Notes are stored persistently in a PostgreSQL database. The app is accessible via a web browser.
Services
| Container |
Image |
Port |
Description |
app_frontend |
custom (Nginx) |
8080→80 |
Serves the static HTML/JS frontend and proxies /api/ requests to the backend |
app_backend |
custom (Flask/Python) |
internal 5000 |
REST API for CRUD operations on notes |
app_db |
postgres:16-alpine |
internal 5432 |
Relational database storing notes persistently |
app_adminer |
adminer:4 |
8081→8080 |
Web UI for browsing and managing the PostgreSQL database |
Networks
| Network |
Purpose |
frontend_net |
Connects the Nginx frontend container (externally reachable) |
backend_net |
Internal network connecting frontend→backend→database and Adminer→database |
The database is only on backend_net and is never directly exposed to the host.
Volumes
| Volume |
Used by |
Purpose |
postgres_data |
app_db |
Persists PostgreSQL data across container restarts and stops |
Container configuration
- app_db: configured via environment variables (
POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD). The db/init.sql file is mounted read-only into /docker-entrypoint-initdb.d/ and runs once on first startup to create the notes table and insert seed data.
- app_backend: receives
DATABASE_URL as an environment variable pointing to the db service. Built from ./backend/Dockerfile using Python 3.12-slim with Flask and psycopg2.
- app_frontend: built from
./frontend/Dockerfile using Nginx 1.27-alpine. The custom nginx.conf proxies all /api/ requests to app_backend:5000 and serves index.html for all other paths.
- app_adminer: uses the official Adminer image with no extra configuration. Reachable on port
8081.
- All containers use
restart: on-failure.
Requirements
- Linux OS
- Docker Engine ≥ 24 with the Compose plugin (
docker compose)
Instructions
Prepare (build images)
./prepare-app.sh
Start
./start-app.sh
Stop (data is preserved)
./stop-app.sh
Remove everything
./remove-app.sh
Viewing the application
Example workflow
./prepare-app.sh
# Preparing app...
./start-app.sh
# Running app...
# The app is available at http://localhost:8080
# Adminer (DB UI) is available at http://localhost:8081
# Open browser, add/delete notes
./stop-app.sh
# Stopping app...
# App stopped. Data in volumes is preserved.
./start-app.sh
# Notes are still there — volume was preserved
./remove-app.sh
# Removing app.
Resources used
Use of artificial intelligence
This project was created with the assistance of Kiro AI (kiro-cli chat agent). The AI generated the initial structure of all files including the Docker Compose configuration, Flask application, Nginx configuration, frontend HTML/JS, and shell scripts. All generated code was reviewed and understood by the author. The AI was used as a coding assistant, not as a replacement for understanding the solution.