mirror of
https://github.com/R0m1k3/FlowReader.git
synced 2026-10-11 17:28:05 +02:00
chore(deploy): non-root image, reproducible builds, private database
- Dockerfile: Go 1.26, npm ci, go mod verify, non-root user, alpine 3.22. - Compose: Postgres no longer published on the host, password and new security settings read from .env, GOMEMLIMIT. - README: document new environment variables and reading shortcuts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
360f3cf012
commit
9eaed0aea4
5 files changed
+72
-27
No files matched your search
+4
-2
@@ -26,14 +26,16 @@
|
||||
Thumbs.db
|
||||
task.md
|
||||
|
||||
# Go
|
||||
# Go (go.sum is committed for reproducible, verified builds)
|
||||
vendor/
|
||||
go.sum
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# Tooling
|
||||
.playwright-mcp/
|
||||
|
||||
# FlowReader Specific
|
||||
/_bmad-output/tmp/
|
||||
+16
-15
@@ -1,32 +1,33 @@
|
||||
# Multi-stage Dockerfile for FlowReader
|
||||
|
||||
# Step 1: Build the React Frontend
|
||||
FROM node:20-alpine AS web-builder
|
||||
FROM node:22-alpine AS web-builder
|
||||
WORKDIR /app/web
|
||||
COPY web/package*.json ./
|
||||
RUN npm install
|
||||
# Reproducible install from the lockfile
|
||||
RUN npm ci --no-audit --no-fund
|
||||
COPY web/ ./
|
||||
RUN npm run build
|
||||
|
||||
# Step 2: Build the Go Backend
|
||||
FROM golang:1.24-alpine AS builder
|
||||
FROM golang:1.26-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN go mod tidy
|
||||
RUN go mod download
|
||||
# Copy the built frontend from Step 1
|
||||
COPY --from=web-builder /app/web/dist ./web/dist
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /server ./cmd/server
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download && go mod verify
|
||||
COPY cmd/ ./cmd/
|
||||
COPY internal/ ./internal/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-w -s" -o /server ./cmd/server
|
||||
|
||||
# Step 3: Final Production Image
|
||||
FROM alpine:3.19
|
||||
FROM alpine:3.22
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache wget ca-certificates
|
||||
RUN apk add --no-cache wget ca-certificates tzdata \
|
||||
&& adduser -D -H -u 10001 flowreader
|
||||
COPY --from=builder /server /app/server
|
||||
# Copy the static files for the Go server to serve
|
||||
COPY --from=builder /app/web/dist /app/web/dist
|
||||
# Copy migration files for auto-migration
|
||||
COPY --from=builder /app/migrations /app/migrations
|
||||
# Static frontend and migrations (read-only for the app user)
|
||||
COPY --from=web-builder /app/web/dist /app/web/dist
|
||||
COPY migrations /app/migrations
|
||||
|
||||
USER flowreader
|
||||
EXPOSE 8080
|
||||
CMD ["/app/server"]
|
||||
@@ -87,13 +87,30 @@ Un template dédié est fourni pour les utilisateurs d'Unraid.
|
||||
| `PORT` | Port du serveur | `8080` |
|
||||
| `DATABASE_URL` | Connexion PostgreSQL | `postgres://...` |
|
||||
| `OPENROUTER_API_KEY` | Clé pour les résumés IA | *(Optionnel)* |
|
||||
| `OPENROUTER_MODEL` | Modèle utilisé pour les résumés | `google/gemini-2.0-flash-001` |
|
||||
| `POSTGRES_PASSWORD` | Mot de passe PostgreSQL (compose, à mettre dans `.env`) | `flowreader` — **à changer** |
|
||||
| `REGISTRATION_ENABLED` | `false` pour fermer les inscriptions (le 1er compte, admin, reste possible) | `true` |
|
||||
| `TRUSTED_PROXIES` | IP/CIDR du reverse proxy (ex. `172.16.0.0/12`) pour le rate-limit par IP client | *(vide)* |
|
||||
| `COOKIE_SECURE` | Forcer le cookie `Secure` (HTTPS derrière proxy) | auto |
|
||||
| `WS_ALLOWED_ORIGINS` | Origines WebSocket supplémentaires | *(vide)* |
|
||||
|
||||
> 🔒 La base PostgreSQL n'est plus exposée sur l'hôte par défaut. Changez `POSTGRES_PASSWORD`
|
||||
> **avant** le premier démarrage (il n'est appliqué qu'à la création du volume).
|
||||
|
||||
### Lecture
|
||||
|
||||
- Raccourcis clavier : `j`/`k` naviguer, `o` ouvrir, `m` lu/non lu, `s` favori, `v` original,
|
||||
`/` rechercher, `u` non lus/tous, `r` actualiser, `Espace` page suivante puis article suivant,
|
||||
`?` aide.
|
||||
- Bouton **Aa** dans le lecteur : thème (clair, sépia, sombre, auto), police (serif, sans,
|
||||
Atkinson Hyperlegible), taille, interligne et largeur de colonne.
|
||||
|
||||
## 🛠️ Développement
|
||||
|
||||
Envie de mettre les mains dans le code ?
|
||||
|
||||
```bash
|
||||
# Pré-requis : Go 1.22+, Node 20+, Docker
|
||||
# Pré-requis : Go 1.26+, Node 22+, Docker
|
||||
|
||||
# 1. Lancer les services (DB)
|
||||
make docker-up
|
||||
|
||||
@@ -10,8 +10,19 @@ services:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- PORT=8080
|
||||
- DATABASE_URL=postgres://flowreader:flowreader@db:5432/flowreader?sslmode=disable
|
||||
- OPENROUTER_API_KEY=votre_clef_ici
|
||||
# Set a strong password in a .env file next to this compose file.
|
||||
# Note: POSTGRES_PASSWORD only applies when the volume is first created.
|
||||
- DATABASE_URL=postgres://flowreader:${POSTGRES_PASSWORD:-flowreader}@db:5432/flowreader?sslmode=disable
|
||||
# Close public sign-ups once your account exists (the first account is admin).
|
||||
- REGISTRATION_ENABLED=${REGISTRATION_ENABLED:-true}
|
||||
# Behind a reverse proxy (Traefik, NPM, Caddy…): its IP/CIDR, so rate
|
||||
# limiting sees real client IPs. Leave empty when exposed directly.
|
||||
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
|
||||
# Force Secure cookies when served over HTTPS behind a proxy.
|
||||
- COOKIE_SECURE=${COOKIE_SECURE:-}
|
||||
- GOMEMLIMIT=48MiB
|
||||
# Optional: AI summaries (OpenRouter). Leave empty to disable.
|
||||
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-}
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@@ -25,13 +36,15 @@ services:
|
||||
container_name: flowreader-db
|
||||
environment:
|
||||
- POSTGRES_USER=flowreader
|
||||
- POSTGRES_PASSWORD=flowreader
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-flowreader}
|
||||
- POSTGRES_DB=flowreader
|
||||
volumes:
|
||||
# Persistance des données sur Unraid (chemin typique)
|
||||
- /mnt/user/appdata/flowreader/postgres_data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
# Not published on the host: only the app container needs the database.
|
||||
# Uncomment for local debugging only (and bind to 127.0.0.1).
|
||||
# ports:
|
||||
# - "127.0.0.1:5432:5432"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U flowreader -d flowreader" ]
|
||||
|
||||
+16
-4
@@ -7,7 +7,17 @@ services:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- PORT=8080
|
||||
- DATABASE_URL=postgres://flowreader:flowreader@db:5432/flowreader?sslmode=disable
|
||||
# Set a strong password in a .env file next to this compose file.
|
||||
# Note: POSTGRES_PASSWORD only applies when the volume is first created.
|
||||
- DATABASE_URL=postgres://flowreader:${POSTGRES_PASSWORD:-flowreader}@db:5432/flowreader?sslmode=disable
|
||||
# Close public sign-ups once your account exists (the first account is admin).
|
||||
- REGISTRATION_ENABLED=${REGISTRATION_ENABLED:-true}
|
||||
# Behind a reverse proxy (Traefik, NPM, Caddy…): its IP/CIDR, so rate
|
||||
# limiting sees real client IPs. Leave empty when exposed directly.
|
||||
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
|
||||
# Force Secure cookies when served over HTTPS behind a proxy.
|
||||
- COOKIE_SECURE=${COOKIE_SECURE:-}
|
||||
- GOMEMLIMIT=48MiB
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@@ -27,12 +37,14 @@ services:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=flowreader
|
||||
- POSTGRES_PASSWORD=flowreader
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-flowreader}
|
||||
- POSTGRES_DB=flowreader
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
# Not published on the host: only the app container needs the database.
|
||||
# Uncomment for local debugging only (and bind to 127.0.0.1).
|
||||
# ports:
|
||||
# - "127.0.0.1:5432:5432"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U flowreader -d flowreader" ]
|
||||
|
||||
Reference in new issue
Block a user