From cb565b5ac848986d6ca1a52a182abfab9e3b7c20 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 15 Jan 2026 22:18:56 -0700 Subject: [PATCH] Containerize frontend --- .dockerignore | 17 +++++++++++++++++ Dockerfile | 41 ++++++++++++++++++++++++++++++++++++++++ docker-compose.caddy.yml | 30 ++++++++++++----------------- scripts/setup-prod.sh | 22 ++++----------------- 4 files changed, 74 insertions(+), 36 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..628e382 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +node_modules +dist +.git +.gitignore +*.md +.env* +!.env.example +server/ +authentik/ +caddy/ +scripts/ +docs/ +tests/ +*.log +.DS_Store +Caddyfile +docker-compose*.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..10a3651 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +# Kaboot Frontend - Multi-stage Production Build +# +# Build: +# docker build \ +# --build-arg VITE_API_URL=https://kaboot.example.com \ +# --build-arg VITE_BACKEND_URL=https://kaboot.example.com \ +# --build-arg VITE_AUTHENTIK_URL=https://auth.example.com \ +# -t kaboot-frontend . + +FROM node:20-alpine AS builder +WORKDIR /app + +COPY package*.json ./ +RUN npm ci --silent + +COPY index.html tsconfig.json vite.config.ts postcss.config.mjs ./ +COPY src/ ./src/ +COPY components/ ./components/ +COPY hooks/ ./hooks/ +COPY public/ ./public/ + +ARG VITE_API_URL +ARG VITE_BACKEND_URL +ARG VITE_AUTHENTIK_URL +ARG VITE_OIDC_CLIENT_ID=kaboot-spa +ARG VITE_OIDC_APP_SLUG=kaboot +ARG GEMINI_API_KEY + +ENV VITE_API_URL=$VITE_API_URL \ + VITE_BACKEND_URL=$VITE_BACKEND_URL \ + VITE_AUTHENTIK_URL=$VITE_AUTHENTIK_URL \ + VITE_OIDC_CLIENT_ID=$VITE_OIDC_CLIENT_ID \ + VITE_OIDC_APP_SLUG=$VITE_OIDC_APP_SLUG \ + GEMINI_API_KEY=$GEMINI_API_KEY + +RUN npm run build + +FROM caddy:2-alpine +COPY --from=builder /app/dist /srv/frontend +EXPOSE 80 443 +CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] diff --git a/docker-compose.caddy.yml b/docker-compose.caddy.yml index a79fb70..bba43ed 100644 --- a/docker-compose.caddy.yml +++ b/docker-compose.caddy.yml @@ -1,28 +1,22 @@ -# Caddy Reverse Proxy for Kaboot Production -# -# This compose file adds Caddy as a reverse proxy with automatic HTTPS. -# Use with docker-compose.prod.yml using the -f flag. -# -# Usage: -# docker compose -f docker-compose.prod.yml -f docker-compose.caddy.yml up -d -# -# Prerequisites: -# 1. Copy Caddyfile.example to Caddyfile and update domains -# 2. Build the frontend: npm run build -# 3. Update your domain DNS to point to your server -# 4. See docs/PRODUCTION.md for full instructions - services: - caddy: - image: caddy:2-alpine - container_name: kaboot-caddy + kaboot-frontend: + build: + context: . + dockerfile: Dockerfile + args: + VITE_API_URL: https://${KABOOT_DOMAIN} + VITE_BACKEND_URL: https://${KABOOT_DOMAIN} + VITE_AUTHENTIK_URL: https://${AUTH_DOMAIN} + VITE_OIDC_CLIENT_ID: kaboot-spa + VITE_OIDC_APP_SLUG: kaboot + GEMINI_API_KEY: ${GEMINI_API_KEY:-} + container_name: kaboot-frontend restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - - ./dist:/srv/frontend:ro - ./caddy/data:/data - ./caddy/config:/config depends_on: diff --git a/scripts/setup-prod.sh b/scripts/setup-prod.sh index 1910756..e98d4ed 100755 --- a/scripts/setup-prod.sh +++ b/scripts/setup-prod.sh @@ -133,6 +133,10 @@ cat > .env << EOF # Kaboot Production Configuration # Generated by setup-prod.sh on $(date) +# Domain Configuration (used by docker-compose for frontend build) +KABOOT_DOMAIN=${KABOOT_DOMAIN} +AUTH_DOMAIN=${AUTH_DOMAIN} + # Database PG_PASS=${PG_PASS} PG_USER=authentik @@ -229,29 +233,12 @@ if [ -f "$DEV_BLUEPRINT" ]; then print_success "Removed development blueprint" fi -print_step "Installing frontend dependencies..." - -npm install --silent 2>/dev/null || npm install - -print_success "Dependencies installed" - -print_step "Building frontend with production URLs..." - -VITE_API_URL="https://${KABOOT_DOMAIN}" \ -VITE_BACKEND_URL="https://${KABOOT_DOMAIN}" \ -VITE_AUTHENTIK_URL="https://${AUTH_DOMAIN}" \ -VITE_OIDC_CLIENT_ID="kaboot-spa" \ -VITE_OIDC_APP_SLUG="kaboot" \ -npm run build --silent 2>/dev/null || npm run build - if [ -n "$GEMINI_API_KEY" ]; then print_success "System AI will be available (key configured for backend)" else print_warning "No Gemini API key provided - users must configure their own" fi -print_success "Frontend built" - echo "" echo -e "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}" echo -e "${GREEN}${BOLD} Setup Complete!${NC}" @@ -280,7 +267,6 @@ echo "──────────────────────── echo " .env - Environment variables" echo " Caddyfile - Reverse proxy config" echo " authentik/blueprints/kaboot-setup-production.yaml" -echo " dist/ - Built frontend" echo "" echo -e "${BOLD}Next Steps${NC}" echo "────────────────────────────────────────────────────────────"