zkt26/README.md
2026-04-01 09:38:54 +02:00

108 lines
3.7 KiB
Markdown

# 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)
```bash
./prepare-app.sh
```
### Start
```bash
./start-app.sh
```
### Stop (data is preserved)
```bash
./stop-app.sh
```
### Remove everything
```bash
./remove-app.sh
```
## Viewing the application
| URL | Description |
|---|---|
| http://localhost:8080 | Notes web application |
| http://localhost:8081 | Adminer — log in with Server: `db`, User: `appuser`, Password: `apppassword`, Database: `appdb` |
## Example workflow
```bash
./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
- [Docker documentation](https://docs.docker.com/)
- [Flask documentation](https://flask.palletsprojects.com/)
- [Nginx documentation](https://nginx.org/en/docs/)
- [PostgreSQL Docker image](https://hub.docker.com/_/postgres)
- [Adminer Docker image](https://hub.docker.com/_/adminer)
## 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.