22 06 2026

newapi单个镜像不含数据库,默认是采用sqlite存储数据,并发性能差,huggingface平台提供2h16g的免费docker,但是仅支持开放一个端口。

那么为什么不能在newapi原本的镜像基础上,加装一个数据库,这样就可以白嫖huggingface的服务了。

说干就干,直接上代码,新建一个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.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" << EOF
local   all   all   trust
host    all   all   127.0.0.1/32   md5
host    all   all   ::1/128        md5
EOF
fi

# Remove stale PID file from previous run
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

# Optimize for slow network storage (Hugging Face 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
synchronous_commit = off
full_page_writes = off
EOF
fi

# Fix permissions on every start
chown -R postgres:postgres "$PG_DATA"
chmod 0700 "$PG_DATA"

# Recreate missing critical directories (HF persistent storage may lose them on restart)
for dir in base global pg_commit_ts pg_dynshmem pg_logical pg_logical/snapshots pg_logical/mappings pg_multixact/members pg_multixact/offsets pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_wal/archive_status pg_wal/summaries; do
    if [ ! -d "$PG_DATA/$dir" ]; then
        echo "Recreating missing directory: $dir"
        mkdir -p "$PG_DATA/$dir"
    fi
done
chown -R postgres:postgres "$PG_DATA"

rm -f "$PG_LOG"

echo "Starting PostgreSQL..."
su postgres -c "$PG_BIN/pg_ctl -D $PG_DATA -l $PG_LOG start" || {
    echo "=== PostgreSQL log ==="
    cat "$PG_LOG" 2>/dev/null || echo "(no log file)"
    exit 1
}

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

然后新建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.UTF-8
ENV LC_ALL=en_US.UTF-8

EXPOSE 3000

VOLUME ["/data"]

ENTRYPOINT ["/entrypoint.sh"]记得修改readme文件端口app_port: 3000,数据文件在/data,可以挂载buckets作为永久存储。

  1. 上一篇:利用huggingface space的高配免费容器创建各种玩具
  2. 下一篇:通过cname优选域名/IP接入cloudflare
评论
暂无回帖!赶紧来抢占沙发吧!