File size: 6,190 Bytes
af8f89c
36d2deb
 
10b70a9
6a0246e
af8f89c
 
 
 
10b70a9
6a0246e
 
10b70a9
e8816ce
5711951
 
 
af8f89c
 
 
 
2a8928d
 
af8f89c
 
6a0246e
 
2a8928d
af8f89c
f4be5ea
e8816ce
5711951
af8f89c
 
5711951
af8f89c
 
5711951
af8f89c
 
5711951
af8f89c
 
 
 
 
 
 
 
 
6db1678
5711951
 
af8f89c
111ba62
5711951
 
e8816ce
 
 
 
 
6a0246e
5711951
e8816ce
5711951
8b1ab5c
6a0246e
5711951
e8816ce
0f0f717
5711951
 
e8816ce
8f7a7a3
5711951
6a0246e
 
5711951
990fa90
5711951
 
 
cd06c05
5711951
 
cd06c05
264ac69
5711951
 
 
e8816ce
5711951
 
e8816ce
262b6c2
8f7a7a3
262b6c2
e8816ce
5711951
e8816ce
5711951
 
 
 
 
 
 
 
 
 
 
 
 
5e1192b
af8f89c
5afbe18
af8f89c
5711951
 
7b05b4e
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
# Use an official Python runtime as a parent image
# Using python:3.10-slim-bullseye for a Debian Bullseye based slim Python 3.10 environment
FROM python:3.10-slim-bullseye

# Set environment variables for Python, pip, and locale
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV PIP_NO_CACHE_DIR off
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

# Install system dependencies (as root)
# build-essential for packages that might need to compile C code
# libffi-dev often needed by cryptography (common sub-dependency)
# curl is a generally useful utility
RUN apt-get update && apt-get install -y --no-install-recommends \
    ffmpeg \
    imagemagick \
    git \
    build-essential \
    libffi-dev \
    fonts-dejavu-core \
    fonts-liberation \
    libgl1-mesa-glx \
    libglib2.0-0 \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Modify ImageMagick policy.xml (as root)
# This is critical for TextClip and other ImageMagick-dependent features in MoviePy
RUN if [ -f /etc/ImageMagick-6/policy.xml ]; then \
        XML_FILE="/etc/ImageMagick-6/policy.xml"; \
        echo "INFO: Attempting to modify ImageMagick policy at $XML_FILE (v6)." ; \
    elif [ -f /etc/ImageMagick-7/policy.xml ]; then \
        XML_FILE="/etc/ImageMagick-7/policy.xml"; \
        echo "INFO: Attempting to modify ImageMagick policy at $XML_FILE (v7)." ; \
    else \
        XML_FILE=""; \
        echo "WARNING: ImageMagick policy.xml not found in /etc/ImageMagick-[67]/. MoviePy TextClip might fail." ; \
    fi && \
    if [ -n "$XML_FILE" ] && [ -f "$XML_FILE" ]; then \
        sed -i 's/<policy domain="path" rights="none" pattern="@\*"\/>/<!-- <policy domain="path" rights="none" pattern="@\*" \/> -->/' "$XML_FILE" && \
        sed -i 's/<policy domain="coder" rights="none" pattern="TEXT"\/>/<!-- <policy domain="coder" rights="none" pattern="TEXT" \/> -->/' "$XML_FILE" && \
        sed -i 's/<policy domain="coder" rights="none" pattern="LABEL"\/>/<!-- <policy domain="coder" rights="none" pattern="LABEL" \/> -->/' "$XML_FILE" && \
        sed -i 's/<policy domain="coder" rights="none" pattern="MVG"\/>/<!-- <policy domain="coder" rights="none" pattern="MVG" \/> -->/' "$XML_FILE" && \
        sed -i 's/<policy domain="coder" rights="none" pattern="MSL"\/>/<!-- <policy domain="coder" rights="none" pattern="MSL" \/> -->/' "$XML_FILE" && \
        sed -i 's/<policy domain="coder" rights="none" pattern="HTTPS"\/>/<!-- <policy domain="coder" rights="none" pattern="HTTPS" \/> -->/' "$XML_FILE" && \
        sed -i 's/<policy domain="coder" rights="none" pattern="HTTP"\/>/<!-- <policy domain="coder" rights="none" pattern="HTTP" \/> -->/' "$XML_FILE" && \
        echo "INFO: ImageMagick policy modifications applied to $XML_FILE." ; \
    else \
        echo "INFO: No ImageMagick policy file found to modify, or XML_FILE variable was empty." ; \
    fi

# Create a non-root user and group.
# Create home directory, .cache for pip, and .streamlit for Streamlit config.
RUN groupadd -r appgroup --gid 1000 && \
    useradd --no-log-init -r -g appgroup -u 1000 --create-home --shell /bin/bash appuser && \
    mkdir -p /home/appuser/.cache/pip && \
    mkdir -p /home/appuser/.streamlit && \
    chown -R appuser:appgroup /home/appuser

# Set Streamlit home directory to the one created for appuser
ENV STREAMLIT_HOME=/home/appuser/.streamlit
# Disable Streamlit telemetry using environment variable (alternative to CLI flag)
ENV BROWSER_GATHERUSAGEDATA=false

# Set the working directory for the application
WORKDIR /app

# Copy requirements.txt first to leverage Docker layer caching.
# Ensure appuser owns this file in its destination.
COPY --chown=appuser:appgroup requirements.txt .

# Switch to the non-root user to install Python packages
USER appuser
RUN pip install --no-cache-dir --upgrade pip && \
    echo "Attempting to install packages from requirements.txt as appuser..." && \
    pip install --user --no-cache-dir -r requirements.txt
    # If you still need streamlit-sortable from GitHub and it's NOT in requirements.txt:
    # echo "Attempting to install streamlit-sortable from GitHub as appuser..." && \
    # pip install --user --no-cache-dir git+https://github.com/okld/streamlit-sortable.git

# Add the user's local bin directory (where pip --user installs scripts) to PATH
# This ensures executables like 'streamlit' are found.
ENV PATH="/home/appuser/.local/bin:${PATH}"

# Switch back to root only for operations that require root privileges, like copying to system dirs
# For copying application code to /app, appuser should have write permission if WORKDIR is /app and /app is owned by appuser.
# However, using root for COPY and then chown is a common robust pattern.
USER root
COPY . .
# Ensure the entire /app directory and its contents are owned by appuser
RUN chown -R appuser:appgroup /app

# Create runtime directories as appuser (now that /app is owned by appuser)
USER appuser
RUN mkdir -p /app/temp_cinegen_media
RUN mkdir -p /app/assets/fonts # Ensure this exists, even if copied

# Optional: Copy custom fonts to a system-wide location if MoviePy/ImageMagick needs them there.
# This might require switching back to USER root temporarily for the cp and fc-cache.
# For now, relying on Pillow finding fonts in assets/ or system paths.
# USER root
# RUN if [ -d "/app/assets/fonts" ] && [ "$(ls -A /app/assets/fonts)" ]; then \
#         mkdir -p /usr/local/share/fonts/truetype/cinegen_custom && \
#         cp /app/assets/fonts/*.*tf /usr/local/share/fonts/truetype/cinegen_custom/ 2>/dev/null || true && \
#         fc-cache -fv && \
#         echo "INFO: Copied custom fonts to system and refreshed font cache."; \
#     else \
#         echo "INFO: No custom fonts found in /app/assets/fonts to copy system-wide." ; \
#     fi
# USER appuser # Switch back to appuser for runtime

# Expose the port Streamlit runs on
EXPOSE 8501

# Define the command to run the application as appuser
# The --browser.gatherUsageStats=false flag should work for Streamlit 1.13+
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0", "--browser.gatherUsageStats=false"]