File size: 3,818 Bytes
0df77ff
 
 
0c0d5e5
7ce37bf
61e7c18
 
0c0d5e5
 
0df77ff
7ce37bf
0df77ff
 
 
 
0c0d5e5
22d5035
7e4b3da
0df77ff
22d5035
0df77ff
22d5035
 
 
 
116ec26
0df77ff
 
 
 
b563962
22d5035
0df77ff
 
22d5035
b563962
0df77ff
22d5035
0df77ff
 
22d5035
7ce37bf
0df77ff
 
 
0c0d5e5
 
61e7c18
4680b44
0c0d5e5
 
 
 
22d5035
0c0d5e5
0df77ff
 
 
 
 
22d5035
4680b44
0c0d5e5
 
0df77ff
 
 
a4bef0b
496ca32
0df77ff
443bf8a
 
0df77ff
4680b44
0c0d5e5
a4bef0b
 
22d5035
0c0d5e5
496ca32
0df77ff
0404cc9
61e7c18
a4bef0b
61e7c18
0df77ff
 
5bef8b0
 
 
 
61e7c18
 
0df77ff
443bf8a
22d5035
0df77ff
 
22d5035
 
 
0404cc9
0df77ff
7ce37bf
 
 
6aed364
7ce37bf
6aed364
7ce37bf
0404cc9
6856dac
 
e3e3266
4b5756e
61e7c18
443bf8a
0df77ff
61e7c18
a4bef0b
0df77ff
 
 
 
0404cc9
 
c7a62ec
0404cc9
0df77ff
 
 
 
 
443bf8a
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# ============================================
# Base stage for shared configuration
# ============================================
FROM node:20.11-alpine3.19 AS base

# Configure build environment with optimized settings
ENV NODE_OPTIONS="--max_old_space_size=3072" \
    NEXT_TELEMETRY_DISABLED=1 \
    NODE_ENV=production \
    PYTHONDONTWRITEBYTECODE=1

# ============================================
# Dependencies stage - caches node_modules
# ============================================
FROM base AS deps

WORKDIR /app

# Copy only package files for better caching
COPY package.json yarn.lock ./

# Use yarn with cache for faster installs
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \
    yarn config set cache-folder /usr/local/share/.cache/yarn && \
    yarn install --frozen-lockfile --network-timeout 300000

# ============================================
# Builder stage - builds Next.js application
# ============================================
FROM deps AS web-builder

WORKDIR /app

# Copy source files
COPY . .

# Install dev dependencies needed for build
RUN yarn add --dev autoprefixer postcss tailwindcss code-inspector-plugin

# Build with standalone output
RUN yarn build

# ============================================
# Python builder stage - builds Python deps
# ============================================
FROM python:3.10-slim-bookworm AS python-builder

# Install build dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Use BuildKit's cache mount for pip
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install --no-cache-dir poetry

# Copy and install Python dependencies
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false && \
    poetry install --no-dev --no-interaction --no-ansi

# ============================================
# Final stage - minimal production image
# ============================================
FROM python:3.10-slim-bookworm

# Create non-root user for HF security
RUN useradd -m -u 1000 user

# Install only required runtime packages
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    nodejs \
    npm \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Set up directory structure
WORKDIR /app
RUN mkdir -p api web && chown -R user:user /app

# Install core Python packages
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install --no-cache-dir \
    gunicorn \
    gevent \
    flask \
    cloudscraper \
    transformers

# Copy built files from previous stages
COPY --from=python-builder --chown=user /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
COPY --chown=user . /app/

# Copy Next.js standalone build
COPY --from=web-builder --chown=user /app/.next/standalone /app/web
COPY --from=web-builder --chown=user /app/.next/static /app/web/.next/static
COPY --from=web-builder --chown=user /app/public /app/web/public

# Set environment variables
ENV FLASK_APP=app.py \
    EDITION=SELF_HOSTED \
    DEPLOY_ENV=PRODUCTION \
    CONSOLE_API_URL=http://127.0.0.1:7860 \
    CONSOLE_WEB_URL=http://127.0.0.1:3000 \
    SERVICE_API_URL=http://127.0.0.1:7860 \
    APP_WEB_URL=http://127.0.0.1:3000 \
    NODE_ENV=production \
    HOME=/app \
    PATH="/usr/local/bin:${PATH}" \
    PYTHONPATH=/app/api \
    MAIL_TYPE=resend \
    MAIL_RESEND_API_KEY=null

# Switch to non-root user
USER user

# Expose HF Spaces port
EXPOSE 7860

# Copy and set up entrypoint
COPY --chown=user docker/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

WORKDIR /app

# Add healthcheck
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:7860/health || exit 1

CMD ["./entrypoint.sh"]