This commit is contained in:
Ferko 2026-05-19 20:28:07 +00:00
parent 38dd167159
commit 41d540476e
6 changed files with 350 additions and 39 deletions

281
sk1/README.md Normal file
View File

@ -0,0 +1,281 @@
# Budget Tracker Cloud Application
## URL aplikácie
https://budgettomas.dedyn.io
---
# O aplikácii
Budget Tracker je webová aplikácia na správu príjmov a výdavkov.
Funkcie:
* pridávanie transakcií
* mazanie transakcií
* výpočet zostatku
* zobrazenie príjmov a výdavkov
* zabezpečené HTTPS pripojenie
---
# Použité technológie
* React frontend
* Node.js Express backend
* PostgreSQL databáza
* nginx reverse proxy
* Docker Compose
* Oracle Cloud Infrastructure
* Let's Encrypt HTTPS
---
# Kontajnery
Aplikácia používa 4 kontajnery:
* frontend
* backend
* postgres
* nginx
---
# Nasadenie aplikácie
Spustenie aplikácie:
./prepare-app.sh
Zastavenie a odstránenie aplikácie:
./remove-app.sh
---
# Záloha databázy
Vytvorenie zálohy databázy:
./backup.sh
Súbor zálohy:
backups/backup.sql
---
# Environment premenné
Citlivé údaje sú uložené v:
.env
Súbor .env je ignorovaný pomocou .gitignore.
---
# HTTPS
Aplikácia používa:
* nginx reverse proxy
* Let's Encrypt SSL certifikát
---
# Logy
Zobrazenie nginx logov:
docker logs budget_nginx
alebo:
docker exec -it budget_nginx cat /var/log/nginx/access.log
---
# Trvalé úložisko
Databáza používa Docker volume:
postgres_data:
---
# Automatický reštart
Kontajnery používajú:
restart: always
---
# Cloud infraštruktúra
Aplikácia je nasadená na Oracle Cloud Infrastructure pomocou Ubuntu Servera a Docker Compose.
---
# Externé zdroje
* Docker dokumentácia
* nginx dokumentácia
* PostgreSQL dokumentácia
* Oracle Cloud dokumentácia
* React dokumentácia
* Express.js dokumentácia
* Let's Encrypt dokumentácia
---
# Analýza nákladov
Predpoklady:
* 1000 používateľov denne
* databáza alebo súbory veľkosti 50 GB
Použité cloudové zdroje:
| Zdroj | Cena | Fakturácia |
| ----------------------- | ------------- | ---------- |
| Oracle Cloud Compute VM | 0 € | mesačne |
| 50 GB storage | približne 5 € | mesačne |
| Verejná IP adresa | 0 € | mesačne |
| HTTPS certifikát | 0 € | ročne |
| DNS služba | 0 € | mesačne |
Odhad ročných nákladov:
| Položka | Cena |
| ---------------- | -------------------- |
| Compute VM | 0 € |
| Storage | približne 60 € ročne |
| HTTPS certifikát | 0 € |
| DNS | 0 € |
| Spolu | približne 60 € ročne |
---
# Opis súborov
| Súbor | Obsah |
| ------------------- | -------------------------------- |
| docker-compose.yaml | konfigurácia Docker kontajnerov |
| nginx/default.conf | nginx reverse proxy konfigurácia |
| backend/server.js | backend API |
| backend/db.js | pripojenie na databázu |
| frontend/src/App.js | React frontend |
| backup.sh | vytvorenie databázovej zálohy |
| prepare-app.sh | spustenie aplikácie |
| remove-app.sh | odstránenie aplikácie |
| .env | environment premenné |
| README.md | dokumentácia projektu |
---
# Stručný opis konfigurácie
Projekt používa Docker Compose na správu kontajnerov.
nginx slúži ako reverse proxy a zabezpečuje HTTPS komunikáciu.
Backend pomocou Node.js Express a komunikuje s PostgreSQL databázou.
Frontend je vytvorený v Reacte.
---
# Návod na použitie aplikácie
Aplikáciu je možné otvoriť vo webovom prehliadači:
https://budgettomas.dedyn.io
Používateľ môže pridávať a mazať transakcie a sledovať zostatok.
---
# Návod na vykonanie zálohy
Spustenie backup scriptu:
./backup.sh
Výsledný backup sa uloží do:
backups/backup.sql
---
# Návod na zobrazenie logov
Zobrazenie nginx logov:
docker logs budget_nginx
alebo:
docker exec -it budget_nginx cat /var/log/nginx/access.log
---
# Podmienky spustenia scriptov
## prepare-app.sh
Podmienky:
* nainštalovaný Docker
* nainštalovaný Docker Compose
* Linux systém
* dostupný internet
* existujúci súbor .env
Spustenie:
./prepare-app.sh
---
## remove-app.sh
Podmienky:
* existujúce Docker kontajnery
* spustený Docker daemon
Spustenie:
./remove-app.sh
---

View File

@ -1,10 +1,10 @@
const { Pool } = require("pg");
const pool = new Pool({
user: "budget_user",
host: "postgres",
database: "budget_db",
password: process.env.POSTGRES_PASSWORD,
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_NAME,
password: process.env.DB_PASSWORD,
port: 5432,
});

View File

@ -1,9 +1,7 @@
#!/bin/bash
DATE=$(date +%Y-%m-%d_%H-%M-%S)
mkdir -p backups
docker exec budget_postgres pg_dump -U budget_user budget_db > backups/backup_$DATE.sql
docker exec budget_postgres pg_dump -U postgres budget_db > backups/backup.sql
echo "backup created: backups/backup_$DATE.sql"
echo "backup completed"

View File

@ -1,5 +1,36 @@
version: '3.9'
services:
postgres:
image: postgres:16
container_name: budget_postgres
restart: always
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
backend:
build: ./backend
container_name: budget_backend
restart: always
env_file:
- .env
ports:
- "5000:5000"
environment:
DB_HOST: ${DB_HOST}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME}
depends_on:
- postgres
frontend:
build: ./frontend
container_name: budget_frontend
@ -9,39 +40,17 @@ services:
depends_on:
- backend
backend:
build: ./backend
container_name: budget_backend
restart: always
env_file:
- .env
ports:
- "5000:5000"
depends_on:
- postgres
postgres:
image: postgres:16
container_name: budget_postgres
restart: always
environment:
POSTGRES_USER: budget_user
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: budget_db
volumes:
- postgres_data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
nginx:
image: nginx:latest
container_name: budget_nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/certbot:/var/www/certbot
- /etc/letsencrypt:/etc/letsencrypt
depends_on:
- frontend
- backend

View File

@ -51,7 +51,7 @@ function App() {
.filter(t => t.type === "expense")
.reduce((acc, t) => acc + Number(t.amount), 0);
const balance = income - expenses;
const balance = (income - expenses).toFixed(2);
return (
@ -77,7 +77,7 @@ function App() {
<h3>Income</h3>
<p>{income} </p>
<p>{income.toFixed(2)} </p>
</div>
@ -85,7 +85,7 @@ function App() {
<h3>Expenses</h3>
<p>{expenses} </p>
<p>{expenses.toFixed(2)} </p>
</div>
@ -107,6 +107,7 @@ function App() {
<input
type="number"
step="0.01"
placeholder="amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
@ -156,7 +157,7 @@ function App() {
<h3>{transaction.title}</h3>
<p>{transaction.amount} </p>
<p>{Number(transaction.amount).toFixed(2)} </p>
<small>
{new Date(transaction.created_at).toLocaleString()}

View File

@ -1,12 +1,34 @@
server {
listen 80;
server_name budgettomas.dedyn.io;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 80;
listen 443 ssl;
server_name budgettomas.dedyn.io;
ssl_certificate /etc/letsencrypt/live/budgettomas.dedyn.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/budgettomas.dedyn.io/privkey.pem;
location / {
proxy_pass http://frontend:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/ {
proxy_pass http://backend:5000/;
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://backend:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}