File size: 4,403 Bytes
7c447a5 e8997ce 7c447a5 e8997ce 7c447a5 e8997ce 7c447a5 e8997ce 7c447a5 d02be95 e8997ce 7c447a5 e8997ce 7c447a5 e8997ce 7c447a5 e8997ce 17c5c69 18362b0 e8cf564 97a31eb 7c447a5 e8997ce cf579a5 7c447a5 e8997ce e8cf564 18362b0 cf579a5 17c5c69 cf579a5 7c447a5 e8997ce cf579a5 e8997ce 7c447a5 cf579a5 7c447a5 18362b0 cf579a5 8b951c1 17c5c69 cf579a5 17c5c69 cf579a5 7c447a5 8b951c1 17c5c69 7c447a5 cf579a5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# ---------- Frontend build ----------
FROM node:20-bullseye AS fe
WORKDIR /app/frontend
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm run build
# ---------- Backend build (build venv only) ----------
FROM python:3.11-slim AS be
ENV PIP_NO_CACHE_DIR=1 PYTHONUNBUFFERED=1 PIP_PREFER_BINARY=1
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential gcc g++ gfortran make pkg-config \
libopenblas-dev liblapack-dev git \
&& rm -rf /var/lib/apt/lists/*
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:${PATH}"
RUN python -m pip install --upgrade pip setuptools wheel
RUN pip install --index-url https://download.pytorch.org/whl/cpu "torch==2.3.1"
RUN pip install --no-cache-dir safetensors accelerate
COPY backend/requirements.txt ./backend/requirements.txt
RUN sed -i 's/^[Tt]orch[[:space:]=<>!].*/# torch pinned separately (CPU)/' backend/requirements.txt || true
RUN pip install --only-binary=:all: blis || echo "Precompiled blis not available"
RUN pip install -r backend/requirements.txt || pip install -r backend/requirements.txt --no-deps
RUN pip install --no-cache-dir gunicorn
COPY backend/ ./backend/
# ---------- Runtime ----------
FROM python:3.11-slim AS runtime
ENV PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1 PORT=7860 \
PATH="/opt/venv/bin:${PATH}" \
MPLCONFIGDIR=/tmp
ENV HOME=/tmp \
XDG_CACHE_HOME=/tmp/.cache \
HF_HOME=/tmp/.cache/huggingface \
HF_HUB_CACHE=/tmp/.cache/huggingface/hub \
HF_DATASETS_CACHE=/tmp/.cache/huggingface/datasets \
TRANSFORMERS_CACHE=/tmp/.cache/huggingface/transformers \
MPLCONFIGDIR=/tmp
RUN mkdir -p /tmp/huggingface /tmp/transformers /tmp/hub /tmp/datasets
WORKDIR /app
# 依賴
RUN apt-get update && apt-get install -y --no-install-recommends \
nginx supervisor ca-certificates \
libgomp1 libopenblas0 \
&& rm -rf /var/lib/apt/lists/*
RUN install -d -m 0777 \
/tmp/.cache \
/tmp/.cache/huggingface/hub \
/tmp/.cache/huggingface/datasets \
/tmp/.cache/huggingface/transformers \
/tmp/nginx/client_body /tmp/nginx/proxy /tmp/nginx/fastcgi /tmp/nginx/uwsgi /tmp/nginx/scgi
# 建立可寫暫存
RUN mkdir -p /tmp/nginx/client_body /tmp/nginx/proxy /tmp/nginx/fastcgi /tmp/nginx/uwsgi /tmp/nginx/scgi \
/tmp/matplotlib
# 前端
COPY --from=fe /app/frontend/dist /usr/share/nginx/html
# venv + 後端
COPY --from=be /opt/venv /opt/venv
COPY --from=be /app/backend /app/backend
# nginx 主設定
COPY nginx.conf.template /etc/nginx/nginx.conf
RUN printf "access_log /dev/stdout;\nerror_log /dev/stderr info;\n" \
> /etc/nginx/conf.d/log_to_stdout.conf
# 放一個 http 級別的 drop-in,避免高風險 sed
RUN printf "client_max_body_size 100M;\nclient_body_temp_path /tmp/nginx/client_body;\nproxy_temp_path /tmp/nginx/proxy;\nfastcgi_temp_path /tmp/nginx/fastcgi;\nuwsgi_temp_path /tmp/nginx/uwsgi;\nscgi_temp_path /tmp/nginx/scgi;\n" \
> /etc/nginx/conf.d/temp_paths.conf
# 調整 nginx.conf:移除 user;設定 pid;在 http{} 內包含 conf.d
RUN set -eux; \
sed -ri 's/^\s*user\s+[^;]+;//g' /etc/nginx/nginx.conf || true; \
if grep -qE '^\s*pid\s+' /etc/nginx/nginx.conf; then \
sed -ri 's|^\s*pid\s+[^;]+;|pid /tmp/nginx.pid;|' /etc/nginx/nginx.conf; \
else \
sed -ri '1i pid /tmp/nginx.pid;' /etc/nginx/nginx.conf; \
fi; \
if ! grep -q 'include /etc/nginx/conf.d/\*.conf;' /etc/nginx/nginx.conf; then \
sed -ri 's|(^\s*include\s+/etc/nginx/mime\.types;)|\1\n include /etc/nginx/conf.d/*.conf;|' /etc/nginx/nginx.conf; \
fi
# supervisor 設定:pidfile 放 /tmp;不要 user=
RUN mkdir -p /etc/supervisor/conf.d && \
printf "[program:api]\n\
command=gunicorn --workers 2 --threads 8 --timeout 0 --chdir /app/backend -b 0.0.0.0:5001 server:app\n\
priority=10\nautostart=true\nautorestart=true\n\
stdout_logfile=/dev/stdout\nstderr_logfile=/dev/stderr\n\
stdout_logfile_maxbytes=0\nstderr_logfile_maxbytes=0\n\n\
[program:nginx]\n\
command=nginx -g \"daemon off;\"\n\
priority=20\nautostart=true\nautorestart=true\n\
stdout_logfile=/dev/stdout\nstderr_logfile=/dev/stderr\n\
stdout_logfile_maxbytes=0\nstderr_logfile_maxbytes=0\n\n\
[supervisord]\n\
logfile=/dev/stdout\nlogfile_maxbytes=0\n\
pidfile=/tmp/supervisord.pid\n\
nodaemon=true\n" \
> /etc/supervisor/conf.d/app.conf
EXPOSE 7860
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/app.conf"]
|