build(newapi): 全容器化部署并添加 PostgreSQL 服务

This commit is contained in:
cnphpbb
2026-09-02 12:29:39 +08:00
parent 3ea11a9945
commit b1113a5c2c
2 changed files with 62 additions and 22 deletions
+15 -10
View File
@@ -8,15 +8,17 @@
# $EDITOR env.cfg # 填入真实密码/密钥后保存 # $EDITOR env.cfg # 填入真实密码/密钥后保存
# docker compose -p newapi --env-file ./env.cfg -f ./stack.yml up -d # docker compose -p newapi --env-file ./env.cfg -f ./stack.yml up -d
# #
# 前置:宿主机 PostgreSQL 建库建号(只需一次): # 说明:本栈为全容器化独立部署(new-api + Redis + PostgreSQL),
# sudo -u postgres psql -c "CREATE ROLE newapi LOGIN PASSWORD '<你的强密码>';" # 容器内 PostgreSQL 会自动初始化库和账号,无需在宿主机手动建库或配置 pg_hba。
# sudo -u postgres psql -c 'CREATE DATABASE new_api OWNER newapi;' # 容器 PG 未映射宿主机端口,不会与宿主机已有的 PostgreSQL 服务产生端口冲突。
# sudo -u postgres psql -c 'GRANT ALL PRIVILEGES ON DATABASE new_api TO newapi;'
# # PG < 13 若建表报权限错,补:GRANT ALL ON SCHEMA public TO newapi;
# #
# 注意:SQL_DSN / REDIS_CONN_STRING 为 URL 格式, # 注意:SQL_DSN / REDIS_CONN_STRING 为 URL 格式,
# 密码建议纯字母+数字,含 @ : / # 等字符时需做百分号转义 # 密码建议纯字母+数字,含 @ : / # 等字符时需做百分号转义
# ---------- 端口 ----------
# new-api Web 服务对外暴露端口
PORT=3000
# ---------- 镜像 ---------- # ---------- 镜像 ----------
# new-api 版本号(与 GitHub release tag 同名;拉取失败可回退 latest) # new-api 版本号(与 GitHub release tag 同名;拉取失败可回退 latest)
IMAGE_TAG_VER=v1.0.0-rc.30 IMAGE_TAG_VER=v1.0.0-rc.30
@@ -24,20 +26,23 @@ IMAGE_TAG_VER=v1.0.0-rc.30
IMAGE_TAG=calciumion/new-api:${IMAGE_TAG_VER} IMAGE_TAG=calciumion/new-api:${IMAGE_TAG_VER}
# Redis 镜像 # Redis 镜像
REDIS_IMAGE_TAG=redis:8.2 REDIS_IMAGE_TAG=redis:8.2
# PostgreSQL 镜像
PGSQL_IMAGE_TAG=postgres:16-alpine
# ---------- 数据卷 ---------- # ---------- 数据卷 ----------
# 宿主机持久化目录,挂载到容器 /data/app/logs # 宿主机持久化目录,挂载到容器 /data/app/logs、redis 数据以及 pgsql 数据
# 部署前手动创建:mkdir -pv /data/volumes/newapi/{data,logs} # 部署前手动创建:mkdir -pv /data/volumes/newapi/{data,logs,redis,pgsql_data}
Volumes_Path=/data/volumes/newapi Volumes_Path=/data/volumes/newapi
# ---------- 数据库(宿主机已有 PostgreSQL,建议 13+---------- # ---------- 数据库(容器内 PostgreSQL----------
DB_HOST=127.0.0.1 # 容器内网络互通,通过服务名 postgres 访问
DB_HOST=postgres
DB_PORT=5432 DB_PORT=5432
DB_NAME=new_api DB_NAME=new_api
DB_USER=newapi DB_USER=newapi
DB_PASSWORD=<your-strong-password> DB_PASSWORD=<your-strong-password>
# ---------- Redis本栈自建容器,host 网络,只绑 127.0.0.1---------- # ---------- Redis容器内 Redis----------
REDIS_PASSWORD=<your-strong-password> REDIS_PASSWORD=<your-strong-password>
# ---------- new-api 应用 ---------- # ---------- new-api 应用 ----------
+47 -12
View File
@@ -1,10 +1,10 @@
# path:: mkdir -pv /data/volumes/newapi/{data,logs} # path:: mkdir -pv /data/volumes/newapi/{data,logs,redis,pgsql_data}
# pull:: docker compose -p newapi --env-file ./newapi/env.cfg -f ./newapi/stack.yml pull # pull:: docker compose -p newapi --env-file ./newapi/env.cfg -f ./newapi/stack.yml pull
# run:: docker compose -p newapi --env-file ./newapi/env.cfg -f ./newapi/stack.yml up -d # run:: docker compose -p newapi --env-file ./newapi/env.cfg -f ./newapi/stack.yml up -d
# disc:: 数据库使用宿主机已有 PostgreSQL,需先建库建号(SQL 见 env.cfg.example),栈内不跑 PG # disc:: 全栈容器化部署:包含 new-api、Redis 缓存及 PostgreSQL 数据库
# disc:: new-api 与 redis 均为 host 网络:无 ports 映射,PG/Redis 经 127.0.0.1 直连, # disc:: 容器间处于自定义桥接网络 newapi 内,内部通过服务名 postgres:5432 / redis:6379 互通
# disc:: 宿主机 PG 保持默认 localhost 监听即可,无需改 listen_addresses / pg_hba.conf # disc:: 容器 PG 不暴露宿主机端口,与宿主机已有 PostgreSQL 服务互不冲突
# disc:: 第一个注册的账号自动成为管理员;公网只放行 80/4433000 由 Nginx/Caddy 反代,勿直接暴露 # disc:: 第一个注册的账号自动成为管理员;生产务必修改 env.cfg 中的全部密码
services: services:
newapi: newapi:
@@ -12,7 +12,13 @@ services:
container_name: newapi_app container_name: newapi_app
restart: always restart: always
command: --log-dir /app/logs command: --log-dir /app/logs
network_mode: host ports:
- "${PORT:-3000}:3000"
networks:
- newapi
depends_on:
- redis
- postgres
volumes: volumes:
- ${Volumes_Path}/data:/data - ${Volumes_Path}/data:/data
- ${Volumes_Path}/logs:/app/logs - ${Volumes_Path}/logs:/app/logs
@@ -22,18 +28,18 @@ services:
- SQL_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} - SQL_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}
# 本机无 TLS 的 PG 也可显式关闭 SSL: # 本机无 TLS 的 PG 也可显式关闭 SSL:
# - SQL_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable # - SQL_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable
- REDIS_CONN_STRING=redis://:${REDIS_PASSWORD}@127.0.0.1:6379 - REDIS_CONN_STRING=redis://:${REDIS_PASSWORD}@redis:6379
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
- BATCH_UPDATE_ENABLED=true - BATCH_UPDATE_ENABLED=true
- ERROR_LOG_ENABLED=true - ERROR_LOG_ENABLED=true
- NODE_NAME=${NODE_NAME} - NODE_NAME=${NODE_NAME}
- SESSION_SECRET=${SESSION_SECRET} - SESSION_SECRET=${SESSION_SECRET}
# 可选:独立日志库(PG 或 ClickHouse),不设则日志与业务同库 # 可选:独立日志库(PG 或 ClickHouse),不设则日志与业务同库
# - LOG_SQL_DSN=postgresql://user:pass@127.0.0.1:5432/new_api_log # - LOG_SQL_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/new_api_log
# 流式无响应超时(秒),默认 120,出现空补全时调大: # 流式无响应超时(秒),默认 120,出现空补全时调大:
# - STREAMING_TIMEOUT=300 # - STREAMING_TIMEOUT=300
healthcheck: healthcheck:
test: ["CMD-SHELL", "wget -q -O - http://localhost:3000/api/status > /dev/null || exit 1"] test: ["CMD-SHELL", "wget -q -O - http://127.0.0.1:3000/api/status > /dev/null || exit 1"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 3 retries: 3
@@ -42,11 +48,40 @@ services:
image: ${REDIS_IMAGE_TAG} image: ${REDIS_IMAGE_TAG}
container_name: newapi_redis container_name: newapi_redis
restart: always restart: always
network_mode: host networks:
# 宿主网络下只绑 127.0.0.1,外部无法直连;宿主机 6379 已被占用时先处理冲突 - newapi
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--bind", "127.0.0.1"] volumes:
- ${Volumes_Path}/redis:/data
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
healthcheck: healthcheck:
test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD} ping | grep -q PONG"] test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD} ping | grep -q PONG"]
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
postgres:
image: ${PGSQL_IMAGE_TAG}
container_name: newapi_pgsql
restart: always
shm_size: 256mb
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME}
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
- TZ=Asia/Shanghai
volumes:
- ${Volumes_Path}/pgsql_data:/var/lib/postgresql/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
networks:
- newapi
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
networks:
newapi:
driver: bridge