chore(docker): Update Docker deployment guide and workflow configurations

This commit is contained in:
Fatih Kadir Akın
2026-01-05 23:41:03 +03:00
parent 1d0926eac1
commit ad59ae3ebb
9 changed files with 274 additions and 462 deletions
+19 -117
View File
@@ -1,107 +1,22 @@
# prompts.chat All-in-One Docker Image
# Contains Node.js + PostgreSQL for single-container deployment
# prompts.chat Bootstrap Docker Image
# Lightweight image that clones and builds on first run
#
# Usage:
# docker build -t my-prompts .
# docker build --build-arg BRAND_NAME="My App" --build-arg BRAND_COLOR="#ff0000" -t my-prompts .
# docker run -p 80:80 my-prompts
#
# Build Arguments (all optional):
# BRAND_NAME, BRAND_DESCRIPTION, BRAND_LOGO, BRAND_COLOR
# AUTH_PROVIDERS (comma-separated: github,google,credentials)
# LOCALES (comma-separated: en,es,fr)
# docker run -p 80:80 -v prompts-data:/data ghcr.io/f/prompts.chat
# docker run -p 80:80 -v prompts-data:/data -e PCHAT_NAME="My App" ghcr.io/f/prompts.chat
FROM node:24-bookworm-slim AS builder
# Build arguments for whitelabel branding
ARG BRAND_NAME="My Prompt Library"
ARG BRAND_DESCRIPTION="Collect, organize, and share AI prompts"
ARG BRAND_LOGO="/logo.svg"
ARG BRAND_LOGO_DARK=""
ARG BRAND_FAVICON="/logo.svg"
ARG BRAND_COLOR="#6366f1"
ARG THEME_RADIUS="sm"
ARG THEME_VARIANT="default"
ARG THEME_DENSITY="default"
ARG AUTH_PROVIDERS="credentials"
ARG ALLOW_REGISTRATION="true"
ARG LOCALES="en"
ARG DEFAULT_LOCALE="en"
ARG FEATURE_PRIVATE_PROMPTS="true"
ARG FEATURE_CHANGE_REQUESTS="true"
ARG FEATURE_CATEGORIES="true"
ARG FEATURE_TAGS="true"
ARG FEATURE_COMMENTS="true"
ARG FEATURE_AI_SEARCH="false"
ARG FEATURE_AI_GENERATION="false"
ARG FEATURE_MCP="false"
WORKDIR /app
# Copy package files first for better caching
COPY package.json package-lock.json ./
COPY prisma ./prisma/
# Install all dependencies (including dev for build)
RUN npm ci
# Copy application files
COPY . .
# Remove unnecessary files
RUN rm -rf .github .claude packages .git
# Run docker-setup.js to generate prompts.config.ts with branding
ENV BRAND_NAME=${BRAND_NAME}
ENV BRAND_DESCRIPTION=${BRAND_DESCRIPTION}
ENV BRAND_LOGO=${BRAND_LOGO}
ENV BRAND_LOGO_DARK=${BRAND_LOGO_DARK}
ENV BRAND_FAVICON=${BRAND_FAVICON}
ENV BRAND_COLOR=${BRAND_COLOR}
ENV THEME_RADIUS=${THEME_RADIUS}
ENV THEME_VARIANT=${THEME_VARIANT}
ENV THEME_DENSITY=${THEME_DENSITY}
ENV AUTH_PROVIDERS=${AUTH_PROVIDERS}
ENV ALLOW_REGISTRATION=${ALLOW_REGISTRATION}
ENV LOCALES=${LOCALES}
ENV DEFAULT_LOCALE=${DEFAULT_LOCALE}
ENV FEATURE_PRIVATE_PROMPTS=${FEATURE_PRIVATE_PROMPTS}
ENV FEATURE_CHANGE_REQUESTS=${FEATURE_CHANGE_REQUESTS}
ENV FEATURE_CATEGORIES=${FEATURE_CATEGORIES}
ENV FEATURE_TAGS=${FEATURE_TAGS}
ENV FEATURE_COMMENTS=${FEATURE_COMMENTS}
ENV FEATURE_AI_SEARCH=${FEATURE_AI_SEARCH}
ENV FEATURE_AI_GENERATION=${FEATURE_AI_GENERATION}
ENV FEATURE_MCP=${FEATURE_MCP}
RUN node scripts/docker-setup.js
# Generate Prisma client and build
# DATABASE_URL is needed at build time for Prisma, but not used
ENV NEXT_TELEMETRY_DISABLED=1
ENV DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy"
RUN npx prisma generate && npm run build
# Production image
FROM node:24-bookworm-slim
# Labels for GitHub Container Registry
LABEL org.opencontainers.image.source="https://github.com/f/awesome-chatgpt-prompts"
LABEL org.opencontainers.image.description="prompts.chat - Self-hosted AI prompt library"
LABEL org.opencontainers.image.licenses="MIT"
# Environment variables
ENV DEBIAN_FRONTEND=noninteractive
ENV NODE_ENV=production
ENV PORT=80
ENV HOSTNAME="0.0.0.0"
ENV DATABASE_URL="postgresql://prompts:prompts@localhost:5432/prompts?schema=public"
# Install PostgreSQL, supervisor, and utilities
# Install PostgreSQL, git, and utilities
RUN apt-get update && apt-get install -y --no-install-recommends \
postgresql-15 \
postgresql-contrib-15 \
supervisor \
git \
curl \
openssl \
ca-certificates \
@@ -109,38 +24,25 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& mkdir -p /var/run/postgresql /var/log/supervisor \
&& chown -R postgres:postgres /var/run/postgresql
# Create directories
WORKDIR /app
RUN mkdir -p /data/postgres /data/app && chown -R postgres:postgres /data/postgres
# Copy built application from builder
COPY --from=builder /app/public ./public
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/prompts.csv ./prompts.csv
COPY --from=builder /app/messages ./messages
COPY --from=builder /app/prompts.config.ts ./prompts.config.ts
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
# Copy node_modules for prisma CLI (needed for migrations)
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma
COPY --from=builder /app/node_modules/prisma ./node_modules/prisma
# Copy Docker configuration files
# Copy bootstrap scripts
COPY docker/bootstrap.sh /bootstrap.sh
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
RUN chmod +x /bootstrap.sh
# Create data directory for PostgreSQL
RUN mkdir -p /data/postgres && chown -R postgres:postgres /data/postgres
# Environment defaults
ENV NODE_ENV=production
ENV PORT=80
ENV HOSTNAME="0.0.0.0"
ENV DATABASE_URL="postgresql://prompts:prompts@localhost:5432/prompts?schema=public"
ENV REPO_URL="https://github.com/f/awesome-chatgpt-prompts.git"
# Expose port
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
HEALTHCHECK --interval=30s --timeout=10s --start-period=180s --retries=3 \
CMD curl -f http://localhost:80/api/health || exit 1
# Entrypoint
ENTRYPOINT ["/entrypoint.sh"]
CMD []
ENTRYPOINT ["/bootstrap.sh"]
-101
View File
@@ -1,101 +0,0 @@
# prompts.chat App-Only Dockerfile
# For use with docker-compose (separate database container)
#
# Build with branding:
# docker build --build-arg BRAND_NAME="My App" -f docker/Dockerfile.app -t my-prompts .
FROM node:24-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Copy package files
COPY package.json package-lock.json ./
COPY prisma ./prisma/
# Install dependencies
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
# Build arguments for whitelabel branding
ARG BRAND_NAME="My Prompt Library"
ARG BRAND_DESCRIPTION="Collect, organize, and share AI prompts"
ARG BRAND_LOGO="/logo.svg"
ARG BRAND_LOGO_DARK=""
ARG BRAND_FAVICON="/logo.svg"
ARG BRAND_COLOR="#6366f1"
ARG THEME_RADIUS="sm"
ARG THEME_VARIANT="default"
ARG AUTH_PROVIDERS="credentials"
ARG LOCALES="en"
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Remove unnecessary files
RUN rm -rf .github .claude packages docker .git
# Run docker-setup.js to generate prompts.config.ts with branding
ENV BRAND_NAME=${BRAND_NAME} \
BRAND_DESCRIPTION=${BRAND_DESCRIPTION} \
BRAND_LOGO=${BRAND_LOGO} \
BRAND_LOGO_DARK=${BRAND_LOGO_DARK} \
BRAND_FAVICON=${BRAND_FAVICON} \
BRAND_COLOR=${BRAND_COLOR} \
THEME_RADIUS=${THEME_RADIUS} \
THEME_VARIANT=${THEME_VARIANT} \
AUTH_PROVIDERS=${AUTH_PROVIDERS} \
LOCALES=${LOCALES}
RUN node scripts/docker-setup.js
# DATABASE_URL is needed at build time for Prisma, but not used
ENV NEXT_TELEMETRY_DISABLED=1
ENV DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy"
# Generate Prisma client
RUN npx prisma generate
# Build Next.js
RUN npm run build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# Install netcat for health checks
RUN apk add --no-cache netcat-openbsd curl
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy built files
COPY --from=builder /app/public ./public
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/prompts.csv ./prompts.csv
# Copy standalone build
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Copy entrypoint
COPY docker/entrypoint-app.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENTRYPOINT ["/entrypoint.sh"]
CMD ["node", "server.js"]
+73 -34
View File
@@ -9,25 +9,28 @@ echo "║ ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo ""
# Generate AUTH_SECRET if not provided
if [ -z "$AUTH_SECRET" ]; then
export AUTH_SECRET=$(openssl rand -base64 32)
echo "⚠ AUTH_SECRET not provided, generated random secret"
echo " For production, set AUTH_SECRET environment variable"
fi
# PostgreSQL paths
# Paths
APP_DIR="/data/app"
PGDATA="/data/postgres"
PGBIN="/usr/lib/postgresql/15/bin"
BUILD_MARKER="/data/.built"
# Initialize PostgreSQL data directory if needed
# Generate AUTH_SECRET if not provided
if [ -z "$AUTH_SECRET" ]; then
if [ -f "/data/.auth_secret" ]; then
export AUTH_SECRET=$(cat /data/.auth_secret)
else
export AUTH_SECRET=$(openssl rand -base64 32)
echo "$AUTH_SECRET" > /data/.auth_secret
echo "⚠ AUTH_SECRET generated and saved"
fi
fi
# Initialize PostgreSQL if needed
if [ ! -f "$PGDATA/PG_VERSION" ]; then
echo "▶ Initializing PostgreSQL database..."
# Initialize PostgreSQL
echo "▶ Initializing PostgreSQL..."
su postgres -c "$PGBIN/initdb -D $PGDATA"
# Configure PostgreSQL
cat >> "$PGDATA/postgresql.conf" << EOF
listen_addresses = 'localhost'
port = 5432
@@ -35,34 +38,77 @@ max_connections = 100
shared_buffers = 128MB
EOF
# Configure authentication
cat > "$PGDATA/pg_hba.conf" << EOF
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
EOF
# Start PostgreSQL temporarily to create database
su postgres -c "$PGBIN/pg_ctl -D $PGDATA -l /tmp/pg.log start"
sleep 3
# Create database and user
su postgres -c "$PGBIN/createuser -s prompts 2>/dev/null" || true
su postgres -c "$PGBIN/createdb -O prompts prompts 2>/dev/null" || true
# Stop PostgreSQL (supervisor will start it)
su postgres -c "$PGBIN/pg_ctl -D $PGDATA stop"
sleep 2
echo "✓ PostgreSQL initialized"
fi
# Clone and build on first run
if [ ! -f "$BUILD_MARKER" ]; then
echo ""
echo "▶ First run detected - building prompts.chat..."
echo ""
# Clone repository
if [ ! -d "$APP_DIR/.git" ]; then
echo "▶ Cloning repository..."
rm -rf "$APP_DIR"
git clone --depth 1 "$REPO_URL" "$APP_DIR"
echo "✓ Repository cloned"
fi
cd "$APP_DIR"
# Clean up unnecessary files
rm -rf .github .claude packages .git
# Install dependencies
echo "▶ Installing dependencies..."
npm ci
echo "✓ Dependencies installed"
# Run docker-setup.js to generate config with branding
echo "▶ Generating configuration..."
node scripts/docker-setup.js
echo "✓ Configuration generated"
# Generate Prisma client
echo "▶ Generating Prisma client..."
npx prisma generate
echo "✓ Prisma client generated"
# Build Next.js
echo "▶ Building Next.js application (this may take a few minutes)..."
npm run build
echo "✓ Build complete"
# Mark as built
touch "$BUILD_MARKER"
echo ""
echo "✅ Build complete! Starting application..."
echo ""
else
echo "✓ Using existing build"
cd "$APP_DIR"
fi
# Start supervisor (manages PostgreSQL and Next.js)
echo "▶ Starting services..."
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf &
SUPERVISOR_PID=$!
# Wait for PostgreSQL to be ready
# Wait for PostgreSQL
echo "▶ Waiting for PostgreSQL..."
for i in $(seq 1 30); do
if $PGBIN/pg_isready -h localhost -p 5432 >/dev/null 2>&1; then
@@ -76,23 +122,17 @@ for i in $(seq 1 30); do
sleep 1
done
# Run database migrations
# Run migrations
echo "▶ Running database migrations..."
cd /app
./node_modules/prisma/build/index.js migrate deploy
npx prisma migrate deploy
echo "✓ Migrations complete"
# Seed database if empty (check if Prompt table exists and has data)
# Seed if empty
PROMPT_COUNT=$(su postgres -c "$PGBIN/psql -h localhost -U prompts -d prompts -t -c \"SELECT COUNT(*) FROM \\\"Prompt\\\"\"" 2>/dev/null | tr -d ' ' || echo "0")
if [ "$PROMPT_COUNT" = "0" ] || [ -z "$PROMPT_COUNT" ]; then
echo "▶ Seeding database with prompts..."
# Run seed script if available
if [ -f "/app/prisma/seed.ts" ]; then
npx tsx /app/prisma/seed.ts || echo "⚠ Seeding skipped or failed"
fi
echo "✓ Database seeded"
else
echo "✓ Database already has $PROMPT_COUNT prompts"
echo "▶ Seeding database..."
npx tsx prisma/seed.ts 2>/dev/null || echo "⚠ Seeding skipped"
echo "✓ Database ready"
fi
echo ""
@@ -105,5 +145,4 @@ echo "║ ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo ""
# Keep container running and forward signals
wait $SUPERVISOR_PID
-24
View File
@@ -1,24 +0,0 @@
#!/bin/sh
set -e
echo "🚀 Starting prompts.chat..."
# Wait for database to be ready
echo "⏳ Waiting for database..."
until nc -z ${DATABASE_HOST:-db} ${DATABASE_PORT:-5432}; do
sleep 1
done
echo "✅ Database is ready"
# Run migrations
echo "📦 Running database migrations..."
npx prisma migrate deploy
# Check if database needs seeding
echo "🌱 Checking database..."
# Skip seed check in entrypoint, let the app handle it
echo "✨ prompts.chat is starting on port ${PORT:-3000}"
# Execute the main command
exec "$@"
+2 -2
View File
@@ -15,8 +15,8 @@ stdout_logfile=/var/log/supervisor/postgresql.log
stderr_logfile=/var/log/supervisor/postgresql-error.log
[program:nextjs]
command=node /app/server.js
directory=/app
command=node /data/app/.next/standalone/server.js
directory=/data/app
user=root
autostart=true
autorestart=true