- Jak postawić własny serwer za 2 EUR/miesiąc
- Jak uruchomić swoje aplikacje Flask w kontenerach
- Jak skonfigurować automatyczne SSL
- Jak zarządzać wieloma projektami na jednym serwerze
- IONOS VPS Basic: 2 EUR/miesiąc
- System: Ubuntu 22.04 LTS
- Zasoby: 1 vCPU, 1GB RAM (wystarczy na start)
# Dostajesz IP i hasło na email
ssh root@123.456.789.123
# Tworzymy nowego użytkownika (nie używamy root!)
adduser junior
usermod -aG sudo junior
# Przechodzimy na nowego użytkownika
su - junior
sudo apt update && sudo apt upgrade -y
sudo apt install podman -y
# Sprawdzamy czy działa
podman --version
# Dodajemy repozytorium Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
# Instalujemy
sudo apt update
sudo apt install caddy -y
# Sprawdzamy
caddy version
# Tworzymy foldery dla naszych projektów
mkdir -p ~/projekty/{sklep,blog,api,portfolio}
cd ~/projekty
~/projekty/sklep/app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return '<h1>Witaj w moim sklepie!</h1>'
@app.route('/produkty')
def produkty():
return '<h1>Lista produktów</h1>'
if __name__ == '__main__':
app.run(debug=True)
~/projekty/sklep/requirements.txt:
Flask==2.3.3
gunicorn==21.2.0
~/projekty/sklep/Dockerfile:
# Używamy lekkiego obrazu Python
FROM python:3.11-slim
# Ustawiamy folder roboczy
WORKDIR /app
# Kopiujemy requirements i instalujemy zależności
COPY requirements.txt .
RUN pip install -r requirements.txt
# Kopiujemy całą aplikację
COPY . .
# Otwieramy port 5000
EXPOSE 5000
# Uruchamiamy aplikację z Gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
cd ~/projekty/sklep
# Budujemy obraz kontenera
podman build -t moj-sklep .
# Uruchamiamy kontener
podman run -d --name sklep -p 5001:5000 moj-sklep
# Sprawdzamy czy działa
podman ps
curl localhost:5001
# Powinno zwrócić: <h1>Witaj w moim sklepie!</h1>
sudo nano /etc/caddy/Caddyfile
# Konfiguracja dla IP (na początku)
:80 {
handle /sklep* {
reverse_proxy localhost:5001
}
respond "Serwer działa! Dodaj /sklep na końcu URL"
}
sudo systemctl reload caddy
Idź na: http://123.456.789.123/sklep
cd ~/projekty/blog
# Kopiujesz tutaj swoje pliki blog-a
# Tworzysz identyczne pliki: app.py, requirements.txt, Dockerfile
podman build -t moj-blog .
podman run -d --name blog -p 5002:5000 moj-blog
cd ~/projekty/api
podman build -t moje-api .
podman run -d --name api -p 5003:5000 moje-api
cd ~/projekty/portfolio
podman build -t moje-portfolio .
podman run -d --name portfolio -p 5004:5000 moje-portfolio
sudo nano /etc/caddy/Caddyfile
:80 {
handle /sklep* {
reverse_proxy localhost:5001
}
handle /blog* {
reverse_proxy localhost:5002
}
handle /api* {
reverse_proxy localhost:5003
}
handle /portfolio* {
reverse_proxy localhost:5004
}
respond "Wybierz: /sklep, /blog, /api, /portfolio"
}
sudo systemctl reload caddy
nano ~/deploy.sh
#!/bin/bash
echo "🚀 Rozpoczynam deployment..."
# Lista projektów i portów
declare -A projekty=(
["sklep"]=5001
["blog"]=5002
["api"]=5003
["portfolio"]=5004
)
# Deploy każdego projektu
for projekt in "${!projekty[@]}"; do
port=${projekty[$projekt]}
echo "📦 Deploying $projekt na porcie $port..."
cd ~/projekty/$projekt
# Zatrzymujemy stary kontener
podman stop $projekt 2>/dev/null || true
podman rm $projekt 2>/dev/null || true
# Budujemy nowy
podman build -t moj-$projekt .
# Uruchamiamy
podman run -d --name $projekt -p $port:5000 moj-$projekt
echo "✅ $projekt działa na porcie $port"
done
echo "🎉 Wszystkie aplikacje uruchomione!"
echo "🌐 Sprawdź: http://$(curl -s ifconfig.me)/sklep"
chmod +x ~/deploy.sh
./deploy.sh
sudo nano /etc/systemd/system/moje-aplikacje.service
[Unit]
Description=Moje Flask Apps
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
User=junior
ExecStart=/home/junior/deploy.sh
ExecStop=/usr/bin/podman stop sklep blog api portfolio
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable moje-aplikacje
sudo systemctl start moje-aplikacje
sudo nano /etc/caddy/Caddyfile
mojadomena.pl {
handle /sklep* {
reverse_proxy localhost:5001
}
handle /blog* {
reverse_proxy localhost:5002
}
handle /api* {
reverse_proxy localhost:5003
}
handle /portfolio* {
reverse_proxy localhost:5004
}
respond "Witaj na mojej stronie!"
}
Caddy automatycznie skonfiguruje SSL! 🔒
podman ps # Działające kontenery
podman ps -a # Wszystkie kontenery
podman logs sklep # Logi kontenera
podman restart sklep # Restart kontenera
sudo systemctl status caddy # Status Caddy
sudo journalctl -u caddy -f # Logi Caddy na żywo
caddy validate --config /etc/caddy/Caddyfile # Sprawdzenie konfiguracji
htop # Zużycie CPU/RAM
df -h # Miejsce na dysku
- Naucz się Git: Zautomatyzuj deployment z GitHub
- Dodaj bazę danych: PostgreSQL w kontenerze
- Monitoring: Dodaj logi i metryki
- Backup: Automatyczne kopie zapasowe
- CI/CD: GitHub Actions do auto-deployment
podman logs nazwa-kontenera # Zobacz co jest nie tak
sudo lsof -i :5001 # Zobacz co używa portu
podman stop stary-kontener # Zatrzymaj stary kontener
sudo systemctl status caddy
caddy validate --config /etc/caddy/Caddyfile
podman system prune -a # Usuń nieużywane obrazy
Masz teraz:
- ✅ Własny serwer za 2 EUR/miesiąc
- ✅ 4 aplikacje Flask w kontenerach
- ✅ Automatyczne SSL
- ✅ Prostą automatyzację
- ✅ Podstawy DevOps
Koszt: ~2 EUR/miesiąc
Czas setup: ~30 minut
Poziom skomplikowania: Początkujący
Jesteś teraz junior DevOps engineer! 🚀