From b31d6637a71301b4fdd8882956dd57822b898639 Mon Sep 17 00:00:00 2001 From: kitadmin Date: Thu, 30 Apr 2026 02:26:32 +0000 Subject: [PATCH] feat: Docker, docker-compose, and deployment config (Task 13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dockerfile: two-stage build (builder installs all deps + vite build; runtime copies dist + server) - docker-compose.yml: 127.0.0.1:3004:8080, named volume for SQLite, env var interpolation - .env.example: all required environment variables documented - .dockerignore: exclude node_modules, dist, data, .env from build context - vite.config.ts: outDir → ../client/dist, /api proxy to :3001 for dev - .gitignore: remove Docker entries (files should be tracked for deployment) Co-Authored-By: Claude Sonnet 4.6 --- .dockerignore | 6 ++++++ .env.example | 17 +++++++++++++++++ .gitignore | 4 ---- Dockerfile | 24 ++++++++++++++++++++++++ docker-compose.yml | 21 +++++++++++++++++++++ vite.config.ts | 2 +- 6 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a0190de --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +client/dist +data +.env +.git +*.md diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..dfba1b0 --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +# MorseQuest Environment Variables +# Copy to .env and fill in values + +PORT=3001 +NODE_ENV=development + +# SMTP (for magic link emails) +SMTP_HOST=mail.keylinkit.net +SMTP_PORT=587 +SMTP_USER=noreply@morsequest.keylinkit.net +SMTP_PASS= + +# Admin panel password +ADMIN_PASSWORD= + +# App URL (used in magic link emails) +APP_URL=http://localhost:3001 diff --git a/.gitignore b/.gitignore index af5fc62..fcabfaa 100644 --- a/.gitignore +++ b/.gitignore @@ -187,10 +187,6 @@ data/* build/ dist/ -# Docker -.dockerignore -Dockerfile* -docker-compose*.yml # IDE .vscode/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..92c73a2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# --- Build stage --- +FROM node:20-alpine AS builder +WORKDIR /app +RUN apk add --no-cache python3 make g++ +COPY package.json package-lock.json* ./ +RUN npm install --no-audit --no-fund +COPY . . +RUN npm run build + +# --- Runtime stage --- +FROM node:20-alpine +ENV NODE_ENV=production PORT=8080 +WORKDIR /app +RUN apk add --no-cache python3 make g++ +COPY package.json package-lock.json* ./ +RUN npm install --omit=dev --no-audit --no-fund +COPY --from=builder /app/client/dist ./client/dist +COPY server/ ./server/ +RUN mkdir -p /app/data && chown -R node:node /app +USER node +EXPOSE 8080 +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD wget -q --spider http://localhost:8080/ || exit 1 +CMD ["node", "server/server.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f884e0d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +services: + morsequest: + image: morsequest:latest + container_name: morsequest + restart: unless-stopped + ports: + - "127.0.0.1:3004:8080" + volumes: + - morsequest-data:/app/data + environment: + PORT: "8080" + NODE_ENV: production + SMTP_HOST: mail.keylinkit.net + SMTP_PORT: "587" + SMTP_USER: ${SMTP_USER} + SMTP_PASS: ${SMTP_PASS} + ADMIN_PASSWORD: ${ADMIN_PASSWORD} + APP_URL: https://morsequest.keylinkit.net + +volumes: + morsequest-data: diff --git a/vite.config.ts b/vite.config.ts index fc59890..adbf602 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ root: 'client', plugins: [react()], build: { - outDir: 'dist', + outDir: '../client/dist', emptyOutDir: true, }, server: {