From 0ee39f152eeb5d0fc5baaa3e8462f1adee62585f Mon Sep 17 00:00:00 2001 From: a2nr Date: Sat, 1 Aug 2026 12:56:51 +0000 Subject: [PATCH] refactor(compose): adaptasi pola network tailscale ala firefly-iii MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Semua service share netns elemes-ts (network_mode: service:elemes-ts), hapus bridge network elemes_network - lms-tail.json: proxy target 127.0.0.1 (bukan nama service DNS) - flowchart pindah port 80 → 8081 (konflik port di netns bersama), tambah nginx.conf custom + EXPOSE 8081 - env internal (COMPILER_WORKER_URL, VELXIO_COMPILER_URL, API_BACKEND, hooks fallback, vite dev proxy) → 127.0.0.1 - fix format volume velxio-data/velxio-arduino-libs agar kompatibel podman-compose 1.0.6 (named volume standar) --- config/lms-tail.json | 14 ++-- flowchart/Dockerfile | 7 +- flowchart/nginx.conf | 13 +++ frontend/src/hooks.server.ts | 5 +- frontend/vite.config.ts | 6 +- podman-compose.yml | 151 ++++++++++++++++++----------------- routes/compile.py | 4 +- 7 files changed, 110 insertions(+), 90 deletions(-) create mode 100644 flowchart/nginx.conf diff --git a/config/lms-tail.json b/config/lms-tail.json index 224edb0..d050776 100644 --- a/config/lms-tail.json +++ b/config/lms-tail.json @@ -8,22 +8,22 @@ "${TS_CERT_DOMAIN}:443": { "Handlers": { "/": { - "Proxy": "http://elemes-frontend:3000" + "Proxy": "http://127.0.0.1:3000" }, "/assets/": { - "Proxy": "http://elemes:5000/assets/" + "Proxy": "http://127.0.0.1:5000/assets/" }, "/velxio/api/compile/": { - "Proxy": "http://elemes:5000/velxio-compile/" + "Proxy": "http://127.0.0.1:5000/velxio-compile/" }, "/velxio/api/compile": { - "Proxy": "http://elemes:5000/velxio-compile" + "Proxy": "http://127.0.0.1:5000/velxio-compile" }, "/velxio/": { - "Proxy": "http://velxio:80/" + "Proxy": "http://127.0.0.1:80/" }, "/flowchart/": { - "Proxy": "http://flowchart:80/" + "Proxy": "http://127.0.0.1:8081/" } } } @@ -31,4 +31,4 @@ "AllowFunnel": { "${TS_CERT_DOMAIN}:443": true } -} \ No newline at end of file +} diff --git a/flowchart/Dockerfile b/flowchart/Dockerfile index 86cad6c..fff410f 100644 --- a/flowchart/Dockerfile +++ b/flowchart/Dockerfile @@ -14,5 +14,10 @@ FROM nginx:alpine # Copy built static files to Nginx's default public directory COPY --from=builder /app/dist/ /usr/share/nginx/html/ -EXPOSE 80 +# Listen on 8081 (not 80) — all services share elemes-ts network +# namespace, where port 80 is taken by velxio. Tailscale serve strips +# the /flowchart/ mount point before proxying here. +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 8081 CMD ["nginx", "-g", "daemon off;"] diff --git a/flowchart/nginx.conf b/flowchart/nginx.conf new file mode 100644 index 0000000..636a22c --- /dev/null +++ b/flowchart/nginx.conf @@ -0,0 +1,13 @@ +server { + listen 8081; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # SPA fallback — tailscale serve strips the /flowchart/ mount point, + # so nginx receives /assets/... and / (index.html) + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/frontend/src/hooks.server.ts b/frontend/src/hooks.server.ts index 2bcc0ae..4465b64 100644 --- a/frontend/src/hooks.server.ts +++ b/frontend/src/hooks.server.ts @@ -2,7 +2,8 @@ * SvelteKit server hook — proxies /api/* requests to the Flask backend. * * Uses API_BACKEND env var (set in podman-compose.yml). - * Falls back to http://elemes:5000, then tries container IP resolution. + * Falls back to http://127.0.0.1:5000 — all services share the + * elemes-ts network namespace, so the backend lives on localhost. */ import type { Handle } from '@sveltejs/kit'; @@ -10,7 +11,7 @@ import type { Handle } from '@sveltejs/kit'; function resolveBackend(): string { const env = process.env.API_BACKEND; if (env) return env; - return 'http://elemes:5000'; + return 'http://127.0.0.1:5000'; } const API_BACKEND = resolveBackend(); diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 7873598..560d4f5 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -9,17 +9,17 @@ export default defineConfig({ server: { proxy: { '/api': { - target: 'http://elemes:5000', + target: 'http://127.0.0.1:5000', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') }, '/velxio/api/compile': { - target: 'http://elemes:5000', + target: 'http://127.0.0.1:5000', changeOrigin: true, rewrite: (path) => '/velxio-compile' }, '/assets': { - target: 'http://elemes:5000', + target: 'http://127.0.0.1:5000', changeOrigin: true } } diff --git a/podman-compose.yml b/podman-compose.yml index 31fbbe2..53219ea 100644 --- a/podman-compose.yml +++ b/podman-compose.yml @@ -1,74 +1,6 @@ version: '3.8' services: - elemes: - build: . - image: lms-backend:latest - volumes: - - ../content:/app/content:ro - - ../tokens_siswa.csv:/app/tokens.csv:rw - - ../assets:/app/assets:ro - env_file: - - ../.env - environment: - - COMPILER_WORKER_URL=http://compiler-worker:8080/execute - networks: - - elemes_network - # production - command: gunicorn --config gunicorn.conf.py "app:create_app()" - # debug - # command: python app.py - - compiler-worker: - build: ./compiler_worker - image: lms-compiler-worker:latest - runtime: runsc # Enable gVisor - networks: - - elemes_network - - elemes-frontend: - build: ./frontend - image: lms-frontend:latest - # ports: - # - 3000:3000 - environment: - - ORIGIN=http://localhost:3000 - - API_BACKEND=http://elemes:5000 - - PUBLIC_APP_BAR_TITLE=${APP_BAR_TITLE} - - PUBLIC_COPYRIGHT_TEXT=${COPYRIGHT_TEXT} - - PUBLIC_PAGE_TITLE_SUFFIX=${PAGE_TITLE_SUFFIX} - - PUBLIC_CURSOR_OFFSET_Y=${CURSOR_OFFSET_Y:-50} - networks: - - elemes_network - depends_on: - - elemes - - velxio: - image: lms-velxio:latest - build: - context: ./velxio - dockerfile: Dockerfile.standalone - args: - VITE_BASE_PATH: /velxio/ - VITE_API_BASE: /velxio/api - ENABLE_ESP32: ${ENABLE_ESP32:-0} - environment: - - SECRET_KEY=embed-only-no-auth-needed - - DATABASE_URL=sqlite+aiosqlite:////app/data/velxio.db - - DATA_DIR=/app/data - networks: - - elemes_network - volumes: - - velxio-data:/app/data - - velxio-arduino-libs:/root/.arduino15 - - flowchart: - build: ./flowchart - image: lms-flowchart:latest - networks: - - elemes_network - - elemes-ts: image: docker.io/tailscale/tailscale:latest hostname: ${ELEMES_HOST} @@ -85,16 +17,85 @@ services: - net_admin - sys_module restart: unless-stopped - depends_on: - - elemes-frontend env_file: - ../.env + elemes: + build: . + image: lms-backend:latest + network_mode: service:elemes-ts + volumes: + - ../content:/app/content:ro + - ../tokens_siswa.csv:/app/tokens.csv:rw + - ../assets:/app/assets:ro + env_file: + - ../.env + environment: + - COMPILER_WORKER_URL=http://127.0.0.1:8080/execute + - VELXIO_COMPILER_URL=http://127.0.0.1:80/api/compile/ + restart: unless-stopped + depends_on: + - elemes-ts + # production + command: gunicorn --config gunicorn.conf.py "app:create_app()" + # debug + # command: python app.py + + compiler-worker: + build: ./compiler_worker + image: lms-compiler-worker:latest + runtime: runsc # Enable gVisor + network_mode: service:elemes-ts + restart: unless-stopped + depends_on: + - elemes-ts + + elemes-frontend: + build: ./frontend + image: lms-frontend:latest + # ports: + # - 3000:3000 + network_mode: service:elemes-ts + environment: + - ORIGIN=http://localhost:3000 + - API_BACKEND=http://127.0.0.1:5000 + - PUBLIC_APP_BAR_TITLE=${APP_BAR_TITLE} + - PUBLIC_COPYRIGHT_TEXT=${COPYRIGHT_TEXT} + - PUBLIC_PAGE_TITLE_SUFFIX=${PAGE_TITLE_SUFFIX} + - PUBLIC_CURSOR_OFFSET_Y=${CURSOR_OFFSET_Y:-50} + restart: unless-stopped + depends_on: + - elemes-ts + - elemes + + velxio: + image: lms-velxio:latest + build: + context: ./velxio + dockerfile: Dockerfile.standalone + args: + VITE_BASE_PATH: /velxio/ + VITE_API_BASE: /velxio/api + network_mode: service:elemes-ts + environment: + - SECRET_KEY=embed-only-no-auth-needed + - DATABASE_URL=sqlite+aiosqlite:////app/data/velxio.db + - DATA_DIR=/app/data + restart: unless-stopped + depends_on: + - elemes-ts + volumes: + - velxio-data:/app/data + - velxio-arduino-libs:/root/.arduino15 + + flowchart: + build: ./flowchart + image: lms-flowchart:latest + network_mode: service:elemes-ts + restart: unless-stopped + depends_on: + - elemes-ts + volumes: velxio-data: velxio-arduino-libs: - -networks: - elemes_network: - driver: bridge - network_mode: service:elemes-ts diff --git a/routes/compile.py b/routes/compile.py index fc3a68d..a7e90e6 100644 --- a/routes/compile.py +++ b/routes/compile.py @@ -14,8 +14,8 @@ from extensions import limiter compile_bp = Blueprint('compile', __name__) -COMPILER_WORKER_URL = os.environ.get('COMPILER_WORKER_URL', 'http://compiler-worker:8080/execute') -VELXIO_COMPILER_URL = os.environ.get('VELXIO_COMPILER_URL', 'http://velxio:80/api/compile/') +COMPILER_WORKER_URL = os.environ.get('COMPILER_WORKER_URL', 'http://127.0.0.1:8080/execute') +VELXIO_COMPILER_URL = os.environ.get('VELXIO_COMPILER_URL', 'http://127.0.0.1:80/api/compile/') ANON_QUEUE_DIR = "/tmp/elemes_anon_queue" # Ensure queue directory exists