build: add Docker Compose setup for Dokploy deployment
- Multi-stage Dockerfile for Go backend (golang:1.25-alpine -> alpine:3) - Multi-stage Dockerfile for Next.js frontend (bun:1 -> node:22-alpine) - docker-compose.yml with backend + frontend services, health checks - Next.js standalone output + API rewrites to proxy /api/* to backend - .dockerignore files for both services - .env.example documenting required environment variables
This commit is contained in:
12
.env.example
Normal file
12
.env.example
Normal file
@@ -0,0 +1,12 @@
|
||||
# KanzlAI Environment Variables
|
||||
# Copy to .env and fill in values: cp .env.example .env
|
||||
|
||||
# Backend
|
||||
PORT=8080
|
||||
|
||||
# Supabase (required for database access)
|
||||
SUPABASE_URL=
|
||||
SUPABASE_ANON_KEY=
|
||||
|
||||
# Claude API (required for AI features)
|
||||
ANTHROPIC_API_KEY=
|
||||
6
backend/.dockerignore
Normal file
6
backend/.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
bin/
|
||||
*.exe
|
||||
.git
|
||||
.gitignore
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
15
backend/Dockerfile
Normal file
15
backend/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
# Build
|
||||
FROM golang:1.25-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY go.mod ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server
|
||||
|
||||
# Run
|
||||
FROM alpine:3
|
||||
RUN apk --no-cache add ca-certificates
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/server .
|
||||
EXPOSE 8080
|
||||
CMD ["./server"]
|
||||
33
docker-compose.yml
Normal file
33
docker-compose.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
expose:
|
||||
- "8080"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- PORT=8080
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 5s
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- .env
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
9
frontend/.dockerignore
Normal file
9
frontend/.dockerignore
Normal file
@@ -0,0 +1,9 @@
|
||||
node_modules/
|
||||
.next/
|
||||
out/
|
||||
build/
|
||||
.git
|
||||
.gitignore
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
.env*
|
||||
28
frontend/Dockerfile
Normal file
28
frontend/Dockerfile
Normal file
@@ -0,0 +1,28 @@
|
||||
# Dependencies
|
||||
FROM oven/bun:1 AS deps
|
||||
WORKDIR /app
|
||||
COPY package.json bun.lock ./
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
# Build
|
||||
FROM oven/bun:1 AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
ENV API_URL=http://backend:8080
|
||||
RUN mkdir -p public
|
||||
RUN bun run build
|
||||
|
||||
# Run
|
||||
FROM node:22-alpine AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
ENV PORT=3000
|
||||
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["node", "server.js"]
|
||||
@@ -1,7 +1,13 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
output: "standalone",
|
||||
rewrites: async () => [
|
||||
{
|
||||
source: "/api/:path*",
|
||||
destination: `${process.env.API_URL || "http://localhost:8080"}/:path*`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
Reference in New Issue
Block a user