README.md

This commit is contained in:
Mohammed Niaz Khaleel Jameel 2026-04-01 10:49:29 +02:00
parent a8483dc085
commit 4a165cc49b

View File

@ -1,8 +1,10 @@
# My Diary — Docker Web Application
# Assignment-1: Docker
**Technical University of Kosice**
**Faculty of Electrical Engineering and Informatics**
**CLOUD TECHNOLOGIES**
**Done by: Mohammed Niaz Khaleel Jameel**
**Technical University of Kosice — Faculty of Electrical Engineering and Informatics**
**Cloud Technologies — Assignment 1: Docker**
---
@ -12,7 +14,7 @@
2. [Description of the application](#2-description-of-the-application)
3. [Virtual networks and named volumes](#3-virtual-networks-and-named-volumes)
4. [Container configuration](#4-container-configuration)
5. [List of containers](#5-list-of-containers)
5. [List of Containers](#5-list-of-containers)
6. [Instructions on how to prepare, launch, pause and delete the application](#6-instructions-on-how-to-prepare-launch-pause-and-delete-the-application)
7. [How to view the application in a web browser](#7-how-to-view-the-application-in-a-web-browser)
8. [List of used resources](#8-list-of-used-resources)
@ -25,7 +27,7 @@
### Required software
**1. Operating System**
- Windows 10/11 with WSL2 (Windows Subsystem for Linux) enabled
- Windows 10/11 with WSL2 (Windows Subsystem for Linux) enabled.
**2. Docker Engine**
- Version 20.10 or newer
@ -33,89 +35,92 @@
- On Windows we need Docker Desktop with WSL2 backend enabled
**3. Docker Compose**
- Version 2.0 or any newer version
- Version 2.0 or maybe any newer version will be fine.
- Command to check its usage: `docker compose version`
**4. Internet connection**
- Required only during `prepare-app.sh` to pull these images from Docker Hub:
- `postgres:15-alpine`
- `nginx:alpine`
- `python:3.11-slim` — used to build the app image
- Since Python, PostgreSQL and Nginx run inside the container, and Django is installed inside the container via pip, we do not need to install these manually
- Required only during prepare-app.sh to pull these images from Docker Hub:
- postgres:15-alpine
- nginx:alpine
- python:3.11-slim — These were used to build the app image
- Since python, postgresSQL, nginx runs inside the container and Django installed inside the container via pip, we don't need to install these manually
### Hardware requirements
- At least 1 GB free RAM for all three containers
- At least 2 GB free disk space for Docker images
### Network requirements
- Port 80 must be free on the host machine — make sure it is not used by another web server
- Port 80 must be free on the host machine. Make sure it is not used by another web server.
---
## 2. Description of the application
My Diary is a private, multi-user web diary application accessible through localhost. It allows multiple users to each have their own personal diary, completely separate from other users.
My Diary is a private, multi-user web diary application accessible through my localhost. It allows multiple users to each have their own personal diary, separate from other users.
### Account management
- Register a new personal account with a username and password
- Log in and log out securely
- Each user can only see their own entries — never anyone else's
1. Register a new personal account with a username and password.
2. Log in and log out securely.
3. Each user can only see their own entries — never anyone else's.
### Writing diary entries
- Create a new diary entry with a title, written content, and a mood tag
- Available moods: 😊 Happy, 😢 Sad, 😰 Anxious, 😌 Calm, 🤩 Excited, 😠 Angry, 🙏 Grateful, 😴 Tired
- Edit an existing entry at any time
- Delete an entry permanently
1. Create a new diary entry with a title, written content, and a mood tag.
2. Edit an existing entry at any time.
3. Delete an entry permanently.
### Browsing entries
- View all past entries displayed as cards on the home page, sorted newest first
- Click any entry card to read the full entry
- Search entries by keyword — searches both the title and the content
- Filter entries by mood
1. View all past entries displayed as cards on the home page, sorted newest first
2. Click any entry card to read the full entry
3. Search entries by keyword — searches both the title and the content
4. Filter entries by mood
### Data persistence
All diary entries are stored in a PostgreSQL database. The data is saved in a Docker named volume (`postgres_data`) which means entries survive container restarts, application updates, and even stopping and restarting the entire application.
1. All diary entries are stored in a PostgreSQL database. The data is saved in a Docker named volume (postgres_data) which means entries survive container restarts, application updates, and even stopping and restarting the entire application.
### Admin panel
A Django admin panel is available at `/admin/` for superusers to manage all users and entries directly.
1. A Django admin panel is available at /admin/ for superusers to manage all users and entries directly.
---
## 3. Virtual networks and named volumes
### Virtual network — `diary_network`
- The Virtual networks here is: diary_network
- A private Docker bridge network that connects all three containers together.
- Containers communicate with each other using container names as hostnames instead of IP addresses.
- diary-nginx talks to diary-app using the hostname app on port 8000, and diary-app talks to diary-db using the hostname db on port 5432.
- From outside, only diary-nginx is reachable on port 80 where the database and Django app are completely hidden from the internet.
- Without this network, containers cannot see each other at all.
A private Docker bridge network that connects all three containers together. Containers communicate with each other using container names as hostnames instead of IP addresses. `diary-nginx` talks to `diary-app` using the hostname `app` on port `8000`, and `diary-app` talks to `diary-db` using the hostname `db` on port `5432`. From outside, only `diary-nginx` is reachable on port `80` — the database and Django app are completely hidden from the internet. Without this network, containers cannot see each other at all.
- Some of the named volume used are: postgres_data and diary_static
- Postgres_data is mounted inside the diary-db container at /var/lib/postgresql/data.
- Stores the entire PostgreSQL database of all user accounts and all diary entries.
- This volume lives independently of the containers, so when you stop the application the data stays on disk and is available again when you restart.
- It is only permanently deleted when running remove-app.sh.
### Named volume — `postgres_data`
Mounted inside the `diary-db` container at `/var/lib/postgresql/data`. Stores the entire PostgreSQL database of all user accounts and all diary entries. This volume lives independently of the containers, so when you stop the application the data stays on disk and is available again when you restart. It is only permanently deleted when running `remove-app.sh`.
### Named volume — `diary_static`
Mounted inside `diary-app` at `/app/staticfiles` with write access, and inside `diary-nginx` at the same path as read-only. When `diary-app` starts, Django writes all static files (CSS stylesheets) into this volume. Nginx then reads directly from the same volume to serve them to the browser, without going through Django at all. This makes static file serving faster and more efficient.
- Likewise, diary_static is mounted inside diary-app at /app/staticfiles with write access, and inside diary-nginx at the same path as read-only.
- When diary-app starts, Django writes all static files (CSS stylesheets) into this volume.
- Nginx then reads directly from the same volume to serve them to the browser, without going through Django at all.
- This makes static file serving faster and more efficient.
---
## 4. Container configuration
The `diary-db` container runs `postgres:15-alpine` and is configured entirely through environment variables`POSTGRES_DB`, `POSTGRES_USER`, and `POSTGRES_PASSWORD` which set up the database name and credentials on first startup. It mounts the `postgres_data` named volume to persist all data and is not exposed on any host port, making it only reachable from within `diary_network`.
The diary-db container runs postgres:15-alpine and is configured entirely through environment variables, POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD, which set up the database name and credentials on first startup. It mounts the postgres_data named volume to persist all data and is not exposed on any host port, making it only reachable from within diary_network.
The `diary-app` container is built from a custom Dockerfile based on `python:3.11-slim`. It installs all Python dependencies from `requirements.txt` and runs Django via Gunicorn with 2 worker processes. A custom `entrypoint.sh` script runs on startup — it waits until PostgreSQL is ready, runs database migrations automatically, then starts Gunicorn. The container is configured through environment variables for the database connection, secret key, and debug mode. It mounts the `diary_static` volume to share static files with Nginx.
The diary-app container is built from a custom docker file based on python:3.11-slim. It installs all Python dependencies from requirements.txt and runs Django via gunicorn with 2 worker processes. A custom entrypoint.sh script runs on startup and it waits until PostgreSQL is ready, runs database migrations automatically, then starts Gunicorn. The container is configured through environment variables for the database connection, secret key, and debug mode. It mounts the diary_static volume to share static files with Nginx.
The `diary-nginx` container runs `nginx:alpine` and is the only container exposed to the host on port `80`. Its configuration file `nginx/nginx.conf` is attached into the container, telling Nginx to serve static files directly from the `diary_static` volume and forward all other requests to `diary-app` on port `8000`.
The diary-nginx container runs nginx:alpine and is the only container exposed to the host on port 80. Its configuration file nginx.conf is attached into the container, telling Nginx to serve static files directly from the diary_static volume and forward all other requests to diary-app on port 8000.
---
## 5. List of containers
## 5. List of Containers
There are three containers used for running this web application.
| Container | Image | Port | Description |
|---|---|---|---|
| `diary-db` | `postgres:15-alpine` | 5432 (internal only) | Relational database that stores all user accounts and diary entries |
| `diary-app` | `diary-app:latest` | 8000 (internal only) | Django web application served by Gunicorn — handles all business logic and page rendering |
| `diary-nginx` | `nginx:alpine` | 80 (public) | Reverse proxy that receives all browser requests, serves static files directly and forwards everything else to Django |
1. **diary_db** Image used is postgres: 15-alpine which is a relational database that stores all user accounts and diary entries.
2. **diary_app** Image used is diary_app which runs on port 8000. It runs Django web app served by gunicorn and this handles all business logic.
3. **diary_nginx** Image used is nginx which runs on port 80. It is basically a reverse proxy that receives all browser requests, serves static files directly and forwards everything else to Django.
---
@ -125,38 +130,37 @@ There are three containers used for running this web application.
```bash
./prepare-app.sh
```
Builds the Docker image and creates the network and volumes. This has to be run once before starting the application for the first time, or again after changing the code.
This will build the docker image and creates the network and volumes. This has to be run once before starting the application for the first time or maybe after changing the code.
### Launch
```bash
./start-app.sh
```
Starts all three containers. The app will then be available at `http://localhost`.
This starts all three containers mentioned previously. The app will be then viewed at localhost.
### Pause
```bash
./stop-app.sh
```
Stops and removes all containers but keeps the `postgres_data` and `diary_static` volumes intact. All diary entries are preserved. The application can be started again afterwards using `./start-app.sh`.
Stops and removes all containers but keeps the postgres_data and diary_static volumes just there. All diary entries are preserved. The application can be seen afterwards after launching it.
### Delete
```bash
./remove-app.sh
```
Permanently removes all containers, images, volumes and the network. All diary data is deleted. You will need to run `./prepare-app.sh` again to use the application from scratch.
This deletes the entire containers, images, etc., permanently. You may need to again initialize by creating it first.
---
## 7. How to view the application in a web browser
To view the application, once it is prepared, launch it using `./start-app.sh`. After a few seconds all containers will be running and the application can be opened in any web browser at:
- To view the application, once our application is prepared, we need to launch it using the `./start-app.sh`.
- After few seconds, the link to local host will be created and we can use any of our desktop's web browser to view.
```
http://localhost
```
Click **Register here** to create a new account, then log in and start writing diary entries.
---
## 8. List of used resources
@ -169,4 +173,4 @@ Click **Register here** to create a new account, then log in and start writing d
## 9. Use of artificial intelligence
I used Claude (claude.ai) by Anthropic as an assistant for guiding me through this project. It helped me with generating code, explaining Docker concepts, and fixing configuration issues. All final decisions regarding the application design, structure, and technology choices were made by me.
I used Claude (claude.ai) by Anthropic as an assistant for guiding me for this project. It helped me with generating code, explaining docker concepts, and fixing configuration issues. All final decisions regarding the application design, structure, and technology choices were made by me.