build: Dockerfile and compose for VM103 behind traefik
One image for both processes (node:24-slim pinned by digest, Node 24.21 / SQLite 3.53 as in development). compose: server on the proxy network with traefik labels in the house convention (web-secured, certresolver http, ipwhitelist LAN only), driver with no network; both non-root, read-only rootfs, no capabilities, no host port, no Docker socket. Data in /srv/appdata/homelab-upgrade/data. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
26fc787ae7
commit
089b014edc
3 files changed
+96
No files matched your search
@@ -0,0 +1,15 @@
|
||||
.git
|
||||
node_modules
|
||||
dist
|
||||
coverage
|
||||
data
|
||||
docs
|
||||
tools
|
||||
deploy
|
||||
.env
|
||||
.env.*
|
||||
*.log
|
||||
*.sqlite*
|
||||
src/testing
|
||||
**/*.test.ts
|
||||
**/*.test.tsx
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# One image, two processes (server and driver); the compose file picks the command.
|
||||
# Backend runs TypeScript natively on Node 24 (type stripping): no build step, only the frontend is bundled.
|
||||
ARG NODE_IMAGE=node:24-slim@sha256:2fe369e969550cde8e867afc3fe370b260140cab4a23d467074295b42163d553
|
||||
|
||||
FROM ${NODE_IMAGE} AS build
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
COPY tsconfig.json vite.config.ts ./
|
||||
COPY src ./src
|
||||
RUN npm run build:web
|
||||
|
||||
FROM ${NODE_IMAGE} AS runtime
|
||||
ARG REVISION=unknown
|
||||
LABEL org.opencontainers.image.title="homelab-upgrade" org.opencontainers.image.revision="${REVISION}"
|
||||
ENV NODE_ENV=production HOST=0.0.0.0 PORT=8080 DB_PATH=/data/queue.sqlite WEB_DIR=/app/dist/web
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --omit=dev && npm cache clean --force
|
||||
COPY --from=build /app/dist/web ./dist/web
|
||||
COPY src ./src
|
||||
USER node
|
||||
CMD ["node", "src/main/server.ts"]
|
||||
@@ -0,0 +1,58 @@
|
||||
# Target: /opt/homelab/compose/homelab-upgrade/compose.yaml on VM103.
|
||||
# Image is built on the VM from this repo (see docs/DEPLOY.md); data lives in /srv/appdata/homelab-upgrade/data (uid 1000).
|
||||
name: homelab-upgrade
|
||||
|
||||
x-common: &common
|
||||
image: homelab-upgrade:0.1.0
|
||||
restart: unless-stopped
|
||||
user: "1000:1000"
|
||||
read_only: true
|
||||
cap_drop: [ALL]
|
||||
security_opt: ["no-new-privileges:true"]
|
||||
tmpfs: [/tmp]
|
||||
volumes:
|
||||
- /srv/appdata/homelab-upgrade/data:/data
|
||||
|
||||
services:
|
||||
# The web app: reads the database and inserts rows; executes nothing. No Docker socket, no host port.
|
||||
server:
|
||||
<<: *common
|
||||
command: ["node", "src/main/server.ts"]
|
||||
environment:
|
||||
TZ: Europe/Warsaw
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/api/health').then((r) => process.exit(r.ok ? 0 : 1), () => process.exit(1))"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
networks: [default, proxy]
|
||||
labels:
|
||||
traefik.enable: "true"
|
||||
traefik.docker.network: "proxy"
|
||||
traefik.http.routers.homelab-upgrade.rule: 'Host(`upgrade.mariuszpacek.pl`)'
|
||||
traefik.http.routers.homelab-upgrade.entrypoints: "web-secured"
|
||||
traefik.http.routers.homelab-upgrade.priority: "100"
|
||||
traefik.http.routers.homelab-upgrade.middlewares: "homelab-upgrade-lan"
|
||||
traefik.http.routers.homelab-upgrade.tls: "true"
|
||||
traefik.http.routers.homelab-upgrade.tls.certresolver: "http"
|
||||
traefik.http.routers.homelab-upgrade.service: "homelab-upgrade"
|
||||
traefik.http.services.homelab-upgrade.loadbalancer.server.port: "8080"
|
||||
# No login yet: LAN only.
|
||||
traefik.http.middlewares.homelab-upgrade-lan.ipwhitelist.sourcerange: "192.168.0.1/24,10.0.0.0/16"
|
||||
|
||||
# The driver: takes queued steps one at a time. Only fake demo handlers exist so far (DEMO=1),
|
||||
# so it needs no network, no Docker socket and no secrets.
|
||||
driver:
|
||||
<<: *common
|
||||
command: ["node", "src/main/driver.ts"]
|
||||
environment:
|
||||
TZ: Europe/Warsaw
|
||||
DEMO: "1"
|
||||
DRIVER_IDLE_MS: "5000"
|
||||
network_mode: none
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
name: proxy
|
||||
external: true
|
||||
Reference in new issue
Block a user