feat: add Docker Compose deployment for backend/frontend/postgres
Backend Dockerfile runs drizzle-kit migrate on start, frontend serves the built Vite app via nginx and proxies /api to the backend container. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TBf3yfnnHzMQ5qhLV2285A
This commit is contained in:
1 parent
b38a5a4a57
commit
b5ac041c32
8 files changed
+123
No files matched your search
@@ -15,6 +15,9 @@ synapse/data/
|
||||
synapse/pgdata/
|
||||
!synapse/homeserver.yaml.sample
|
||||
|
||||
# talktime app stack runtime data (docker-compose.yml at repo root)
|
||||
/pgdata/
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
.env
|
||||
.env.local
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM node:22-alpine
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
ENV NODE_ENV=production
|
||||
EXPOSE 4000
|
||||
CMD ["sh", "-c", "npx drizzle-kit migrate && node dist/server.js"]
|
||||
@@ -0,0 +1,39 @@
|
||||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: talktime
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme}
|
||||
POSTGRES_DB: talktime
|
||||
volumes:
|
||||
- ./pgdata:/var/lib/postgresql/data
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
DATABASE_URL: postgresql://talktime:${DB_PASSWORD:-changeme}@db:5432/talktime
|
||||
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET must be set}
|
||||
PORT: 4000
|
||||
APP_BASE_URL: ${APP_BASE_URL:-http://localhost:8080}
|
||||
SYNAPSE_BASE_URL: ${SYNAPSE_BASE_URL}
|
||||
SYNAPSE_ADMIN_TOKEN: ${SYNAPSE_ADMIN_TOKEN}
|
||||
SYNAPSE_SERVER_NAME: ${SYNAPSE_SERVER_NAME}
|
||||
SMTP_HOST: ${SMTP_HOST:-}
|
||||
SMTP_PORT: ${SMTP_PORT:-587}
|
||||
SMTP_USER: ${SMTP_USER:-}
|
||||
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
|
||||
MAIL_FROM: ${MAIL_FROM:-TalkTime <no-reply@talktime.local>}
|
||||
ports:
|
||||
- "4000:4000"
|
||||
|
||||
frontend:
|
||||
build: ./frontend
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
- "8080:80"
|
||||
@@ -0,0 +1,34 @@
|
||||
# Deployment
|
||||
|
||||
## Lokal / Server mit Docker Compose
|
||||
|
||||
Voraussetzung: Synapse läuft bereits (siehe `synapse/README.md`), Admin-Token liegt vor.
|
||||
|
||||
```bash
|
||||
export DB_PASSWORD=<starkes-passwort>
|
||||
export JWT_SECRET=<langer-zufalls-string>
|
||||
export APP_BASE_URL=http://localhost:8080
|
||||
export SYNAPSE_BASE_URL=http://<synapse-host>:8008
|
||||
export SYNAPSE_ADMIN_TOKEN=<token>
|
||||
export SYNAPSE_SERVER_NAME=chat.talktime.local
|
||||
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Startet:
|
||||
- `db` — PostgreSQL 16, Daten in `./pgdata`
|
||||
- `backend` — Fastify-API, migriert die DB beim Start automatisch (`drizzle-kit migrate`), Port 4000
|
||||
- `frontend` — gebautes Vite-Frontend hinter nginx, proxied `/api/*` zu `backend:4000`, Port 8080
|
||||
|
||||
App danach unter `http://localhost:8080` erreichbar.
|
||||
|
||||
## Produktivbetrieb
|
||||
|
||||
- Reverse Proxy (nginx/Caddy) terminiert TLS vor Port 8080 (frontend) und ggf. Synapse (8008/8448) — Ports nicht direkt exponieren.
|
||||
- `.env`-Datei statt `export` nutzen (nicht committen), Secrets nie in Git.
|
||||
- Backups: `pgdata/`-Volume (App-DB) und Synapse-eigene Postgres-DB regelmäßig sichern (`pg_dump`).
|
||||
- Updates: `git pull && docker compose up -d --build`.
|
||||
|
||||
## Environment-Variablen (Backend)
|
||||
|
||||
Siehe `backend/.env.example` für die vollständige Liste (lokal ohne Docker) bzw. oben für Compose.
|
||||
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
.env
|
||||
.env.local
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM node:22-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.27-alpine
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,18 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:4000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user