Run Own Auth with Docker and Postgres
Own Auth runs inside the application container and stores authentication records in Postgres by default. The Compose setup below starts Postgres, applies the Own Auth migrations in a one-off container, and starts the backend only after the migration completes.
Build the application image
This Dockerfile installs dependencies, builds the TypeScript backend, removes development packages, and copies the compiled application into the runtime image.
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
RUN npm prune --omit=dev
FROM node:22-slim
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/package*.json ./
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
CMD ["node", "dist/server.js"]Run migrations before the application
services:
db:
image: postgres:17
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 5s
timeout: 5s
retries: 10
volumes:
- postgres-data:/var/lib/postgresql/data
migrate:
build: .
command: ["npx", "own-auth", "migrate"]
environment:
DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
depends_on:
db:
condition: service_healthy
app:
build: .
environment:
DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
OWN_AUTH_TOKEN_PEPPER: ${OWN_AUTH_TOKEN_PEPPER}
depends_on:
migrate:
condition: service_completed_successfully
ports:
- "3000:3000"
volumes:
postgres-data:The Postgres health check gates the migration container. The application starts only after npx own-auth migrate exits successfully. The postgres-data volume keeps Own Auth tables when the database container is replaced.
Start the stack
docker compose up --build