You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
7.5 KiB
Docker

## Base image for all the stages
FROM node:22-slim AS base
ARG USE_CN_MIRROR
ENV DEBIAN_FRONTEND="noninteractive"
RUN \
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
fi \
# Add required package & update base package
&& apt update \
&& apt install busybox proxychains-ng -qy \
&& apt full-upgrade -qy \
&& apt autoremove -qy --purge \
&& apt clean -qy \
# Configure BusyBox
&& busybox --install -s \
# Add nextjs:nodejs to run the app
&& addgroup --system --gid 1001 nodejs \
&& adduser --system --home "/app" --gid 1001 -uid 1001 nextjs \
# Set permission for nextjs:nodejs
&& chown -R nextjs:nodejs "/etc/proxychains4.conf" \
# Cleanup temp files
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
## Builder image, install all the dependencies and build the app
FROM base AS builder
ARG USE_CN_MIRROR
ENV NEXT_PUBLIC_SERVICE_MODE="server" \
APP_URL="http://192.168.15.199:3210" \
DATABASE_DRIVER="node" \
DATABASE_URL="postgres://postgres:uWNZugjBqixf8dxC@localhost:5432/lobechat" \
KEY_VAULTS_SECRET="Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ="
# Sentry
ENV NEXT_PUBLIC_SENTRY_DSN="" \
SENTRY_ORG="" \
SENTRY_PROJECT=""
# Posthog
ENV NEXT_PUBLIC_ANALYTICS_POSTHOG="" \
NEXT_PUBLIC_POSTHOG_HOST="" \
NEXT_PUBLIC_POSTHOG_KEY=""
# Umami
ENV NEXT_PUBLIC_ANALYTICS_UMAMI="" \
NEXT_PUBLIC_UMAMI_SCRIPT_URL="" \
NEXT_PUBLIC_UMAMI_WEBSITE_ID=""
# Node
ENV NODE_OPTIONS="--max-old-space-size=8192"
WORKDIR /app
COPY package.json ./
COPY .npmrc ./
RUN \
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
export SENTRYCLI_CDNURL="https://npmmirror.com/mirrors/sentry-cli"; \
npm config set registry "https://registry.npmmirror.com/"; \
fi \
# Set the registry for corepack
&& export COREPACK_NPM_REGISTRY=$(npm config get registry | sed 's/\/$//') \
# Enable corepack
&& corepack enable \
# Use pnpm for corepack
&& corepack use $(sed -n 's/.*"packageManager": "\(.*\)".*/\1/p' package.json) \
# Install the dependencies
&& pnpm i \
# Add sharp and db migration dependencies
&& mkdir -p /deps \
&& pnpm add sharp pg drizzle-orm --prefix /deps
COPY . .
# run build standalone for docker version
RUN npm run build:docker
## Application image, copy all the files for production
FROM scratch AS app
COPY --from=builder /app/public /app/public
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder /app/.next/standalone /app/
COPY --from=builder /app/.next/static /app/.next/static
# copy dependencies
COPY --from=builder /deps/node_modules/.pnpm /app/node_modules/.pnpm
COPY --from=builder /deps/node_modules/pg /app/node_modules/pg
COPY --from=builder /deps/node_modules/drizzle-orm /app/node_modules/drizzle-orm
# Copy database migrations
COPY --from=builder /app/src/database/server/migrations /app/migrations
COPY --from=builder /app/scripts/migrateServerDB/docker.cjs /app/docker.cjs
COPY --from=builder /app/scripts/migrateServerDB/errorHint.js /app/errorHint.js
## Production image, copy all the files and run next
FROM base
# Copy all the files from app, set the correct permission for prerender cache
COPY --from=app --chown=nextjs:nodejs /app /app
ENV NODE_ENV="production" \
NODE_TLS_REJECT_UNAUTHORIZED=""
# set hostname to localhost
ENV HOSTNAME="192.168.15.199" \
PORT="3210"
# General Variables
ENV ACCESS_CODE="" \
APP_URL="http://192.168.15.199:3210" \
API_KEY_SELECT_MODE="" \
DEFAULT_AGENT_CONFIG="" \
SYSTEM_AGENT="" \
FEATURE_FLAGS="" \
PROXY_URL=""
# Database
ENV KEY_VAULTS_SECRET="Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=" \
DATABASE_DRIVER="node" \
DATABASE_URL="postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobechat"
# Next Auth
ENV NEXT_AUTH_SECRET="BIoLJoshK5E0R4BxLl4tkDedzIZkdyam/MB+vThTAT0=" \
NEXT_AUTH_SSO_PROVIDERS="casdoor" \
NEXTAUTH_URL="http://192.168.15.199:3210/api/auth"
# S3
ENV NEXT_PUBLIC_S3_DOMAIN="" \
S3_PUBLIC_DOMAIN="http://192.168.15.199:9000" \
S3_ACCESS_KEY_ID="soaucnP8Bip0TDdUjxng" \
S3_BUCKET="casdoor" \
S3_ENDPOINT="http://192.168.15.199:9000" \
S3_SECRET_ACCESS_KEY="ZPUzvY34umfcfxvWKSv0P00vczVMB6YmgJS5J9eO"
# Model Variables
ENV \
# AI21
AI21_API_KEY="" \
# Ai360
AI360_API_KEY="" \
# Anthropic
ANTHROPIC_API_KEY="" ANTHROPIC_PROXY_URL="" \
# Amazon Bedrock
AWS_ACCESS_KEY_ID="" AWS_SECRET_ACCESS_KEY="" AWS_REGION="" AWS_BEDROCK_MODEL_LIST="" \
# Azure OpenAI
AZURE_API_KEY="" AZURE_API_VERSION="" AZURE_ENDPOINT="" AZURE_MODEL_LIST="" \
# Baichuan
BAICHUAN_API_KEY="" \
# DeepSeek
DEEPSEEK_API_KEY="" \
# Fireworks AI
FIREWORKSAI_API_KEY="" FIREWORKSAI_MODEL_LIST="" \
# GitHub
GITHUB_TOKEN="" GITHUB_MODEL_LIST="" \
# Google
GOOGLE_API_KEY="" GOOGLE_PROXY_URL="" \
# Groq
GROQ_API_KEY="" GROQ_MODEL_LIST="" GROQ_PROXY_URL="" \
# Minimax
MINIMAX_API_KEY="" \
# Mistral
MISTRAL_API_KEY="" \
# Moonshot
MOONSHOT_API_KEY="" MOONSHOT_PROXY_URL="" \
# Novita
NOVITA_API_KEY="" NOVITA_MODEL_LIST="" \
# Ollama
OLLAMA_MODEL_LIST="" OLLAMA_PROXY_URL="" \
# OpenAI
OPENAI_API_KEY="" OPENAI_MODEL_LIST="" OPENAI_PROXY_URL="" \
# OpenRouter
OPENROUTER_API_KEY="" OPENROUTER_MODEL_LIST="" \
# Perplexity
PERPLEXITY_API_KEY="" PERPLEXITY_PROXY_URL="" \
# Qwen
QWEN_API_KEY="" QWEN_MODEL_LIST="" \
# SiliconCloud
SILICONCLOUD_API_KEY="" SILICONCLOUD_MODEL_LIST="" SILICONCLOUD_PROXY_URL="" \
# Spark
SPARK_API_KEY="" \
# Stepfun
STEPFUN_API_KEY="" \
# Taichu
TAICHU_API_KEY="" \
# TogetherAI
TOGETHERAI_API_KEY="" TOGETHERAI_MODEL_LIST="" \
# Upstage
UPSTAGE_API_KEY="" \
# 01.AI
ZEROONE_API_KEY="" ZEROONE_MODEL_LIST="" \
# Zhipu
ZHIPU_API_KEY=""
USER nextjs
EXPOSE 3210/tcp
CMD \
if [ -n "$PROXY_URL" ]; then \
# Set regex for IPv4
IP_REGEX="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$"; \
# Set proxychains command
PROXYCHAINS="proxychains -q"; \
# Parse the proxy URL
host_with_port="${PROXY_URL#*//}"; \
host="${host_with_port%%:*}"; \
port="${PROXY_URL##*:}"; \
protocol="${PROXY_URL%%://*}"; \
# Resolve to IP address if the host is a domain
if ! [[ "$host" =~ "$IP_REGEX" ]]; then \
nslookup=$(nslookup -q="A" "$host" | tail -n +3 | grep 'Address:'); \
if [ -n "$nslookup" ]; then \
host=$(echo "$nslookup" | tail -n 1 | awk '{print $2}'); \
fi; \
fi; \
# Generate proxychains configuration file
printf "%s\n" \
'localnet 127.0.0.0/255.0.0.0' \
'localnet ::1/128' \
'proxy_dns' \
'remote_dns_subnet 224' \
'strict_chain' \
'tcp_connect_time_out 8000' \
'tcp_read_time_out 15000' \
'[ProxyList]' \
"$protocol $host $port" \
> "/etc/proxychains4.conf"; \
fi; \
# Run migration
node "/app/docker.cjs"; \
if [ "$?" -eq "0" ]; then \
# Run the server
${PROXYCHAINS} node "/app/server.js"; \
fi;