feat: Docker, docker-compose, and deployment config (Task 13)

- 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 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 02:26:32 +00:00
parent c9c12a4c2c
commit b31d6637a7
6 changed files with 69 additions and 5 deletions
+6
View File
@@ -0,0 +1,6 @@
node_modules
client/dist
data
.env
.git
*.md
+17
View File
@@ -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
-4
View File
@@ -187,10 +187,6 @@ data/*
build/ build/
dist/ dist/
# Docker
.dockerignore
Dockerfile*
docker-compose*.yml
# IDE # IDE
.vscode/ .vscode/
+24
View File
@@ -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"]
+21
View File
@@ -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:
+1 -1
View File
@@ -5,7 +5,7 @@ export default defineConfig({
root: 'client', root: 'client',
plugins: [react()], plugins: [react()],
build: { build: {
outDir: 'dist', outDir: '../client/dist',
emptyOutDir: true, emptyOutDir: true,
}, },
server: { server: {