背景
NewAPI 单个镜像默认不包含数据库,采用 SQLite 存储数据,并发性能较差。HuggingFace Spaces 提供 2 核 16G 的免费 Docker 容器,但仅支持开放一个端口。
解决方案:在 NewAPI 镜像基础上内嵌 PostgreSQL,实现数据库一体化部署,白嫖 HuggingFace 的免费服务。
项目文件
1. entrypoint.sh
#!/bin/bash
set -e
PG_VERSION=15
PG_BIN=/usr/lib/postgresql/$PG_VERSION/bin
PG_DATA=/data/pgdata
PG_LOG=/data/pgdata/pg.log
: "${POSTGRES_USER:=root}"
: "${POSTGRES_PASSWORD:=123456}"
: "${POSTGRES_DB:=new-api}"
: "${SQL_DSN:=postgresql://root:123456@localhost:5432/new-api}"
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
mkdir -p "$PG_DATA"
chown -R postgres:postgres "$PG_DATA"
if [ ! -f "$PG_DATA/PG_VERSION" ]; then
echo "Initializing PostgreSQL data directory..."
su postgres -c "$PG_BIN/initdb -D $PG_DATA --locale=en_US.UTF-8"
if [ ! -f "$PG_DATA/postgresql.conf" ]; then
echo "FATAL: initdb did not create postgresql.conf" >&2
exit 1
fi
cat > "$PG_DATA/pg_hba.conf" <<- EOHBA
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
EOHBA
fi
# 清理残留 PID 文件
if [ -f "$PG_DATA/postmaster.pid" ]; then
OLD_PID=$(head -1 "$PG_DATA/postmaster.pid")
if ! kill -0 "$OLD_PID" 2>/dev/null; then
echo "Removing stale PostgreSQL PID file (PID $OLD_PID)"
rm -f "$PG_DATA/postmaster.pid"
fi
fi
# 优化慢网络存储(HuggingFace Spaces 环境)
if ! grep -q "^fsync = off" "$PG_DATA/postgresql.conf" 2>/dev/null; then
echo "Applying PostgreSQL storage optimizations..."
cat >> "$PG_DATA/postgresql.conf" <<- EOF
fsync = off
full_page_writes = off
wal_level = minimal
max_wal_senders = 0
listen_addresses = 'localhost'
port = 5432
EOF
fi
echo "Starting PostgreSQL..."
su postgres -c "$PG_BIN/pg_ctl -D $PG_DATA -l $PG_LOG start"
# 等待 PostgreSQL 启动
for i in $(seq 1 600); do
if su postgres -c "$PG_BIN/pg_isready -q"; then
echo "PostgreSQL is ready."
break
fi
if [ "$i" -eq 600 ]; then
echo "=== PostgreSQL log (timeout) ==="
cat "$PG_LOG" 2>/dev/null || echo "(no log file)"
exit 1
fi
sleep 1
done
echo "Creating database user and database if needed..."
su postgres -c "$PG_BIN/psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='$POSTGRES_USER'"" | grep -q 1 || su postgres -c "$PG_BIN/psql -c "CREATE USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD'""
su postgres -c "$PG_BIN/psql -tAc "SELECT 1 FROM pg_database WHERE datname='$POSTGRES_DB'"" | grep -q 1 || su postgres -c "$PG_BIN/psql -c "CREATE DATABASE \"$POSTGRES_DB\" OWNER $POSTGRES_USER""
export SQL_DSN
cd /data
echo "Starting new-api..."
/new-api &
NEWAPI_PID=$!
cleanup() {
echo "Shutting down..."
kill $NEWAPI_PID 2>/dev/null || true
su postgres -c "$PG_BIN/pg_ctl -D $PG_DATA stop" || true
exit 0
}
trap cleanup SIGTERM SIGINT
wait $NEWAPI_PID
EXIT_CODE=$?
su postgres -c "$PG_BIN/pg_ctl -D $PG_DATA stop" || true
exit $EXIT_CODE
2. Dockerfile
FROM calciumion/new-api:v0.13.2
RUN apt-get update && \
apt-get install -y postgresql-15 locales && \
sed -i 's/^# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen && \
locale-gen && \
rm -rf /var/lib/apt/lists/* && \
pg_dropcluster 15 main && \
rm -rf /etc/postgresql/15
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENV POSTGRES_USER=root
ENV POSTGRES_PASSWORD=123456
ENV POSTGRES_DB=new-api
ENV SQL_DSN=postgresql://root:123456@localhost:5432/new-api
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
EXPOSE 3000
VOLUME ["/data"]
ENTRYPOINT ["/entrypoint.sh"]
HuggingFace Spaces 部署设置
在 Space 的 README.md 中配置:
app_port: 3000
- 端口:
3000(NewAPI Web 端口) - 数据持久化:
/data目录可以挂载 HuggingFace 的 Buckets 作为永久存储
部署步骤
- 在 HuggingFace 上创建新 Space,选择 Docker 运行时
- 上传
Dockerfile和entrypoint.sh到仓库根目录 - 配置
README.md中的app_port: 3000 - 等待自动构建完成
- Space 启动后,通过 HuggingFace 提供的 URL 访问 NewAPI 面板
优势
- 免费:HuggingFace 提供 2 核 16G 免费容器
- 高性能:PostgreSQL 替代 SQLite,并发性能大幅提升
- 一体化:无需额外数据库服务,单镜像包含全部组件
- 持久化:通过 HuggingFace Buckets 挂载
/data目录,数据不丢失
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧



暂无评论内容