final
This commit is contained in:
parent
38dd167159
commit
41d540476e
281
sk1/README.md
Normal file
281
sk1/README.md
Normal 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
@ -1,10 +1,10 @@
|
|||||||
const { Pool } = require("pg");
|
const { Pool } = require("pg");
|
||||||
|
|
||||||
const pool = new Pool({
|
const pool = new Pool({
|
||||||
user: "budget_user",
|
user: process.env.DB_USER,
|
||||||
host: "postgres",
|
host: process.env.DB_HOST,
|
||||||
database: "budget_db",
|
database: process.env.DB_NAME,
|
||||||
password: process.env.POSTGRES_PASSWORD,
|
password: process.env.DB_PASSWORD,
|
||||||
port: 5432,
|
port: 5432,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
DATE=$(date +%Y-%m-%d_%H-%M-%S)
|
|
||||||
|
|
||||||
mkdir -p backups
|
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"
|
||||||
|
|||||||
@ -1,5 +1,36 @@
|
|||||||
|
version: '3.9'
|
||||||
|
|
||||||
services:
|
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:
|
frontend:
|
||||||
build: ./frontend
|
build: ./frontend
|
||||||
container_name: budget_frontend
|
container_name: budget_frontend
|
||||||
@ -9,39 +40,17 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- 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:
|
nginx:
|
||||||
image: nginx:latest
|
image: nginx:latest
|
||||||
container_name: budget_nginx
|
container_name: budget_nginx
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
volumes:
|
volumes:
|
||||||
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
|
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
- ./nginx/certbot:/var/www/certbot
|
||||||
|
- /etc/letsencrypt:/etc/letsencrypt
|
||||||
depends_on:
|
depends_on:
|
||||||
- frontend
|
- frontend
|
||||||
- backend
|
- backend
|
||||||
|
|||||||
@ -51,7 +51,7 @@ function App() {
|
|||||||
.filter(t => t.type === "expense")
|
.filter(t => t.type === "expense")
|
||||||
.reduce((acc, t) => acc + Number(t.amount), 0);
|
.reduce((acc, t) => acc + Number(t.amount), 0);
|
||||||
|
|
||||||
const balance = income - expenses;
|
const balance = (income - expenses).toFixed(2);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ function App() {
|
|||||||
|
|
||||||
<h3>Income</h3>
|
<h3>Income</h3>
|
||||||
|
|
||||||
<p>{income} €</p>
|
<p>{income.toFixed(2)} €</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ function App() {
|
|||||||
|
|
||||||
<h3>Expenses</h3>
|
<h3>Expenses</h3>
|
||||||
|
|
||||||
<p>{expenses} €</p>
|
<p>{expenses.toFixed(2)} €</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -107,6 +107,7 @@ function App() {
|
|||||||
|
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
|
step="0.01"
|
||||||
placeholder="amount"
|
placeholder="amount"
|
||||||
value={amount}
|
value={amount}
|
||||||
onChange={(e) => setAmount(e.target.value)}
|
onChange={(e) => setAmount(e.target.value)}
|
||||||
@ -156,7 +157,7 @@ function App() {
|
|||||||
|
|
||||||
<h3>{transaction.title}</h3>
|
<h3>{transaction.title}</h3>
|
||||||
|
|
||||||
<p>{transaction.amount} €</p>
|
<p>{Number(transaction.amount).toFixed(2)} €</p>
|
||||||
|
|
||||||
<small>
|
<small>
|
||||||
{new Date(transaction.created_at).toLocaleString()}
|
{new Date(transaction.created_at).toLocaleString()}
|
||||||
|
|||||||
@ -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 {
|
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 / {
|
location / {
|
||||||
proxy_pass http://frontend:3000;
|
proxy_pass http://frontend:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /api/ {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user