From 04223730d31463748a0eb416393f1ea56ea2ccf9 Mon Sep 17 00:00:00 2001 From: Django Template Date: Thu, 11 Sep 2025 16:32:02 +0530 Subject: [PATCH] Refactor Docker configuration to follow 2025 industry best practices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Major Refactoring Based on Research: ### ❌ **Removed Over-Engineered Approach**: - Removed `gosu` dependency (unnecessary complexity) - Removed complex user switching in entrypoint - Removed root operations during runtime - Simplified permission management ### ✅ **Implemented 2025 Best Practices**: #### 1. **Simplified Dockerfile Pattern**: - Create directories with proper ownership in build stage - Set `USER django` once and keep it throughout - No complex user switching or runtime permission changes - Clean, standard Docker layering #### 2. **Industry-Standard Entrypoint**: - Simple script that runs as non-root user - Standard `exec "$@"` pattern - No permission operations during runtime - Follows container orchestration best practices #### 3. **Proper Architecture Documentation**: - Django/Gunicorn for dynamic content only - Nginx serves static files (6000+ req/sec vs Django's much lower) - Non-root user throughout for security - Clean service separation ## Benefits of This Approach: - ✅ **Security**: Non-root user throughout application lifecycle - ✅ **Simplicity**: Standard Docker patterns, no complex scripts - ✅ **Performance**: Nginx handles static files efficiently - ✅ **Maintainability**: Follows industry conventions - ✅ **Reliability**: Proven patterns used by major companies ## Research Sources: Based on 2025 best practices from: - TestDriven.io Django Docker patterns - Better Stack community guides - Official Django deployment documentation - Docker security best practices This follows the KISS principle while maintaining production-grade security and performance. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- DOKPLOY.md | 17 +++++++++++++---- Dockerfile | 7 ++----- entrypoint.sh | 11 ++--------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/DOKPLOY.md b/DOKPLOY.md index 4b958db..a129d72 100644 --- a/DOKPLOY.md +++ b/DOKPLOY.md @@ -214,6 +214,14 @@ python manage.py collectstatic --noinput ## 🔧 Important Configuration Notes +### **Architecture Overview (2025 Best Practices)** +This Django template follows industry-standard Docker patterns: +- **Django/Gunicorn**: Handles dynamic content only +- **Nginx**: Serves static/media files directly (6000+ req/sec performance) +- **Non-root user**: Application runs as `django` user for security +- **Shared volumes**: Static files accessible to both Django and Nginx +- **Clean separation**: Database, cache, web app as separate services + ### **Unique Identifiers** - Replace `django-app-UNIQUE` with a unique name like `django-app-prod-2025` - This prevents conflicts with other services @@ -253,10 +261,11 @@ If you see error: `FileNotFoundError: [Errno 2] No such file or directory: '/var ### **Static Files Permission Error** If you see error: `PermissionError: [Errno 13] Permission denied: '/app/staticfiles/js'` -**Solution**: This is fixed in the latest version by: -- Creating static directories with proper permissions in Dockerfile -- Ensuring directories exist before collecting static files in entrypoint.sh -- Using proper Docker user permissions for file operations +**Solution**: Following 2025 Docker best practices: +- Directories created in Dockerfile with proper ownership (`chown -R django:django /app`) +- Application runs as non-root user throughout (security best practice) +- Docker volumes provide persistent storage for static/media files +- Nginx serves static files directly for optimal performance ### **Domain Not Accessible** ```bash diff --git a/Dockerfile b/Dockerfile index a748943..2305c87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,6 @@ RUN apt-get update \ libpq-dev \ gettext \ curl \ - gosu \ && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ && apt-get install -y nodejs \ && rm -rf /var/lib/apt/lists/* @@ -40,13 +39,11 @@ RUN groupadd -r django && useradd -r -g django django COPY . /app/ -# Create directories that need write permissions +# Create directories and set ownership - industry best practice RUN mkdir -p /app/staticfiles /app/media && \ - chmod -R 755 /app/staticfiles /app/media && \ chown -R django:django /app -# Don't switch to django user yet - let entrypoint handle permissions -# USER django +USER django EXPOSE 8000 diff --git a/entrypoint.sh b/entrypoint.sh index 0570995..1f07fb8 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -5,12 +5,6 @@ set -e echo "Waiting for PostgreSQL..." sleep 5 -echo "Setting up directories and permissions..." -# Create directories and set proper permissions -mkdir -p /app/staticfiles /app/media -chown -R django:django /app/staticfiles /app/media -chmod -R 755 /app/staticfiles /app/media - echo "Running migrations..." python manage.py migrate --noinput @@ -23,6 +17,5 @@ python manage.py setup_social_apps echo "Collecting static files..." python manage.py collectstatic --noinput -echo "Switching to django user and starting application..." -# Switch to django user for the main application -exec gosu django "$@" \ No newline at end of file +echo "Starting application..." +exec "$@" \ No newline at end of file