@@ -3,12 +3,12 @@ FROM python:3.13.7-slim@sha256:27f90d79cc85e9b7b2560063ef44fa0e9eaae7a7c3f5a9f74
33# OCI Labels for container metadata and registry compliance
44# These labels provide important metadata for container registries and tools
55LABEL org.opencontainers.image.source="https://github.com/allthingslinux/tux" \
6- org.opencontainers.image.description="Tux - The all in one discord bot for the All Things Linux Community" \
7- org.opencontainers.image.licenses="GPL-3.0" \
8- org.opencontainers.image.authors="All Things Linux" \
9- org.opencontainers.image.vendor="All Things Linux" \
10- org.opencontainers.image.title="Tux" \
11- org.opencontainers.image.documentation="https://github.com/allthingslinux/tux/blob/main/README.md"
6+ org.opencontainers.image.description="Tux - The all in one discord bot for the All Things Linux Community" \
7+ org.opencontainers.image.licenses="GPL-3.0" \
8+ org.opencontainers.image.authors="All Things Linux" \
9+ org.opencontainers.image.vendor="All Things Linux" \
10+ org.opencontainers.image.title="Tux" \
11+ org.opencontainers.image.documentation="https://github.com/allthingslinux/tux/blob/main/README.md"
1212
1313# Create non-root user early for security best practices
1414# Using system user (no login shell) with fixed UID/GID for consistency
@@ -36,12 +36,12 @@ RUN echo 'path-exclude /usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/01_nodoc && \
3636RUN apt-get update && \
3737 apt-get upgrade -y && \
3838 apt-get install -y --no-install-recommends --no-install-suggests \
39- git=1:2.47.2-0.2 \
40- libcairo2=1.18.4-1+b1 \
41- libgdk-pixbuf-2.0-0=2.42.12+dfsg-4 \
42- libpango-1.0-0=1.56.3-1 \
43- libpangocairo-1.0-0=1.56.3-1 \
44- shared-mime-info=2.4-5+b2 \
39+ git=1:2.47.2-0.2 \
40+ libcairo2=1.18.4-1+b1 \
41+ libgdk-pixbuf-2.0-0=2.42.12+dfsg-4 \
42+ libpango-1.0-0=1.56.3-1 \
43+ libpangocairo-1.0-0=1.56.3-1 \
44+ shared-mime-info=2.4-5+b2 \
4545 # Cleanup package manager caches to reduce layer size
4646 && apt-get clean \
4747 && rm -rf /var/lib/apt/lists/*
@@ -75,14 +75,14 @@ FROM base AS build
7575RUN apt-get update && \
7676 apt-get upgrade -y && \
7777 apt-get install -y --no-install-recommends \
78- # GCC compiler and build essentials for native extensions
79- build-essential=12.12 \
80- # Additional utilities required by some Python packages
81- findutils=4.10.0-3 \
82- # Development headers for graphics libraries
83- libcairo2-dev=1.18.4-1+b1 \
84- # Foreign Function Interface library for Python extensions
85- libffi8=3.4.8-2 \
78+ # GCC compiler and build essentials for native extensions
79+ build-essential=12.12 \
80+ # Additional utilities required by some Python packages
81+ findutils=4.10.0-3 \
82+ # Development headers for graphics libraries
83+ libcairo2-dev=1.18.4-1+b1 \
84+ # Foreign Function Interface library for Python extensions
85+ libffi8=3.4.8-2 \
8686 # Cleanup to reduce intermediate layer size
8787 && apt-get clean \
8888 && rm -rf /var/lib/apt/lists/*
@@ -130,7 +130,10 @@ RUN cp -a src/tux ./tux
130130
131131# 4. Root level files needed for installation
132132# These include metadata and licensing information
133- COPY README.md LICENSE pyproject.toml ./
133+ COPY README.md LICENSE pyproject.toml alembic.ini ./
134+
135+ # 5. Copy scripts directory for entry points
136+ COPY scripts/ ./scripts/
134137
135138# Build arguments for version information
136139# These allow passing version info without requiring git history in build context
@@ -143,15 +146,15 @@ ARG BUILD_DATE=""
143146# SECURITY: Git operations happen outside container, only VERSION string is passed in
144147RUN set -eux; \
145148 if [ -n "$VERSION" ]; then \
146- # Use provided version from build args (preferred for all builds)
147- echo "Using provided version: $VERSION" ; \
148- echo "$VERSION" > /app/VERSION; \
149+ # Use provided version from build args (preferred for all builds)
150+ echo "Using provided version: $VERSION" ; \
151+ echo "$VERSION" > /app/VERSION; \
149152 else \
150- # Fallback for builds without version info
151- # NOTE: .git directory is excluded by .dockerignore for security/performance
152- # Version should be passed via --build-arg VERSION=$(git describe --tags --always --dirty | sed 's/^v//')
153- echo "No version provided, using fallback" ; \
154- echo "dev" > /app/VERSION; \
153+ # Fallback for builds without version info
154+ # NOTE: .git directory is excluded by .dockerignore for security/performance
155+ # Version should be passed via --build-arg VERSION=$(git describe --tags --always --dirty | sed 's/^v//')
156+ echo "No version provided, using fallback" ; \
157+ echo "dev" > /app/VERSION; \
155158 fi; \
156159 echo "Building version: $(cat /app/VERSION)"
157160
@@ -181,11 +184,11 @@ RUN set -eux; \
181184 # Conditionally install zsh for enhanced development experience
182185 # Only installs if DEVCONTAINER build arg is set to 1
183186 if [ "$DEVCONTAINER" = "1" ]; then \
184- apt-get update && \
185- apt-get install -y --no-install-recommends zsh=5.9-4+b6 && \
186- chsh -s /usr/bin/zsh && \
187- apt-get clean && \
188- rm -rf /var/lib/apt/lists/*; \
187+ apt-get update && \
188+ apt-get install -y --no-install-recommends zsh=5.9-4+b6 && \
189+ chsh -s /usr/bin/zsh && \
190+ apt-get clean && \
191+ rm -rf /var/lib/apt/lists/*; \
189192 fi
190193# Fix ownership of all application files for non-root user
191194# SECURITY: Ensures the application runs with proper permissions
@@ -218,7 +221,9 @@ USER nonroot
218221
219222# Development container startup command
220223# WORKFLOW: Starts the bot in development mode with automatic database migrations
221- CMD ["python" , "-m" , "tux.main" ]
224+ COPY docker/entrypoint.sh /entrypoint.sh
225+ RUN chmod +x /entrypoint.sh
226+ CMD ["/entrypoint.sh" ]
222227
223228# ==============================================================================
224229# PRODUCTION STAGE - Minimal Runtime Environment
@@ -234,12 +239,12 @@ FROM python:3.13.7-slim@sha256:27f90d79cc85e9b7b2560063ef44fa0e9eaae7a7c3f5a9f74
234239# Duplicate OCI labels for production image metadata
235240# COMPLIANCE: Ensures production images have proper metadata for registries
236241LABEL org.opencontainers.image.source="https://github.com/allthingslinux/tux" \
237- org.opencontainers.image.description="Tux - The all in one discord bot for the All Things Linux Community" \
238- org.opencontainers.image.licenses="GPL-3.0" \
239- org.opencontainers.image.authors="All Things Linux" \
240- org.opencontainers.image.vendor="All Things Linux" \
241- org.opencontainers.image.title="Tux" \
242- org.opencontainers.image.documentation="https://github.com/allthingslinux/tux/blob/main/README.md"
242+ org.opencontainers.image.description="Tux - The all in one discord bot for the All Things Linux Community" \
243+ org.opencontainers.image.licenses="GPL-3.0" \
244+ org.opencontainers.image.authors="All Things Linux" \
245+ org.opencontainers.image.vendor="All Things Linux" \
246+ org.opencontainers.image.title="Tux" \
247+ org.opencontainers.image.documentation="https://github.com/allthingslinux/tux/blob/main/README.md"
243248
244249# Create non-root user (same as base stage)
245250# SECURITY: Consistent user across all stages for permission compatibility
@@ -264,9 +269,9 @@ RUN echo 'path-exclude /usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/01_nodoc && \
264269RUN apt-get update && \
265270 apt-get upgrade -y && \
266271 apt-get install -y --no-install-recommends --no-install-suggests \
267- libcairo2=1.18.4-1+b1 \
268- libffi8=3.4.8-2 \
269- coreutils=9.7-3 \
272+ libcairo2=1.18.4-1+b1 \
273+ libffi8=3.4.8-2 \
274+ coreutils=9.7-3 \
270275 # Aggressive cleanup to minimize image size
271276 && apt-get clean \
272277 && rm -rf /var/lib/apt/lists/* \
@@ -303,6 +308,8 @@ COPY --from=build --chown=nonroot:nonroot /app/src /app/src
303308
304309COPY --from=build --chown=nonroot:nonroot /app/pyproject.toml /app/pyproject.toml
305310COPY --from=build --chown=nonroot:nonroot /app/VERSION /app/VERSION
311+ COPY --from=build --chown=nonroot:nonroot /app/alembic.ini /app/alembic.ini
312+ COPY --from=build --chown=nonroot:nonroot /app/scripts /app/scripts
306313
307314# Create convenient symlinks for Python and application binaries
308315# USABILITY: Allows running 'python' and 'tux' commands without full paths
@@ -311,11 +318,11 @@ RUN ln -sf /app/.venv/bin/python /usr/local/bin/python && \
311318 ln -sf /app/.venv/bin/tux /usr/local/bin/tux
312319
313320RUN set -eux; \
314- mkdir -p /app/.cache/tldr /app/temp; \
315- mkdir -p /home/nonroot/.cache /home/nonroot/.npm; \
316- rm -rf /home/nonroot/.npm/_cacache_; \
317- chown -R nonroot:nonroot /app/.cache /app/temp /home/nonroot/.cache /home/nonroot/.npm; \
318- chmod -R 755 /app/.cache /app/temp /home/nonroot/.cache /home/nonroot/.npm
321+ mkdir -p /app/.cache/tldr /app/temp; \
322+ mkdir -p /home/nonroot/.cache /home/nonroot/.npm; \
323+ rm -rf /home/nonroot/.npm/_cacache_; \
324+ chown -R nonroot:nonroot /app/.cache /app/temp /home/nonroot/.cache /home/nonroot/.npm; \
325+ chmod -R 755 /app/.cache /app/temp /home/nonroot/.cache /home/nonroot/.npm
319326
320327# Switch to non-root user for final optimizations
321328USER nonroot
@@ -334,19 +341,19 @@ RUN set -eux; \
334341 # Remove test directories from installed packages (but preserve prisma binaries)
335342 # These directories contain test files that are not needed in production
336343 for test_dir in tests testing "test*" ; do \
337- find /app/.venv -name "$test_dir" -type d -not -path "*/prisma*" -exec rm -rf {} + 2>/dev/null || true; \
344+ find /app/.venv -name "$test_dir" -type d -not -path "*/prisma*" -exec rm -rf {} + 2>/dev/null || true; \
338345 done; \
339346 # Remove documentation files from installed packages (but preserve prisma docs)
340347 # These files take up significant space and are not needed in production
341348 for doc_pattern in "*.md" "*.txt" "*.rst" "LICENSE*" "NOTICE*" "COPYING*" "CHANGELOG*" "README*" "HISTORY*" "AUTHORS*" "CONTRIBUTORS*" ; do \
342- find /app/.venv -name "$doc_pattern" -not -path "*/prisma*" -delete 2>/dev/null || true; \
349+ find /app/.venv -name "$doc_pattern" -not -path "*/prisma*" -delete 2>/dev/null || true; \
343350 done; \
344351 # Remove large development packages that are not needed in production
345352 # These packages (pip, setuptools, wheel) are only needed for installing packages
346353 # NOTE: Preserving packages that Prisma might need
347354 for pkg in setuptools wheel pkg_resources; do \
348- rm -rf /app/.venv/lib/python3.13/site-packages/${pkg}* 2>/dev/null || true; \
349- rm -rf /app/.venv/bin/${pkg}* 2>/dev/null || true; \
355+ rm -rf /app/.venv/lib/python3.13/site-packages/${pkg}* 2>/dev/null || true; \
356+ rm -rf /app/.venv/bin/${pkg}* 2>/dev/null || true; \
350357 done; \
351358 rm -rf /app/.venv/bin/easy_install* 2>/dev/null || true; \
352359 # Compile Python bytecode for performance optimization
@@ -370,5 +377,6 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
370377
371378# Application entry point and default command
372379# DEPLOYMENT: Configures how the container starts in production
373- ENTRYPOINT ["python" , "-m" , "tux.main" ]
380+ COPY --chmod=755 docker/entrypoint.sh /entrypoint.sh
381+ ENTRYPOINT ["/entrypoint.sh" ]
374382CMD []
0 commit comments