build: split into 3 single-process images, drop nginx
Postiz upstream ships a single image bundling backend+frontend+orchestrator behind an in-container nginx multiplexer on :5000. We don't run nginx — ever — in our k8s stack. Replace with three single-process images: - ghcr.io/hanzoai/social-backend — NestJS, listens on :3000 - ghcr.io/hanzoai/social-frontend — Next.js SSR, listens on :4200 - ghcr.io/hanzoai/social-orchestrator — Temporal worker, no HTTP Dockerfile is multi-target (target=backend|frontend|orchestrator). One shared build stage runs pnpm install + pnpm run build, then three runtime stages COPY the built workspace and pick the right pnpm --filter at CMD. docker-publish.yml fans out a matrix across the three targets — same shared workflow, three published images. Deleted: Dockerfile.dev (nginx-bundled), var/docker/nginx.conf.
This commit is contained in:
@@ -16,10 +16,20 @@ on:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- image: ghcr.io/hanzoai/social-backend
|
||||
target: backend
|
||||
- image: ghcr.io/hanzoai/social-frontend
|
||||
target: frontend
|
||||
- image: ghcr.io/hanzoai/social-orchestrator
|
||||
target: orchestrator
|
||||
uses: hanzoai/.github/.github/workflows/docker-build.yml@main
|
||||
with:
|
||||
image: ghcr.io/hanzoai/social
|
||||
dockerfile: Dockerfile.dev
|
||||
image: ${{ matrix.image }}
|
||||
dockerfile: Dockerfile
|
||||
target: ${{ matrix.target }}
|
||||
platforms: linux/amd64
|
||||
runner-amd64: hanzo-build-linux-amd64
|
||||
build-args: |
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
# Hanzo Social — production multi-target build.
|
||||
#
|
||||
# Three runtime targets, one per app. No nginx, no pm2 — each container runs
|
||||
# a single Node process. Cluster ingress (hanzoai/ingress, traefik) does
|
||||
# the path-based routing across them.
|
||||
#
|
||||
# Build all three:
|
||||
# docker buildx build --target backend -t ghcr.io/hanzoai/social-backend .
|
||||
# docker buildx build --target frontend -t ghcr.io/hanzoai/social-frontend .
|
||||
# docker buildx build --target orchestrator -t ghcr.io/hanzoai/social-orchestrator .
|
||||
|
||||
ARG NODE_VERSION=22.20-bookworm-slim
|
||||
ARG NEXT_PUBLIC_VERSION=dev
|
||||
|
||||
# ─── Stage 1: build (shared across all three apps) ───────────────────
|
||||
FROM node:${NODE_VERSION} AS build
|
||||
ARG NEXT_PUBLIC_VERSION
|
||||
ENV NEXT_PUBLIC_VERSION=$NEXT_PUBLIC_VERSION
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends g++ make python3-pip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1
|
||||
|
||||
COPY . /app
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm run build
|
||||
|
||||
# ─── Stage 2a: backend (NestJS, port 3000) ───────────────────────────
|
||||
FROM node:${NODE_VERSION} AS backend
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app
|
||||
RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1
|
||||
COPY --from=build /app /app
|
||||
EXPOSE 3000
|
||||
# Run prisma db push on startup so schema drift is reconciled before serving.
|
||||
# (Postiz upstream pattern — see root package.json "pm2-run".)
|
||||
CMD ["sh", "-c", "pnpm run prisma-db-push && pnpm --filter ./apps/backend start"]
|
||||
|
||||
# ─── Stage 2b: frontend (Next.js SSR, port 4200) ─────────────────────
|
||||
FROM node:${NODE_VERSION} AS frontend
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app
|
||||
RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1
|
||||
COPY --from=build /app /app
|
||||
EXPOSE 4200
|
||||
CMD ["sh", "-c", "pnpm --filter ./apps/frontend start"]
|
||||
|
||||
# ─── Stage 2c: orchestrator (Temporal worker, no HTTP port) ──────────
|
||||
FROM node:${NODE_VERSION} AS orchestrator
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app
|
||||
RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1
|
||||
COPY --from=build /app /app
|
||||
CMD ["sh", "-c", "pnpm --filter ./apps/orchestrator start"]
|
||||
@@ -1,28 +0,0 @@
|
||||
FROM node:22.20-bookworm-slim
|
||||
ARG NEXT_PUBLIC_VERSION
|
||||
ENV NEXT_PUBLIC_VERSION=$NEXT_PUBLIC_VERSION
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
make \
|
||||
python3-pip \
|
||||
bash \
|
||||
nginx \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN addgroup --system www \
|
||||
&& adduser --system --ingroup www --home /www --shell /usr/sbin/nologin www \
|
||||
&& mkdir -p /www \
|
||||
&& chown -R www:www /www /var/lib/nginx
|
||||
|
||||
|
||||
RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1 pm2
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . /app
|
||||
COPY var/docker/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
RUN pnpm install
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm run build
|
||||
|
||||
CMD ["sh", "-c", "nginx && pnpm run pm2"]
|
||||
@@ -1,70 +0,0 @@
|
||||
user www;
|
||||
worker_processes auto; # it will be determinate automatically by the number of core
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
access_log /var/log/nginx/access.log;
|
||||
client_max_body_size 2G;
|
||||
server {
|
||||
listen 5000;
|
||||
server_name _;
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://localhost:3000/;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
proxy_set_header Reload $http_reload;
|
||||
proxy_set_header Onboarding $http_onboarding;
|
||||
proxy_set_header Activate $http_activate;
|
||||
proxy_set_header Auth $http_auth;
|
||||
proxy_set_header Showorg $http_showorg;
|
||||
proxy_set_header Impersonate $http_impersonate;
|
||||
proxy_set_header Accept-Language $http_accept_language;
|
||||
}
|
||||
|
||||
location /uploads/ {
|
||||
alias /uploads/;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Content-Security-Policy "default-src 'none'; img-src 'self'; media-src 'self'; style-src 'none'; script-src 'none'; frame-ancestors 'none'; sandbox" always;
|
||||
types {
|
||||
image/jpeg jpg jpeg;
|
||||
image/png png;
|
||||
image/gif gif;
|
||||
image/webp webp;
|
||||
image/avif avif;
|
||||
image/bmp bmp;
|
||||
image/tiff tif tiff;
|
||||
video/mp4 mp4;
|
||||
}
|
||||
default_type application/octet-stream;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:4200/;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
proxy_set_header Reload $http_reload;
|
||||
proxy_set_header Onboarding $http_onboarding;
|
||||
proxy_set_header Activate $http_activate;
|
||||
proxy_set_header Auth $http_auth;
|
||||
proxy_set_header Showorg $http_showorg;
|
||||
proxy_set_header Impersonate $http_impersonate;
|
||||
proxy_set_header Accept-Language $http_accept_language;
|
||||
proxy_set_header i18next $http_i18next;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user