Files
jobs/online.md
georg.sinn-schirwitz 23a67d7fe1 initial project commit
2025-08-29 15:07:58 +02:00

214 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Guide to get this online
Awesome—heres a concise, battle-tested set of steps to get your Flask app running behind Traefik on Proxmox, with the code living on your NAS via NFS and exposed as `jobs.allucanget.biz`.
---
# 0) DNS & inbound ports
1. In Cloudflare, add an **A** record
- **Name:** `jobs`
- **IPv4:** `5.226.148.100`
- Decide one of these:
- **Option A (simpler):** set to **DNS only** (grey cloud). Traefik will get Lets Encrypt certs itself.
- **Option B:** keep **Proxied** (orange cloud) and install a **Cloudflare Origin Certificate** on Traefik (Full/Strict).
2. Ensure your router/NAT forwards **80/tcp** and **443/tcp** from WAN to your Traefik box at `192.168.88.10`.
---
# 1) Mount the NAS on the Proxmox host (then bind into the container)
> This avoids NFS-in-container headaches and makes the directory accessible outside the LXC too.
On the **Proxmox host** (not inside a container):
```bash
# Create a mount point for the NAS share
sudo mkdir -p /mnt/nas
# Install NFS client (Debian-based Proxmox)
sudo apt update && sudo apt install -y nfs-common
# (Optional) test mount once
sudo mount -t nfs 192.168.88.9:/mnt/HD/HD_a2/NASNFS /mnt/nas
# Make it permanent in /etc/fstab (add this line):
echo '192.168.88.9:/mnt/HD/HD_a2/NASNFS /mnt/nas nfs defaults,_netdev 0 0' | sudo tee -a /etc/fstab
# Re-mount from fstab to verify
sudo umount /mnt/nas || true
sudo mount -a
# Create your app directory on the NAS thats visible outside the container too
sudo mkdir -p /mnt/nas/jobs-app
sudo chown -R 1000:1000 /mnt/nas/jobs-app # or set to whatever UID/GID you want
```
---
# 2) Create the LXC on Proxmox
1. Download a Debian 12 template (UI: **Datacenter → local → CT Templates → Debian 12**)
2. Create an **unprivileged** LXC (example CTID **201**), with:
- CPU/RAM as needed (e.g., 2 vCPU / 24 GB RAM)
- Root disk: 816 GB is fine
- Network: static IP, e.g. `192.168.88.20/24`, GW `192.168.88.1`
- Features: you dont need NFS inside; well bind-mount from host.
3. Bind-mount the NAS app dir into the container:
```bash
# From the Proxmox host:
pct set 201 -mp0 /mnt/nas/jobs-app,mp=/srv/app
```
4. Start the container:
```bash
pct start 201
```
---
# 3) Prepare Python + Gunicorn inside the LXC
```bash
# Inside CT 201 (ssh or pct enter 201)
apt update && apt install -y python3-venv python3-pip build-essential
# Your code directory is the NAS mount:
cd /srv/app
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install flask gunicorn
```
Minimal Flask app structure (in `/srv/app`):
```
/srv/app
├─ app.py
└─ wsgi.py
```
`app.py`:
```python
from flask import Flask
app = Flask(__name__)
@app.get("/")
def hello():
return "Hello from jobs.allucanget.biz!"
```
`wsgi.py`:
```python
from app import app
if __name__ == "__main__":
app.run()
```
Test locally (inside CT):
```bash
. .venv/bin/activate
gunicorn -b 0.0.0.0:8000 wsgi:app
# Visit http://192.168.88.20:8000 from LAN to confirm
```
Create a systemd service so it starts on boot:
```bash
cat >/etc/systemd/system/jobs.service <<'EOF'
[Unit]
Description=Jobs Flask app (gunicorn)
After=network.target
[Service]
User=root
WorkingDirectory=/srv/app
Environment="PATH=/srv/app/.venv/bin"
ExecStart=/srv/app/.venv/bin/gunicorn -b 0.0.0.0:8000 wsgi:app
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now jobs.service
systemctl status jobs.service --no-pager
```
---
# 4) Wire Traefik to the LXC service
Assumptions:
- Traefik runs at `192.168.88.10`
- You have a **file provider** mounted, e.g. `/etc/traefik/dynamic/`
Create a dynamic config file on the Traefik container host (or inside the Traefik container if thats where the file provider lives), e.g. `/etc/traefik/dynamic/jobs.yml`:
```yaml
http:
routers:
jobs-router:
rule: "Host(`jobs.allucanget.biz`)"
entryPoints:
- websecure
service: jobs-svc
tls:
# Option A: Lets Encrypt (Traefik must be set up with a certResolver in static config)
certResolver: letsencrypt
# Option B (Cloudflare proxied + origin cert): omit certResolver and make sure Traefik serves the CF origin cert
services:
jobs-svc:
loadBalancer:
servers:
- url: "http://192.168.88.20:8000"
```
Reload Traefik (or it auto-watches the file). Make sure Traefiks **static** config has:
- `entryPoints.websecure.address=:443`
- (If using Lets Encrypt) a `certResolver` (HTTP-01 or DNS-01) configured.
- With **Cloudflare “DNS only”**, HTTP-01 is easiest.
- With **Cloudflare proxied**, use a Cloudflare **Origin Certificate** on Traefik (Full/Strict) or use DNS-01.
Optional (X-Forwarded-For): behind Cloudflare, trust CF IP ranges in Traefik so client IPs are correct.
---
# 5) Quick checks
- `curl -I http://192.168.88.20:8000` from Traefik host should return `200`.
- `curl -I https://jobs.allucanget.biz` from outside should return `200` and a valid cert.
- Confirm Cloudflare SSL mode:
- **If DNS only:** Traefik should have a Lets Encrypt cert.
- **If proxied:** Traefik should present the **CF Origin Cert**, and Cloudflare set to **Full (strict)**.
---
# 6) (Nice to have) Security & hardening
- Create a non-root user to run the service; adjust `User=` and file permissions.
- Set a firewall rule so port **8000** on the LXC is only reachable from `192.168.88.10` (Traefik) and your admin IPs.
- Keep `/srv/app` on NAS backed up (snapshot on the NAS).
---
Thats it. If you want, tell me which option you picked for Cloudflare (DNS only vs proxied), and Ill give you the exact Traefik static TLS snippet to match.