## Issue Fixed: - Static files collection failing with permission error in Docker container - Error: `PermissionError: [Errno 13] Permission denied: '/app/staticfiles/js'` - Occurs when running `python manage.py collectstatic` in production ## Solution Applied: 1. **Enhanced Dockerfile**: - Create `/app/staticfiles` and `/app/media` directories explicitly - Set proper ownership with `chown -R django:django /app` - Ensures directories exist with correct permissions before user switch 2. **Improved entrypoint.sh**: - Added `mkdir -p` to ensure directories exist at runtime - Creates directories before attempting static files collection - Provides fallback if directories weren't created in Docker build 3. **Updated Documentation**: - Added troubleshooting section for static files permission error - Explains the fix and prevention methods ## Benefits: - ✅ Resolves Docker container permission issues - ✅ Works with non-root user (security best practice) - ✅ Handles both build-time and runtime directory creation - ✅ Maintains proper file ownership for Django operations This should resolve the collectstatic permission error in Dokploy deployment. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
9.4 KiB
🚀 Dokploy Deployment Guide - Django Template
Complete step-by-step guide to deploy your Django template on Dokploy using Docker Compose (2025).
📋 Prerequisites
- Dokploy server with admin access
- Domain name pointed to your server (A record)
- GitHub repository:
https://github.com/thecyberlearn/modern-django-starter
🌐 Step 1: Domain Setup
Configure DNS Record
Type: A
Name: app (or subdomain of your choice)
Value: YOUR_DOKPLOY_SERVER_IP
TTL: 3600
Example: app.yourdomain.com → 123.456.789.123
🏗️ Step 2: Create Project in Dokploy
- Login to your Dokploy dashboard
- Click "Create Project"
- Fill Project Details:
- Project Name:
django-template(or your preferred name) - Description:
Modern Django template with Tailwind CSS
- Project Name:
- Click "Create Project"
⚙️ Step 3: Create Service - Compose
- Inside your project, click "Create Service"
- Select Service Type: "Compose"
- Fill the "Create Compose" form:
📝 Form Fields to Fill:
- Name:
Django Template(or your preferred service name) - App Name:
django-template-prod(unique identifier for this service) - Compose Type:
Docker Compose(keep as selected) - Description:
Modern Django template with Tailwind CSS, authentication, and PostgreSQL database
- Click "Create" to proceed to configuration
📂 Step 4: Configure Repository Source
Fill Repository Configuration Form:
- Provider:
GitHub - Repository:
https://github.com/thecyberlearn/modern-django-starter - Branch:
main - Compose Path:
./docker-compose.dokploy.yml
Click "Save" to save repository settings.
🔧 Step 5: Configure Raw Docker Compose (Alternative Method)
If you prefer to paste the compose file directly:
- Go to "General" → "Raw" tab
- Paste this Docker Compose configuration:
services:
web:
build:
context: .
target: production
command: >
sh -c "chmod +x /app/entrypoint.sh &&
/app/entrypoint.sh &&
gunicorn --bind 0.0.0.0:8000 --workers 3 django_project.wsgi:application"
volumes:
- "../files/static:/app/staticfiles"
- "../files/media:/app/media"
expose:
- 8000
env_file:
- .env
depends_on:
- db
- redis
environment:
- DJANGO_SETTINGS_MODULE=django_project.settings.production
networks:
- dokploy-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.django-app-UNIQUE.rule=Host(\`your-domain.com\`)"
- "traefik.http.routers.django-app-UNIQUE.entrypoints=websecure"
- "traefik.http.routers.django-app-UNIQUE.tls.certResolver=letsencrypt"
- "traefik.http.services.django-app-UNIQUE.loadbalancer.server.port=8000"
db:
image: postgres:15-alpine
volumes:
- "../files/postgres_data:/var/lib/postgresql/data/"
environment:
- POSTGRES_DB=${DB_NAME:-django_db}
- POSTGRES_USER=${DB_USER:-django_user}
- POSTGRES_PASSWORD=${DB_PASSWORD:-django_password}
networks:
- dokploy-network
redis:
image: redis:7-alpine
volumes:
- "../files/redis_data:/data"
networks:
- dokploy-network
networks:
dokploy-network:
external: true
- Replace
UNIQUEandyour-domain.comwith your values - Click "Save"
🌍 Step 6: Environment Variables
- Go to "Environment" tab
- Add these environment variables:
# Django Configuration
SECRET_KEY=your-very-long-random-secret-key-generate-new-one
DEBUG=False
ALLOWED_HOSTS=app.yourdomain.com,yourdomain.com
DJANGO_SETTINGS_MODULE=django_project.settings.production
# Database Configuration
DB_NAME=django_db
DB_USER=django_user
DB_PASSWORD=super_secure_password_123
DB_HOST=db
DB_PORT=5432
# Email Configuration (Production)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password
DEFAULT_FROM_EMAIL=noreply@yourdomain.com
# Social Authentication (Optional)
GOOGLE_OAUTH2_CLIENT_ID=your-google-client-id
GOOGLE_OAUTH2_CLIENT_SECRET=your-google-client-secret
# Security Settings
SECURE_SSL_REDIRECT=True
- Click "Save Environment"
🌐 Step 7: Domain Configuration
Method A: Using Traefik Labels (Recommended)
Your domain is already configured in the Docker Compose labels. Just update:
- Replace
your-domain.comwith your actual domain (e.g.,app.yourdomain.com) - Replace
django-app-UNIQUEwith a unique identifier (e.g.,django-app-prod)
Method B: Using Dokploy Domain Tab
- Go to "Domains" tab
- Click "Add Domain"
- Fill Domain Form:
- Domain:
app.yourdomain.com - Service:
web - Port:
8000
- Domain:
- Click "Save"
🚀 Step 8: Deploy Application
- Go to "General" tab
- Click "Deploy" button
- Monitor deployment in the "Deployments" tab
- Wait for build to complete (5-10 minutes)
⚡ Step 9: Post-Deployment Setup
After successful deployment, access the web service console:
- Go to "Services" → "web" → "Terminal"
- Run these commands:
# Run database migrations
python manage.py migrate
# Create default user groups (admin, staff, user)
python manage.py create_groups
# Create your admin user
python manage.py createsuperuser
# Enter email and password when prompted
# Build Tailwind CSS for production
python manage.py tailwind build
# Collect static files
python manage.py collectstatic --noinput
✅ Step 10: Verify Deployment
- Visit your domain:
https://app.yourdomain.com - Check SSL certificate: Should show green padlock
- Test authentication: Register/login functionality
- Admin access:
https://app.yourdomain.com/admin/
🔧 Important Configuration Notes
Unique Identifiers
- Replace
django-app-UNIQUEwith a unique name likedjango-app-prod-2025 - This prevents conflicts with other services
Volume Persistence
- All data is stored in
../files/directory - Survives deployments and container restarts
- Located on Dokploy server filesystem
Environment Variables
- SECRET_KEY: Generate new one for production
- DB_PASSWORD: Use strong, unique password
- ALLOWED_HOSTS: Include all domains/subdomains
- EMAIL_HOST_PASSWORD: Use Gmail app password, not regular password
SSL Certificate
- Automatically generated by Let's Encrypt via Traefik
- May take 1-2 minutes after deployment
- Requires valid domain pointing to server
🆘 Troubleshooting
Build Fails
# Check deployment logs in Dokploy
# Common issues:
# - Missing environment variables
# - Invalid Docker Compose syntax
# - Network connectivity issues
Django Logging Error (FileNotFoundError)
If you see error: FileNotFoundError: [Errno 2] No such file or directory: '/var/log/django/django.log'
Solution: This is already fixed in the latest version. The production settings now use console logging only, which is Docker-friendly and works with Dokploy's log viewing system.
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
Domain Not Accessible
# Check DNS propagation
nslookup app.yourdomain.com
# Verify Traefik labels
# Ensure unique router names
# Check domain configuration in Dokploy
Database Connection Error
# Verify environment variables match
# Check PostgreSQL service is running
# Verify network connectivity between services
Static Files Not Loading
# Access web service terminal
python manage.py collectstatic --noinput
# Check volume mounts
# Verify static file paths
SSL Certificate Issues
# Wait 2-3 minutes after deployment
# Check domain DNS resolution
# Verify Let's Encrypt rate limits not exceeded
# Check Traefik logs in Dokploy
🎯 Production Checklist
- Domain correctly pointed to server
- Environment variables all configured
- Database migrations completed
- Admin user created
- SSL certificate working
- Static files loading correctly
- Email configuration tested
- Social auth configured (if needed)
- Monitoring set up
- Backups configured
🔄 Updating Application
To update your deployed application:
- Push changes to GitHub repository
- In Dokploy, go to "General" tab
- Click "Deploy" button
- Monitor deployment progress
- Run any new migrations if needed:
python manage.py migrate python manage.py collectstatic --noinput
📊 Monitoring and Logs
- Application Logs: Available in Dokploy "Logs" tab
- Service Monitoring: Individual service status and metrics
- Deployment History: Last 10 deployments with detailed logs
- Resource Usage: CPU, memory, and disk usage monitoring
🎉 Congratulations! Your Django template is now deployed on Dokploy with professional-grade configuration including SSL, persistent data, and automated deployments!
Need help? Check the deployment logs in Dokploy or review the troubleshooting section above.