File size: 4,888 Bytes
baf138d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96b97e7
d458acb
 
27378e7
 
d458acb
baf138d
27378e7
baf138d
27378e7
 
 
 
 
 
baf138d
d458acb
 
baf138d
 
 
 
d458acb
baf138d
 
 
 
 
 
 
d458acb
baf138d
368ab98
 
27378e7
baf138d
 
27378e7
 
 
 
baf138d
27378e7
 
baf138d
27378e7
d458acb
 
 
 
 
 
 
f834a09
d458acb
 
 
 
27378e7
d458acb
 
f296af7
 
d458acb
368ab98
27378e7
d458acb
 
 
 
 
 
 
baf138d
27378e7
 
 
baf138d
27378e7
baf138d
d458acb
 
 
baf138d
d458acb
baf138d
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# # Use an official Python runtime as a parent image
# FROM python:3.11-slim

# WORKDIR /app      #add by P

# # Set environment variables for Hugging Face cache
# ENV DEBIAN_FRONTEND=noninteractive \
#     PYTHONUNBUFFERED=1 \
#     PYTHONDONTWRITEBYTECODE=1 \
#     TRANSFORMERS_CACHE=/app/cache \
#     HF_HOME=/app/cache \
#     NLTK_DATA=/app/nltk_data \
#     MPLCONFIGDIR=/app/.config/matplotlib

# COPY requirements.txt requirements.txt 
# COPY templates/ /app/templates 
# COPY utils/ /app/utils
# COPY app.py app.py
# COPY blocks/ /app/blocks/ 
# COPY generated_projects/ /app/generated_projects/ 
# COPY blocks/sprites/ /app/blocks/sprites/ 
# COPY blocks/Backdrops/ /app/blocks/Backdrops/ 
# COPY blocks/sound/ /app/blocks/sound/ 
# # COPY OUTPUTS/ /app/OUTPUTS
# COPY . /app/
# COPY . .

# # Install system dependencies
# RUN apt-get update && apt-get install -y \
#     build-essential \
#     libglib2.0-0 \
#     libsm6 \
#     libxext6 \
#     libxrender-dev \
#     tesseract-ocr \
#     poppler-utils \
#     libgl1 \
#     # ffmpeg \
#     # libopencv-dev \
#     curl \
#     ca-certificates \
#     && apt-get clean \
#     && rm -rf /var/lib/apt/lists/*

# RUN pip install --upgrade pip && pip install -r requirements.txt

# # Create necessary directories with correct permissions
# RUN mkdir -p /app/nltk_data /app/.config/matplotlib \
#  && mkdir -p /app/cache /app/data /app/logs /app/outputs /app/blocks \
#  && mkdir -p /app/outputs/DETECTED_IMAGE /app/outputs/SCANNED_IMAGE /app/outputs/EXTRACTED_JSON \
#  && chmod -R 777 /app/cache /app/blocks /app/data /app/logs /app/outputs /app/outputs/SCANNED_IMAGE /app/outputs/EXTRACTED_JSON /app/outputs/DETECTED_IMAGE \
#  && chmod -R 777 /app

# # Set Flask environment variables
# ENV FLASK_APP=app.py \
#     FLASK_ENV=production

# # Expose port and start application
# EXPOSE 7860
# # CMD ["python", "app.py"]
# CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "2", "app:app"]
# #CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "", "--timeout", "360", "app:app"]

# Dockerfile — CPU-optimized, permissions-fixed, non-root runtime

FROM python:3.11-slim

# Set working dir
WORKDIR /app

# Environment: Hugging Face cache + force CPU behavior
ENV DEBIAN_FRONTEND=noninteractive \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    TRANSFORMERS_CACHE=/app/cache \
    HF_HOME=/app/cache \
    NLTK_DATA=/app/nltk_data \
    MPLCONFIGDIR=/app/.config/matplotlib \
    XDG_CACHE_HOME=/app/.cache \
    # Force CPU-only (ensure no CUDA attempts)
    CUDA_VISIBLE_DEVICES= \
    PYTORCH_ENABLE_MPS=0 \
    PYTORCH_NO_CUDA=1

# Copy minimal files first (leverage layer caching)
COPY requirements.txt ./requirements.txt
COPY app.py ./app.py
COPY templates/ ./templates/
COPY utils/ ./utils/
COPY blocks/ ./blocks/
COPY generated_projects/ ./generated_projects/

# Install system dependencies (including fontconfig/fonts)
RUN apt-get update && apt-get install -y --no-install-recommends \
    fontconfig \
    fonts-dejavu-core \
    build-essential \
    curl \
    ca-certificates \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libxrender-dev \
    libgl1 \
    tesseract-ocr \
    poppler-utils \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# Create runtime directories, cache dirs, and static dir BEFORE pip install to ensure permissions
# We will chown to non-root user later
RUN mkdir -p /app/.config/matplotlib \
    /app/cache /app/nltk_data /nltk_data \
    /app/.cache /app/.cache/fontconfig /root/.cache/fontconfig \
    /app/logs /app/outputs /app/outputs/DETECTED_IMAGE /app/outputs/SCANNED_IMAGE /app/outputs/EXTRACTED_JSON \
    /app/data /app/blocks /app/static \
    && chmod -R 777 /app

# Install Python dependencies
RUN pip install --upgrade pip \
 && pip install --no-cache-dir -r requirements.txt

# Pre-download NLTK packages into the chosen directory so runtime import doesn't try to write
ENV NLTK_DATA=/app/nltk_data
RUN python -m nltk.downloader -d /app/nltk_data punkt averaged_perceptron_tagger wordnet || true

# Populate font cache (will quiet fontconfig warnings)
RUN fc-cache -f -v || true

# Create a less-privileged user and give ownership of /app to that user
RUN useradd -m -u 1000 appuser \
    && chown -R appuser:appuser /app

# Switch to non-root user (IMPORTANT: do this AFTER chown)
USER appuser

# Set Flask env
ENV FLASK_APP=app.py \
    FLASK_ENV=production

# Expose port
EXPOSE 7860

# HEALTHCHECK (optional) — uses lightweight endpoint; if you don't have /healthz, change it or remove.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -f http://127.0.0.1:7860/healthz || exit 1

# Run Gunicorn as non-root appuser: single worker + threads, no timeout
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:7860", "-w", "1", "--threads", "4", "-k", "gthread", "--timeout", "0", "--graceful-timeout", "0"]