Files
Fizer Khan 77a88a64df fix login after signup
fix clickhouse issue.
2025-12-24 10:08:01 +05:30

274 lines
11 KiB
Docker

# =============================================================================
# NATS Console - All-in-One Docker Image (Multi-Stage Build)
# =============================================================================
# This Dockerfile creates a single image containing:
# - PostgreSQL 16
# - Redis 7
# - ClickHouse
# - NATS Server with JetStream
# - NATS Console (API, Web, Workers)
#
# Perfect for local development, demos, and trying out the application.
# For production, use docker-compose.prod.yml with separate services.
# =============================================================================
# =============================================================================
# Stage 1: Builder - Install dependencies and build applications
# =============================================================================
FROM node:20-slim AS builder
# Install pnpm
RUN npm install -g pnpm@9
WORKDIR /app
# Copy package files first for better caching
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
COPY apps/api/package.json ./apps/api/
COPY apps/web/package.json ./apps/web/
COPY apps/workers/package.json ./apps/workers/
COPY apps/shared/package.json ./apps/shared/
# Install all dependencies (including devDependencies for build)
RUN pnpm install --frozen-lockfile
# Copy source code
COPY apps/ ./apps/
# Generate Prisma client
RUN cd apps/api && pnpm prisma generate
# Build all applications
RUN pnpm run build
# Extract the generated Prisma client to a known location for copying
# pnpm stores it in node_modules/.pnpm/@prisma+client@*/node_modules/.prisma/client
RUN mkdir -p /prisma-client && \
cp -r node_modules/.pnpm/@prisma+client@*/node_modules/.prisma/client /prisma-client/
# =============================================================================
# Stage 2: Production Dependencies
# =============================================================================
FROM node:20-slim AS prod-deps
RUN npm install -g pnpm@9
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/api/package.json ./apps/api/
COPY apps/web/package.json ./apps/web/
COPY apps/workers/package.json ./apps/workers/
COPY apps/shared/package.json ./apps/shared/
# Install production dependencies with hoisted node_modules for ESM compatibility
# shamefully-hoist creates a flat node_modules structure similar to npm
RUN pnpm install --frozen-lockfile --prod --shamefully-hoist
# =============================================================================
# Stage 3: Runner - Final image with only built artifacts
# =============================================================================
FROM ubuntu:22.04 AS runner
LABEL maintainer="NATS Console Team"
LABEL description="All-in-One NATS JetStream Console with embedded databases"
# Prevent interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
# =============================================================================
# Install system dependencies
# =============================================================================
RUN apt-get update && apt-get install -y \
curl \
wget \
gnupg \
lsb-release \
ca-certificates \
supervisor \
postgresql-client \
redis-tools \
&& rm -rf /var/lib/apt/lists/*
# =============================================================================
# Install Node.js 20 (runtime only, no build tools needed)
# =============================================================================
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
# =============================================================================
# Install PostgreSQL 16
# =============================================================================
RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& apt-get update \
&& apt-get install -y postgresql-16 postgresql-contrib-16 \
&& rm -rf /var/lib/apt/lists/*
# =============================================================================
# Install Redis
# =============================================================================
RUN apt-get update && apt-get install -y redis-server \
&& rm -rf /var/lib/apt/lists/*
# =============================================================================
# Install ClickHouse
# =============================================================================
RUN apt-get update \
&& apt-get install -y apt-transport-https ca-certificates dirmngr \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8919F6BD2B48D754 \
&& echo "deb https://packages.clickhouse.com/deb stable main" | tee /etc/apt/sources.list.d/clickhouse.list \
&& apt-get update \
&& apt-get install -y clickhouse-server clickhouse-client \
&& rm -rf /var/lib/apt/lists/*
# =============================================================================
# Install NATS Server
# =============================================================================
ARG NATS_VERSION=2.10.22
RUN curl -L https://github.com/nats-io/nats-server/releases/download/v${NATS_VERSION}/nats-server-v${NATS_VERSION}-linux-amd64.tar.gz | tar xz \
&& mv nats-server-v${NATS_VERSION}-linux-amd64/nats-server /usr/local/bin/ \
&& rm -rf nats-server-v${NATS_VERSION}-linux-amd64
# =============================================================================
# Create directories
# =============================================================================
RUN mkdir -p /app \
/var/run/postgresql \
/var/lib/postgresql/data \
/var/lib/redis \
/var/lib/clickhouse \
/var/lib/nats \
/var/log/nats-console \
/docker-entrypoint-initdb.d
# Set ownership
RUN chown -R postgres:postgres /var/run/postgresql /var/lib/postgresql
RUN chown -R clickhouse:clickhouse /var/lib/clickhouse
RUN chown -R redis:redis /var/lib/redis
# =============================================================================
# Copy built applications from builder stage
# =============================================================================
WORKDIR /app
# Copy production node_modules first
COPY --from=prod-deps /app/node_modules ./node_modules
# Copy shared package (built)
COPY --from=builder /app/apps/shared/dist ./apps/shared/dist
COPY --from=builder /app/apps/shared/package.json ./apps/shared/
# Copy API (built only)
COPY --from=builder /app/apps/api/dist ./apps/api/dist
COPY --from=builder /app/apps/api/package.json ./apps/api/
COPY --from=builder /app/apps/api/prisma ./apps/api/prisma
# Copy Web (Next.js standalone build)
COPY --from=builder /app/apps/web/.next/standalone ./apps/web-standalone
COPY --from=builder /app/apps/web/.next/static ./apps/web-standalone/apps/web/.next/static
COPY --from=builder /app/apps/web/public ./apps/web-standalone/apps/web/public
# Copy Workers (built only)
COPY --from=builder /app/apps/workers/dist ./apps/workers/dist
COPY --from=builder /app/apps/workers/package.json ./apps/workers/
# Copy the generated Prisma client from builder (extracted to a known path)
# The client needs to be in the pnpm internal location where @prisma/client expects it
COPY --from=builder /prisma-client/client ./node_modules/.prisma/client
# Also copy to the pnpm internal .prisma location that @prisma/client references
# Find the @prisma/client location and copy .prisma/client there
RUN mkdir -p ./node_modules/.pnpm/@prisma+client@*/node_modules/.prisma && \
for dir in ./node_modules/.pnpm/@prisma+client@*/node_modules; do \
if [ -d "$dir" ]; then \
cp -r ./node_modules/.prisma "$dir/"; \
fi; \
done
# Copy package.json files for workspace resolution
COPY package.json pnpm-workspace.yaml ./
# Create symlinks so apps can find node_modules from root
RUN ln -s /app/node_modules /app/apps/api/node_modules && \
ln -s /app/node_modules /app/apps/workers/node_modules && \
ln -s /app/node_modules /app/apps/shared/node_modules
# =============================================================================
# Copy initialization scripts and configuration
# =============================================================================
COPY infrastructure/clickhouse/init/init.sql /docker-entrypoint-initdb.d/clickhouse-init.sql
COPY docker/scripts/entrypoint.sh /entrypoint.sh
COPY docker/scripts/init-databases.sh /init-databases.sh
COPY docker/scripts/wait-for-services.sh /wait-for-services.sh
RUN chmod +x /entrypoint.sh /init-databases.sh /wait-for-services.sh
# Configure supervisord
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# =============================================================================
# Environment variables
# =============================================================================
ENV NODE_ENV=production
ENV PORT=3001
ENV WEB_PORT=3000
ENV DATABASE_URL=postgresql://nats_console:nats_console@localhost:5432/nats_console
ENV REDIS_URL=redis://localhost:6379
ENV CLICKHOUSE_URL=http://localhost:8123
ENV CLICKHOUSE_DATABASE=nats_console
ENV CLICKHOUSE_USER=nats_console
ENV CLICKHOUSE_PASSWORD=nats_console_dev
ENV NATS_URL=nats://localhost:4222
ENV JWT_SECRET=change-me-in-production-use-secure-random-string
ENV JWT_EXPIRES_IN=15m
ENV JWT_REFRESH_EXPIRES_IN=7d
# CORS: Allow all origins in single-container mode (frontend proxies to API)
ENV CORS_ORIGIN=*
# API URL for Next.js rewrites (internal, same container)
ENV API_URL=http://localhost:3001
# Public API URL for client-side requests (can be overridden for external access)
ENV NEXT_PUBLIC_API_URL=/api/v1
# =============================================================================
# Expose ports
# =============================================================================
# Web UI
EXPOSE 3000
# API
EXPOSE 3001
# PostgreSQL
EXPOSE 5432
# Redis
EXPOSE 6379
# ClickHouse HTTP
EXPOSE 8123
# ClickHouse Native
EXPOSE 9000
# NATS
EXPOSE 4222
# NATS Monitoring
EXPOSE 8222
# =============================================================================
# Health check
# =============================================================================
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:3000 && curl -f http://localhost:3001/health || exit 1
# =============================================================================
# Volumes for data persistence
# =============================================================================
VOLUME ["/data"]
# =============================================================================
# Start all services
# =============================================================================
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]