mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-12-11 14:32:30 -05:00
Compare commits
1 Commits
2216efa3a4
...
feat-docke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66e67c751e |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,5 +1,10 @@
|
|||||||
cli-tool/.env
|
cli-tool/.env
|
||||||
frontend/package-lock.json
|
frontend/package-lock.json
|
||||||
|
custom/local_settings.py
|
||||||
|
custom/static/images/*
|
||||||
|
!custom/static/images/.gitkeep
|
||||||
|
custom/static/css/*
|
||||||
|
!custom/static/css/.gitkeep
|
||||||
media_files/encoded/
|
media_files/encoded/
|
||||||
media_files/original/
|
media_files/original/
|
||||||
media_files/hls/
|
media_files/hls/
|
||||||
@@ -35,3 +40,4 @@ frontend-tools/video-editor/client/public/videos/sample-video.mp3
|
|||||||
frontend-tools/chapters-editor/client/public/videos/sample-video.mp3
|
frontend-tools/chapters-editor/client/public/videos/sample-video.mp3
|
||||||
static/chapters_editor/videos/sample-video.mp3
|
static/chapters_editor/videos/sample-video.mp3
|
||||||
static/video_editor/videos/sample-video.mp3
|
static/video_editor/videos/sample-video.mp3
|
||||||
|
backups/
|
||||||
|
|||||||
@@ -1,254 +1,441 @@
|
|||||||
# MediaCMS Docker Restructure Summary
|
# MediaCMS Docker Restructure Summary - Version 7.3
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This document summarizes the complete Docker architecture restructure for MediaCMS 7.3, eliminating supervisord and implementing modern Docker best practices.
|
MediaCMS 7.3 introduces a complete Docker architecture restructure, moving from a monolithic supervisord-based setup to modern microservices with proper separation of concerns.
|
||||||
|
|
||||||
## What Was Created
|
**⚠️ BREAKING CHANGES** - See [`UPGRADE_TO_7.3.md`](./UPGRADE_TO_7.3.md) for migration guide.
|
||||||
|
|
||||||
### New Files
|
## Architecture Comparison
|
||||||
|
|
||||||
#### Dockerfiles
|
### Before (7.x) - Monolithic
|
||||||
- `Dockerfile` - Multi-stage Dockerfile with targets (replaced old Dockerfile):
|
|
||||||
- `build-image` - FFmpeg and Bento4 builder
|
|
||||||
- `base` - Python/Django base image
|
|
||||||
- `web` - uWSGI web server
|
|
||||||
- `worker` - Celery worker (standard)
|
|
||||||
- `worker-full` - Celery worker with extra codecs
|
|
||||||
|
|
||||||
- `Dockerfile.nginx` - Vanilla nginx with MediaCMS configs baked in
|
|
||||||
|
|
||||||
#### Docker Compose Files
|
|
||||||
- `docker-compose.yaml` - Production deployment (no file mounts) - REPLACED
|
|
||||||
- `docker-compose-cert.yaml` - Production with HTTPS (Let's Encrypt) - REPLACED
|
|
||||||
- `docker-compose-dev.yaml` - Development with file mounts and hot reload - REPLACED
|
|
||||||
|
|
||||||
#### Scripts
|
|
||||||
- `scripts/entrypoint-web.sh` - Web container entrypoint
|
|
||||||
- `scripts/entrypoint-worker.sh` - Worker container entrypoint
|
|
||||||
- `scripts/run-migrations.sh` - Migration runner script
|
|
||||||
|
|
||||||
#### Configuration
|
|
||||||
- `config/nginx/nginx.conf` - Main nginx config (from deploy/docker/)
|
|
||||||
- `config/nginx/site.conf` - Virtual host config (from deploy/docker/nginx_http_only.conf)
|
|
||||||
- `config/nginx/uwsgi_params` - uWSGI params (from deploy/docker/)
|
|
||||||
- `config/nginx-proxy/client_max_body_size.conf` - For nginx-proxy (from deploy/docker/reverse_proxy/)
|
|
||||||
- `config/uwsgi/uwsgi.ini` - uWSGI configuration (from deploy/docker/)
|
|
||||||
- `config/imagemagick/policy.xml` - ImageMagick policy (from deploy/docker/)
|
|
||||||
|
|
||||||
#### Documentation
|
|
||||||
- `docs/DOCKER_V7.3_MIGRATION.md` - Complete migration guide
|
|
||||||
- Updated `docs/admins_docs.md` - Sections 4 and 5
|
|
||||||
|
|
||||||
## Architecture Changes
|
|
||||||
|
|
||||||
### Before (Old Architecture)
|
|
||||||
```
|
```
|
||||||
Single Container (supervisord managing multiple processes)
|
┌─────────────────────────────────────┐
|
||||||
├── nginx (port 80)
|
│ Single Container │
|
||||||
├── uwsgi (port 9000)
|
│ ┌──────────┐ │
|
||||||
├── celery beat
|
│ │Supervisor│ │
|
||||||
├── celery short workers
|
│ └────┬─────┘ │
|
||||||
└── celery long workers
|
│ ├─── nginx (port 80) │
|
||||||
|
│ ├─── uwsgi (Django) │
|
||||||
Controlled by ENABLE_* environment variables
|
│ ├─── celery beat │
|
||||||
|
│ ├─── celery workers │
|
||||||
|
│ └─── migrations │
|
||||||
|
│ │
|
||||||
|
│ Volumes: ./ mounted to container │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
### After (New Architecture)
|
### After (7.3) - Microservices
|
||||||
```
|
```
|
||||||
Dedicated Containers (one process per container)
|
┌────────┐ ┌─────┐ ┌───────────┐ ┌──────────┐
|
||||||
├── nginx (port 80) → web:9000
|
│ nginx │→ │ web │ │celery_beat│ │ celery │
|
||||||
├── web (uwsgi on port 9000)
|
│ │ │uwsgi│ │ │ │ workers │
|
||||||
├── celery_beat
|
└────────┘ └─────┘ └───────────┘ └──────────┘
|
||||||
├── celery_short (scalable)
|
│
|
||||||
├── celery_long (scalable, optional :full image)
|
┌───────┴────────┐
|
||||||
├── migrations (runs on startup)
|
│ db │ redis │
|
||||||
├── db (PostgreSQL)
|
└───────┴────────┘
|
||||||
└── redis
|
|
||||||
|
|
||||||
Volumes:
|
Volumes: Named volumes + custom/ bind mount
|
||||||
- static_files (nginx ← web)
|
|
||||||
- media_files (nginx ← web, workers)
|
|
||||||
- postgres_data
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## What Changed
|
||||||
|
|
||||||
|
### 1. Container Services
|
||||||
|
|
||||||
|
| Component | Before (7.x) | After (7.3) |
|
||||||
|
|-----------|-------------|-------------|
|
||||||
|
| **nginx** | Inside main container | Separate container |
|
||||||
|
| **Django/uWSGI** | Inside main container | Dedicated `web` container |
|
||||||
|
| **Celery Beat** | Inside main container | Dedicated container |
|
||||||
|
| **Celery Workers** | Inside main container | Separate containers (short/long) |
|
||||||
|
| **Migrations** | Via environment flag | Init container (runs once) |
|
||||||
|
|
||||||
|
### 2. Volume Strategy
|
||||||
|
|
||||||
|
| Data | Before (7.x) | After (7.3) |
|
||||||
|
|------|-------------|-------------|
|
||||||
|
| **Application code** | Bind mount `./` | **Built into image** |
|
||||||
|
| **Media files** | `./media_files` | **Named volume** `media_files` |
|
||||||
|
| **Static files** | `./static` | **Built into image** (collectstatic at build) |
|
||||||
|
| **Logs** | `./logs` | **Named volume** `logs` |
|
||||||
|
| **PostgreSQL** | `../postgres_data` | **Named volume** `postgres_data` |
|
||||||
|
| **Custom config** | `cms/local_settings.py` | **Bind mount** `./custom/` |
|
||||||
|
|
||||||
|
### 3. Removed Components
|
||||||
|
|
||||||
|
- ❌ supervisord and all supervisord configs
|
||||||
|
- ❌ docker-entrypoint.sh (permission fixing script)
|
||||||
|
- ❌ `ENABLE_*` environment variables
|
||||||
|
- ❌ Runtime collectstatic
|
||||||
|
- ❌ nginx from base image
|
||||||
|
|
||||||
|
### 4. New Components
|
||||||
|
|
||||||
|
- ✅ `custom/` directory for user customizations
|
||||||
|
- ✅ Multi-stage Dockerfile (base, web, worker, worker-full)
|
||||||
|
- ✅ Separate nginx image (`Dockerfile.nginx`)
|
||||||
|
- ✅ Build-time collectstatic
|
||||||
|
- ✅ USER www-data (non-root containers)
|
||||||
|
- ✅ Health checks for all services
|
||||||
|
- ✅ Makefile with common tasks
|
||||||
|
|
||||||
## Key Improvements
|
## Key Improvements
|
||||||
|
|
||||||
### 1. **Removed Components**
|
### Security
|
||||||
- ❌ supervisord and all configs in `deploy/docker/supervisord/`
|
- ✅ Containers run as `www-data` (UID 33), not root
|
||||||
- ❌ `deploy/docker/start.sh`
|
- ✅ Read-only mounts where possible
|
||||||
- ❌ `deploy/docker/entrypoint.sh`
|
- ✅ Smaller attack surface per container
|
||||||
- ❌ All `ENABLE_*` environment variables
|
- ✅ No privilege escalation needed
|
||||||
|
|
||||||
### 2. **Separated Services**
|
### Performance
|
||||||
- Nginx runs in its own container
|
- ✅ Named volumes have better I/O than bind mounts
|
||||||
- Django/uWSGI in dedicated web container
|
- ✅ Static files built into image (no runtime collection)
|
||||||
- Celery workers split by task duration
|
- ✅ Faster container startups
|
||||||
- Migrations run automatically on every startup
|
- ✅ No chown on millions of files at startup
|
||||||
|
|
||||||
### 3. **Production Ready**
|
### Scalability
|
||||||
- No file mounts in production (immutable images)
|
- ✅ Scale web and workers independently
|
||||||
- Named volumes for data persistence
|
- ✅ Ready for load balancing
|
||||||
- Proper health checks
|
- ✅ Can use Docker Swarm or Kubernetes
|
||||||
- Individual service scaling
|
- ✅ Horizontal scaling: `docker compose scale celery_short=3`
|
||||||
|
|
||||||
### 4. **Development Friendly**
|
### Maintainability
|
||||||
- Separate `-dev` compose file with file mounts
|
- ✅ One process per container (proper separation)
|
||||||
- Django debug mode
|
- ✅ Clear service dependencies
|
||||||
- Frontend hot reload
|
- ✅ Standard Docker patterns
|
||||||
- Live code editing
|
- ✅ Easier debugging (service-specific logs)
|
||||||
|
- ✅ Immutable images
|
||||||
|
|
||||||
## Images to Build
|
### Developer Experience
|
||||||
|
- ✅ Separate dev compose with hot reload
|
||||||
|
- ✅ `custom/` directory for all customizations
|
||||||
|
- ✅ Clear documentation and examples
|
||||||
|
- ✅ Makefile targets for common tasks
|
||||||
|
|
||||||
For production, these images need to be built and pushed to Docker Hub:
|
## New Customization System
|
||||||
|
|
||||||
|
### The `custom/` Directory
|
||||||
|
|
||||||
|
All user customizations now go in a dedicated directory:
|
||||||
|
|
||||||
|
```
|
||||||
|
custom/
|
||||||
|
├── README.md # Full documentation
|
||||||
|
├── local_settings.py.example # Template file
|
||||||
|
├── local_settings.py # Your Django settings (gitignored)
|
||||||
|
└── static/
|
||||||
|
├── images/ # Custom logos (gitignored)
|
||||||
|
│ └── logo_dark.png
|
||||||
|
└── css/ # Custom CSS (gitignored)
|
||||||
|
└── custom.css
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- Clear separation from core code
|
||||||
|
- Works out-of-box (empty directory is fine)
|
||||||
|
- Gitignored customizations
|
||||||
|
- Well documented with examples
|
||||||
|
|
||||||
|
See [`custom/README.md`](./custom/README.md) for usage guide.
|
||||||
|
|
||||||
|
## Docker Images
|
||||||
|
|
||||||
|
### Images to Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build base and web image
|
# Web image (Django + uWSGI)
|
||||||
docker build --target web -t mediacms/mediacms:7.3 .
|
docker build --target web -t mediacms/mediacms:7.3 .
|
||||||
|
|
||||||
# Build worker image
|
# Worker image (Celery)
|
||||||
docker build --target worker -t mediacms/mediacms-worker:7.3 .
|
docker build --target worker -t mediacms/mediacms-worker:7.3 .
|
||||||
|
|
||||||
# Build worker-full image
|
# Worker-full image (Celery with extra codecs)
|
||||||
docker build --target worker-full -t mediacms/mediacms-worker:7.3-full .
|
docker build --target worker-full -t mediacms/mediacms-worker:7.3-full .
|
||||||
|
|
||||||
# Build nginx image
|
# Nginx image
|
||||||
docker build -f Dockerfile.nginx -t mediacms/mediacms-nginx:7.3 .
|
docker build -f Dockerfile.nginx -t mediacms/mediacms-nginx:7.3 .
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deployment Options
|
### Image Sizes
|
||||||
|
|
||||||
|
| Image | Approximate Size |
|
||||||
|
|-------|-----------------|
|
||||||
|
| mediacms:7.3 | ~800MB |
|
||||||
|
| mediacms-worker:7.3 | ~800MB |
|
||||||
|
| mediacms-worker:7.3-full | ~1.2GB |
|
||||||
|
| mediacms-nginx:7.3 | ~50MB |
|
||||||
|
|
||||||
|
## Deployment Scenarios
|
||||||
|
|
||||||
### 1. Development
|
### 1. Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose-dev.yaml up
|
docker compose -f docker-compose-dev.yaml up
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
- File mounts for live editing
|
- File mounts for live editing
|
||||||
- Django runserver
|
- Django runserver with DEBUG=True
|
||||||
- Frontend dev server
|
- Frontend hot reload
|
||||||
|
- Immediate code changes
|
||||||
|
|
||||||
### 2. Production (HTTP)
|
### 2. Production (HTTP)
|
||||||
```bash
|
|
||||||
# Rename .new files first
|
|
||||||
mv docker-compose.yaml.new docker-compose.yaml
|
|
||||||
|
|
||||||
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
- Immutable images
|
- Immutable images
|
||||||
- No file mounts
|
- Named volumes for data
|
||||||
|
- Production-ready
|
||||||
- Port 80
|
- Port 80
|
||||||
|
|
||||||
### 3. Production (HTTPS)
|
### 3. Production (HTTPS with Let's Encrypt)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Rename .new files first
|
docker compose -f docker-compose.yaml -f docker-compose-cert.yaml up -d
|
||||||
mv docker-compose-cert.yaml.new docker-compose-cert.yaml
|
|
||||||
|
|
||||||
# Edit and set your domain/email
|
|
||||||
docker compose -f docker-compose-cert.yaml up -d
|
|
||||||
```
|
```
|
||||||
- Automatic Let's Encrypt certificates
|
|
||||||
|
**Features:**
|
||||||
|
- Automatic SSL certificates
|
||||||
- Auto-renewal
|
- Auto-renewal
|
||||||
|
- nginx-proxy + acme-companion
|
||||||
|
- Production-ready
|
||||||
|
|
||||||
## Migration Path for Existing Systems
|
## Minimal Deployment (No Code Required!)
|
||||||
|
|
||||||
### For Production Systems Currently Running
|
**Version 7.3 requires ONLY:**
|
||||||
|
|
||||||
1. **Backup first**
|
1. ✅ `docker-compose.yaml` file
|
||||||
```bash
|
2. ✅ Docker images (from Docker Hub)
|
||||||
docker exec <db_container> pg_dump -U mediacms mediacms > backup.sql
|
3. ⚠️ `custom/` directory (optional, only if customizing)
|
||||||
```
|
|
||||||
|
|
||||||
2. **Update compose file**
|
**No git repo needed!** Download docker-compose.yaml from release/docs and start.
|
||||||
- Replace old docker-compose files with new ones
|
|
||||||
- Update domain settings in cert file if using HTTPS
|
|
||||||
|
|
||||||
3. **Pull new images**
|
## Migration Requirements
|
||||||
```bash
|
|
||||||
docker pull mediacms/mediacms:7.3
|
|
||||||
docker pull mediacms/mediacms-worker:7.3
|
|
||||||
docker pull mediacms/mediacms-nginx:7.3
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Restart**
|
|
||||||
```bash
|
|
||||||
docker compose down
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
|
||||||
1. **No more ENABLE_* variables** - Remove from any custom configs
|
⚠️ **Not backward compatible** - Manual migration required
|
||||||
2. **deploy/docker/local_settings.py** - Now use environment variables or custom image
|
|
||||||
3. **Service names changed**:
|
**What needs migration:**
|
||||||
- `celery_worker` → `celery_short` + `celery_long`
|
1. ✅ PostgreSQL database (dump and restore)
|
||||||
- Added `nginx` service
|
2. ✅ Media files (copy to named volume)
|
||||||
|
3. ✅ Custom settings → `custom/local_settings.py` (if you had them)
|
||||||
|
4. ✅ Custom logos/CSS → `custom/static/` (if you had them)
|
||||||
|
5. ⚠️ Backup scripts (new volume paths)
|
||||||
|
6. ⚠️ Monitoring (new container names)
|
||||||
|
|
||||||
|
### Migration Steps
|
||||||
|
|
||||||
|
See [`UPGRADE_TO_7.3.md`](./UPGRADE_TO_7.3.md) for complete guide.
|
||||||
|
|
||||||
|
**Quick overview:**
|
||||||
|
```bash
|
||||||
|
# 1. Backup
|
||||||
|
docker compose exec db pg_dump -U mediacms mediacms > backup.sql
|
||||||
|
tar -czf media_backup.tar.gz media_files/
|
||||||
|
cp docker-compose.yaml docker-compose.yaml.old
|
||||||
|
|
||||||
|
# 2. Download new docker-compose.yaml
|
||||||
|
wget https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose.yaml
|
||||||
|
|
||||||
|
# 3. Create custom/ if needed
|
||||||
|
mkdir -p custom/static/{images,css}
|
||||||
|
# Copy your old settings/logos if you had them
|
||||||
|
|
||||||
|
# 4. Pull images and start
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 5. Restore data
|
||||||
|
cat backup.sql | docker compose exec -T db psql -U mediacms mediacms
|
||||||
|
# (See full guide for media migration)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
|
||||||
|
### Created/Reorganized
|
||||||
|
|
||||||
|
```
|
||||||
|
├── Dockerfile # Multi-stage (base, web, worker)
|
||||||
|
├── Dockerfile.nginx # Nginx image
|
||||||
|
├── docker-compose.yaml # Production
|
||||||
|
├── docker-compose-cert.yaml # Production + HTTPS
|
||||||
|
├── docker-compose-dev.yaml # Development
|
||||||
|
├── Makefile # Common tasks
|
||||||
|
├── custom/ # User customizations
|
||||||
|
│ ├── README.md
|
||||||
|
│ ├── local_settings.py.example
|
||||||
|
│ └── static/
|
||||||
|
├── config/
|
||||||
|
│ ├── imagemagick/policy.xml
|
||||||
|
│ ├── nginx/
|
||||||
|
│ │ ├── nginx.conf
|
||||||
|
│ │ └── site.conf
|
||||||
|
│ ├── nginx-proxy/
|
||||||
|
│ │ └── client_max_body_size.conf
|
||||||
|
│ └── uwsgi/
|
||||||
|
│ └── uwsgi.ini
|
||||||
|
└── scripts/
|
||||||
|
└── run-migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Makefile Targets
|
||||||
|
|
||||||
|
New Makefile with common operations:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make backup-db # PostgreSQL dump with timestamp
|
||||||
|
make admin-shell # Quick Django shell access
|
||||||
|
make build-frontend # Rebuild frontend assets
|
||||||
|
make test # Run test suite
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rollback Strategy
|
||||||
|
|
||||||
|
If migration fails:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Stop new version
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# 2. Checkout old version
|
||||||
|
git checkout main
|
||||||
|
|
||||||
|
# 3. Restore old compose
|
||||||
|
git checkout main docker-compose.yaml
|
||||||
|
|
||||||
|
# 4. Restore data from backups
|
||||||
|
# (See UPGRADE_TO_7.3.md for details)
|
||||||
|
|
||||||
|
# 5. Start old version
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
## Testing Checklist
|
## Testing Checklist
|
||||||
|
|
||||||
Before deploying to production, test:
|
Before production deployment:
|
||||||
|
|
||||||
- [ ] Migrations run successfully
|
- [ ] Migrations run successfully
|
||||||
- [ ] Static files served correctly
|
- [ ] Static files load correctly
|
||||||
- [ ] Media files served correctly
|
- [ ] Media files upload/download work
|
||||||
- [ ] Django admin accessible
|
- [ ] Video transcoding works (check celery_long logs)
|
||||||
- [ ] Video upload works
|
- [ ] Admin panel accessible
|
||||||
- [ ] Video transcoding works (celery_long)
|
- [ ] Custom settings loaded (if using custom/)
|
||||||
- [ ] Thumbnail generation works (celery_short)
|
- [ ] Database persists across restarts
|
||||||
- [ ] HTTPS redirects work (if using cert file)
|
- [ ] Media persists across restarts
|
||||||
- [ ] Database persistence across restarts
|
- [ ] Logs accessible via `docker compose logs`
|
||||||
- [ ] Media files persistence across restarts
|
- [ ] Health checks pass: `docker compose ps`
|
||||||
|
|
||||||
## Configuration Examples
|
## Common Post-Upgrade Tasks
|
||||||
|
|
||||||
### Use Full Worker Image
|
### View Logs
|
||||||
```yaml
|
```bash
|
||||||
celery_long:
|
# Before: tail -f logs/uwsgi.log
|
||||||
image: mediacms/mediacms-worker:7.3-full
|
# After:
|
||||||
|
docker compose logs -f web
|
||||||
|
docker compose logs -f celery_long
|
||||||
```
|
```
|
||||||
|
|
||||||
### Set Custom Domain
|
### Access Shell
|
||||||
```yaml
|
```bash
|
||||||
environment:
|
# Before: docker exec -it <container> bash
|
||||||
FRONTEND_HOST: 'https://videos.example.com'
|
# After:
|
||||||
PORTAL_NAME: 'My Video Portal'
|
make admin-shell
|
||||||
|
# Or: docker compose exec web bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restart Service
|
||||||
|
```bash
|
||||||
|
# Before: docker restart <container>
|
||||||
|
# After:
|
||||||
|
docker compose restart web
|
||||||
```
|
```
|
||||||
|
|
||||||
### Scale Workers
|
### Scale Workers
|
||||||
```bash
|
```bash
|
||||||
|
# New capability:
|
||||||
docker compose up -d --scale celery_short=3 --scale celery_long=2
|
docker compose up -d --scale celery_short=3 --scale celery_long=2
|
||||||
```
|
```
|
||||||
|
|
||||||
## Files to Review Before Finalizing
|
### Database Backup
|
||||||
|
```bash
|
||||||
|
# Before: Custom script
|
||||||
|
# After:
|
||||||
|
make backup-db
|
||||||
|
```
|
||||||
|
|
||||||
1. **Dockerfile** - Review Python/Django/uWSGI configuration
|
## Performance Considerations
|
||||||
2. **config/nginx/site.conf** - Review nginx paths and proxy settings
|
|
||||||
3. **docker-compose.yaml** - Review volume mounts and service dependencies
|
### Startup Time
|
||||||
4. **scripts/run-migrations.sh** - Review migration logic
|
- **Before**: Slower (chown on all files)
|
||||||
|
- **After**: Faster (no permission fixing)
|
||||||
|
|
||||||
|
### I/O Performance
|
||||||
|
- **Before**: Bind mount overhead
|
||||||
|
- **After**: Named volumes (better performance)
|
||||||
|
|
||||||
|
### Memory Usage
|
||||||
|
- **Before**: Single large container
|
||||||
|
- **After**: Multiple smaller containers (better resource allocation)
|
||||||
|
|
||||||
|
## New Volume Management
|
||||||
|
|
||||||
|
### List Volumes
|
||||||
|
```bash
|
||||||
|
docker volume ls | grep mediacms
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inspect Volume
|
||||||
|
```bash
|
||||||
|
docker volume inspect mediacms_media_files
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup Volume
|
||||||
|
```bash
|
||||||
|
docker run --rm \
|
||||||
|
-v mediacms_media_files:/data:ro \
|
||||||
|
-v $(pwd):/backup \
|
||||||
|
alpine tar czf /backup/media_backup.tar.gz -C /data .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- **Upgrade Guide**: [`UPGRADE_TO_7.3.md`](./UPGRADE_TO_7.3.md)
|
||||||
|
- **Customization**: [`custom/README.md`](./custom/README.md)
|
||||||
|
- **Admin Docs**: `docs/admins_docs.md`
|
||||||
|
|
||||||
|
## Timeline Estimates
|
||||||
|
|
||||||
|
| Instance Size | Expected Migration Time |
|
||||||
|
|---------------|------------------------|
|
||||||
|
| Small (<100 videos) | 30-60 minutes |
|
||||||
|
| Medium (100-1000 videos) | 1-3 hours |
|
||||||
|
| Large (>1000 videos) | 3-8 hours |
|
||||||
|
|
||||||
|
**Plan accordingly and schedule during low-traffic periods!**
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
1. Read [`UPGRADE_TO_7.3.md`](./UPGRADE_TO_7.3.md) thoroughly
|
||||||
|
2. Check [`custom/README.md`](./custom/README.md) for customization
|
||||||
|
3. Search GitHub Issues
|
||||||
|
4. Test in staging first
|
||||||
|
5. Keep backups for at least 1 week post-upgrade
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
To finalize this restructure:
|
1. ✅ Read [`UPGRADE_TO_7.3.md`](./UPGRADE_TO_7.3.md)
|
||||||
|
2. ✅ Test in development: `docker compose -f docker-compose-dev.yaml up`
|
||||||
|
3. ✅ Backup production data
|
||||||
|
4. ✅ Test migration in staging
|
||||||
|
5. ✅ Plan maintenance window
|
||||||
|
6. ✅ Execute migration
|
||||||
|
7. ✅ Monitor for 24-48 hours
|
||||||
|
|
||||||
1. **Test locally** with docker-compose-dev.yaml
|
---
|
||||||
2. **Build images** and push to Docker Hub
|
|
||||||
3. **Update CI/CD** to build new images
|
|
||||||
4. **Test in staging environment**
|
|
||||||
5. **Create release notes** referencing migration guide
|
|
||||||
|
|
||||||
## Backup
|
**Ready to upgrade?** Start with: [`UPGRADE_TO_7.3.md`](./UPGRADE_TO_7.3.md)
|
||||||
|
|
||||||
Old Docker files have been backed up to `.docker-backup/` directory.
|
|
||||||
|
|
||||||
## Rollback Plan
|
|
||||||
|
|
||||||
If issues arise, rollback by:
|
|
||||||
1. Reverting to old docker-compose files
|
|
||||||
2. Using old image tags
|
|
||||||
3. Restoring database from backup if needed
|
|
||||||
|
|
||||||
Old files are preserved in `.docker-backup/` directory.
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
- Migration Guide: `docs/DOCKER_V7.3_MIGRATION.md`
|
|
||||||
- Admin Docs: `docs/admins_docs.md` (updated sections 4, 5)
|
|
||||||
- Issues: https://github.com/mediacms-io/mediacms/issues
|
|
||||||
|
|||||||
26
Dockerfile
26
Dockerfile
@@ -1,6 +1,5 @@
|
|||||||
FROM python:3.13.5-slim-bookworm AS build-image
|
FROM python:3.13.5-slim-bookworm AS build-image
|
||||||
|
|
||||||
# Install system dependencies needed for downloading and extracting
|
|
||||||
RUN apt-get update -y && \
|
RUN apt-get update -y && \
|
||||||
apt-get install -y --no-install-recommends wget xz-utils unzip && \
|
apt-get install -y --no-install-recommends wget xz-utils unzip && \
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
@@ -14,7 +13,6 @@ RUN mkdir -p ffmpeg-tmp && \
|
|||||||
cp -v ffmpeg-tmp/ffmpeg ffmpeg-tmp/ffprobe ffmpeg-tmp/qt-faststart /usr/local/bin && \
|
cp -v ffmpeg-tmp/ffmpeg ffmpeg-tmp/ffprobe ffmpeg-tmp/qt-faststart /usr/local/bin && \
|
||||||
rm -rf ffmpeg-tmp ffmpeg-release-amd64-static.tar.xz
|
rm -rf ffmpeg-tmp ffmpeg-release-amd64-static.tar.xz
|
||||||
|
|
||||||
# Install Bento4 in the specified location
|
|
||||||
RUN mkdir -p /home/mediacms.io/bento4 && \
|
RUN mkdir -p /home/mediacms.io/bento4 && \
|
||||||
wget -q http://zebulon.bok.net/Bento4/binaries/Bento4-SDK-1-6-0-637.x86_64-unknown-linux.zip && \
|
wget -q http://zebulon.bok.net/Bento4/binaries/Bento4-SDK-1-6-0-637.x86_64-unknown-linux.zip && \
|
||||||
unzip Bento4-SDK-1-6-0-637.x86_64-unknown-linux.zip -d /home/mediacms.io/bento4 && \
|
unzip Bento4-SDK-1-6-0-637.x86_64-unknown-linux.zip -d /home/mediacms.io/bento4 && \
|
||||||
@@ -38,7 +36,6 @@ ENV PYTHONUNBUFFERED=1 \
|
|||||||
VIRTUAL_ENV=/home/mediacms.io \
|
VIRTUAL_ENV=/home/mediacms.io \
|
||||||
PATH="$VIRTUAL_ENV/bin:$PATH"
|
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
|
||||||
# Install system dependencies (no nginx, no supervisor)
|
|
||||||
RUN apt-get update -y && \
|
RUN apt-get update -y && \
|
||||||
apt-get -y upgrade && \
|
apt-get -y upgrade && \
|
||||||
apt-get install --no-install-recommends -y \
|
apt-get install --no-install-recommends -y \
|
||||||
@@ -56,15 +53,12 @@ RUN apt-get update -y && \
|
|||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Set up virtualenv
|
|
||||||
RUN mkdir -p /home/mediacms.io/mediacms/{logs,media_files,static} && \
|
RUN mkdir -p /home/mediacms.io/mediacms/{logs,media_files,static} && \
|
||||||
cd /home/mediacms.io && \
|
cd /home/mediacms.io && \
|
||||||
python3 -m venv $VIRTUAL_ENV
|
python3 -m venv $VIRTUAL_ENV
|
||||||
|
|
||||||
# Copy requirements files
|
|
||||||
COPY requirements.txt requirements-dev.txt ./
|
COPY requirements.txt requirements-dev.txt ./
|
||||||
|
|
||||||
# Install Python dependencies using pip (within virtualenv)
|
|
||||||
ARG DEVELOPMENT_MODE=False
|
ARG DEVELOPMENT_MODE=False
|
||||||
RUN pip install --no-cache-dir uv && \
|
RUN pip install --no-cache-dir uv && \
|
||||||
uv pip install --no-binary lxml --no-binary xmlsec -r requirements.txt && \
|
uv pip install --no-binary lxml --no-binary xmlsec -r requirements.txt && \
|
||||||
@@ -79,28 +73,17 @@ RUN pip install --no-cache-dir uv && \
|
|||||||
libxmlsec1-dev \
|
libxmlsec1-dev \
|
||||||
libpq-dev
|
libpq-dev
|
||||||
|
|
||||||
# Copy ffmpeg and Bento4 from build image
|
|
||||||
COPY --from=build-image /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg
|
COPY --from=build-image /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg
|
||||||
COPY --from=build-image /usr/local/bin/ffprobe /usr/local/bin/ffprobe
|
COPY --from=build-image /usr/local/bin/ffprobe /usr/local/bin/ffprobe
|
||||||
COPY --from=build-image /usr/local/bin/qt-faststart /usr/local/bin/qt-faststart
|
COPY --from=build-image /usr/local/bin/qt-faststart /usr/local/bin/qt-faststart
|
||||||
COPY --from=build-image /home/mediacms.io/bento4 /home/mediacms.io/bento4
|
COPY --from=build-image /home/mediacms.io/bento4 /home/mediacms.io/bento4
|
||||||
|
|
||||||
# Copy application files with correct ownership
|
|
||||||
COPY --chown=www-data:www-data . /home/mediacms.io/mediacms
|
COPY --chown=www-data:www-data . /home/mediacms.io/mediacms
|
||||||
WORKDIR /home/mediacms.io/mediacms
|
WORKDIR /home/mediacms.io/mediacms
|
||||||
|
|
||||||
# Copy imagemagick policy for sprite thumbnail generation
|
# Copy imagemagick policy for sprite thumbnail generation
|
||||||
COPY config/imagemagick/policy.xml /etc/ImageMagick-6/policy.xml
|
COPY config/imagemagick/policy.xml /etc/ImageMagick-6/policy.xml
|
||||||
|
|
||||||
# Copy local_settings.py from config to cms/ for default Docker config (if exists)
|
|
||||||
RUN if [ -f config/local_settings.py ]; then \
|
|
||||||
cp config/local_settings.py cms/local_settings.py && \
|
|
||||||
chown www-data:www-data cms/local_settings.py && \
|
|
||||||
echo "Docker local_settings.py applied"; \
|
|
||||||
else \
|
|
||||||
echo "No config/local_settings.py found, using default settings"; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create www-data user directories and set permissions
|
# Create www-data user directories and set permissions
|
||||||
RUN mkdir -p /var/run/mediacms && \
|
RUN mkdir -p /var/run/mediacms && \
|
||||||
chown -R www-data:www-data /home/mediacms.io/mediacms/logs \
|
chown -R www-data:www-data /home/mediacms.io/mediacms/logs \
|
||||||
@@ -108,11 +91,12 @@ RUN mkdir -p /var/run/mediacms && \
|
|||||||
/home/mediacms.io/mediacms/static \
|
/home/mediacms.io/mediacms/static \
|
||||||
/var/run/mediacms
|
/var/run/mediacms
|
||||||
|
|
||||||
# Copy and set up entrypoint script
|
# Collect static files during build
|
||||||
COPY scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
RUN python manage.py collectstatic --noinput && \
|
||||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
chown -R www-data:www-data /home/mediacms.io/mediacms/static
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
# Run container as www-data user
|
||||||
|
USER www-data
|
||||||
|
|
||||||
############ WEB IMAGE (Django/uWSGI) ############
|
############ WEB IMAGE (Django/uWSGI) ############
|
||||||
FROM base AS web
|
FROM base AS web
|
||||||
|
|||||||
15
Makefile
15
Makefile
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: admin-shell build-frontend
|
.PHONY: admin-shell build-frontend backup-db
|
||||||
|
|
||||||
admin-shell:
|
admin-shell:
|
||||||
@container_id=$$(docker compose ps -q web); \
|
@container_id=$$(docker compose ps -q web); \
|
||||||
@@ -17,3 +17,16 @@ build-frontend:
|
|||||||
test:
|
test:
|
||||||
docker compose -f docker-compose-dev.yaml exec --env TESTING=True -T web pytest
|
docker compose -f docker-compose-dev.yaml exec --env TESTING=True -T web pytest
|
||||||
|
|
||||||
|
backup-db:
|
||||||
|
@echo "Creating PostgreSQL database dump..."
|
||||||
|
@mkdir -p backups
|
||||||
|
@timestamp=$$(date +%Y%m%d_%H%M%S); \
|
||||||
|
dump_file="backups/mediacms_dump_$${timestamp}.sql"; \
|
||||||
|
docker compose exec -T db pg_dump -U mediacms -d mediacms > "$${dump_file}"; \
|
||||||
|
if [ $$? -eq 0 ]; then \
|
||||||
|
echo "Database dump created successfully: $${dump_file}"; \
|
||||||
|
else \
|
||||||
|
echo "Database dump failed"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
292
QUICKSTART.md
Normal file
292
QUICKSTART.md
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
# MediaCMS 7.3 - Quick Start
|
||||||
|
|
||||||
|
## Minimal Deployment (No Code Required!)
|
||||||
|
|
||||||
|
MediaCMS 7.3 can be deployed with **just 2 files**:
|
||||||
|
|
||||||
|
1. `docker-compose.yaml`
|
||||||
|
2. `custom/` directory (optional)
|
||||||
|
|
||||||
|
**No git repo, no code checkout needed!** Everything runs from Docker images.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fresh Installation
|
||||||
|
|
||||||
|
### 1. Create deployment directory
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir mediacms && cd mediacms
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Download docker-compose.yaml
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with curl:
|
||||||
|
```bash
|
||||||
|
curl -O https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Start MediaCMS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Access your site
|
||||||
|
|
||||||
|
- **Frontend**: http://localhost
|
||||||
|
- **Admin**: http://localhost/admin
|
||||||
|
- Username: `admin`
|
||||||
|
- Password: Check logs for auto-generated password:
|
||||||
|
```bash
|
||||||
|
docker compose logs migrations | grep "password:"
|
||||||
|
```
|
||||||
|
|
||||||
|
**That's it!** 🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Optional: Customization
|
||||||
|
|
||||||
|
### Add Custom Settings
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create custom directory
|
||||||
|
mkdir -p custom/static/{images,css}
|
||||||
|
|
||||||
|
# 2. Download example template
|
||||||
|
wget -O custom/local_settings.py.example \
|
||||||
|
https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/custom/local_settings.py.example
|
||||||
|
|
||||||
|
# 3. Copy and edit
|
||||||
|
cp custom/local_settings.py.example custom/local_settings.py
|
||||||
|
nano custom/local_settings.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Example customizations:
|
||||||
|
```python
|
||||||
|
# custom/local_settings.py
|
||||||
|
DEBUG = False
|
||||||
|
ALLOWED_HOSTS = ['media.example.com']
|
||||||
|
PORTAL_NAME = "My Media Portal"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Custom Logo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Copy your logo
|
||||||
|
cp ~/my-logo.png custom/static/images/logo_dark.png
|
||||||
|
|
||||||
|
# 2. Reference in settings
|
||||||
|
cat >> custom/local_settings.py <<EOF
|
||||||
|
PORTAL_LOGO_DARK_PNG = "/custom/static/images/logo_dark.png"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 3. Restart (no rebuild needed!)
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Custom CSS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create CSS file
|
||||||
|
cat > custom/static/css/custom.css <<EOF
|
||||||
|
body {
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 2. Reference in settings
|
||||||
|
cat >> custom/local_settings.py <<EOF
|
||||||
|
EXTRA_CSS_PATHS = ["/custom/static/css/custom.css"]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 3. Restart (no rebuild needed!)
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: Both settings AND static files only need restart - nginx serves custom/ files directly!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HTTPS with Let's Encrypt
|
||||||
|
|
||||||
|
### 1. Download cert overlay
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose-cert.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Edit domains
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano docker-compose-cert.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Change these lines:
|
||||||
|
```yaml
|
||||||
|
VIRTUAL_HOST: 'media.example.com' # Your domain
|
||||||
|
LETSENCRYPT_HOST: 'media.example.com' # Your domain
|
||||||
|
LETSENCRYPT_EMAIL: 'admin@example.com' # Your email
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Start with SSL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.yaml -f docker-compose-cert.yaml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
**SSL certificates are issued automatically!**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
Your deployment directory:
|
||||||
|
|
||||||
|
```
|
||||||
|
mediacms/
|
||||||
|
├── docker-compose.yaml # Required
|
||||||
|
├── docker-compose-cert.yaml # Optional (for HTTPS)
|
||||||
|
└── custom/ # Optional (for customizations)
|
||||||
|
├── local_settings.py # Django settings
|
||||||
|
└── static/
|
||||||
|
├── images/ # Custom logos
|
||||||
|
└── css/ # Custom CSS
|
||||||
|
```
|
||||||
|
|
||||||
|
**Named volumes** (managed by Docker):
|
||||||
|
- `mediacms_postgres_data` - Database
|
||||||
|
- `mediacms_media_files` - Uploaded media
|
||||||
|
- `mediacms_static_files` - Static assets
|
||||||
|
- `mediacms_logs` - Application logs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
### View logs
|
||||||
|
```bash
|
||||||
|
docker compose logs -f web
|
||||||
|
docker compose logs -f celery_long
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access Django shell
|
||||||
|
```bash
|
||||||
|
docker compose exec web python manage.py shell
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create admin user
|
||||||
|
```bash
|
||||||
|
docker compose exec web python manage.py createsuperuser
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restart service
|
||||||
|
```bash
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stop everything
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update to newer version
|
||||||
|
```bash
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backup
|
||||||
|
|
||||||
|
### Database backup
|
||||||
|
```bash
|
||||||
|
docker compose exec db pg_dump -U mediacms mediacms > backup_$(date +%Y%m%d).sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### Media files backup
|
||||||
|
```bash
|
||||||
|
docker run --rm \
|
||||||
|
-v mediacms_media_files:/data:ro \
|
||||||
|
-v $(pwd):/backup \
|
||||||
|
alpine tar czf /backup/media_backup_$(date +%Y%m%d).tar.gz -C /data .
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Upgrading from 7.x?
|
||||||
|
|
||||||
|
If you're upgrading from an older MediaCMS version, see:
|
||||||
|
- **[UPGRADE_TO_7.3.md](./UPGRADE_TO_7.3.md)** - Complete migration guide
|
||||||
|
- **[DOCKER_RESTRUCTURE_SUMMARY.md](./DOCKER_RESTRUCTURE_SUMMARY.md)** - What changed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- **Customization**: Download [`custom/README.md`](https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/custom/README.md)
|
||||||
|
- **Upgrade Guide**: [UPGRADE_TO_7.3.md](./UPGRADE_TO_7.3.md)
|
||||||
|
- **Architecture**: [DOCKER_RESTRUCTURE_SUMMARY.md](./DOCKER_RESTRUCTURE_SUMMARY.md)
|
||||||
|
- **Project Docs**: https://docs.mediacms.io
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Can't access the site?
|
||||||
|
|
||||||
|
Check services are running:
|
||||||
|
```bash
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
All services should be "Up" or "Exited (0)" for migrations.
|
||||||
|
|
||||||
|
### Forgot admin password?
|
||||||
|
|
||||||
|
Check logs:
|
||||||
|
```bash
|
||||||
|
docker compose logs migrations | grep "password:"
|
||||||
|
```
|
||||||
|
|
||||||
|
Or create new admin:
|
||||||
|
```bash
|
||||||
|
docker compose exec web python manage.py createsuperuser
|
||||||
|
```
|
||||||
|
|
||||||
|
### Videos not encoding?
|
||||||
|
|
||||||
|
Check celery workers:
|
||||||
|
```bash
|
||||||
|
docker compose logs celery_long
|
||||||
|
docker compose logs celery_short
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port 80 already in use?
|
||||||
|
|
||||||
|
Edit docker-compose.yaml to use different port:
|
||||||
|
```yaml
|
||||||
|
nginx:
|
||||||
|
ports:
|
||||||
|
- "8080:80" # Use port 8080 instead
|
||||||
|
```
|
||||||
|
|
||||||
|
Then access at http://localhost:8080
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- **Issues**: https://github.com/mediacms-io/mediacms/issues
|
||||||
|
- **Discussions**: https://github.com/mediacms-io/mediacms/discussions
|
||||||
|
- **Docs**: https://docs.mediacms.io
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🎉 Enjoy MediaCMS!**
|
||||||
477
UPGRADE_TO_7.3.md
Normal file
477
UPGRADE_TO_7.3.md
Normal file
@@ -0,0 +1,477 @@
|
|||||||
|
# Upgrade Guide: MediaCMS 7.x to 7.3
|
||||||
|
|
||||||
|
**IMPORTANT: This is a major architectural change. Read this entire guide before upgrading.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Fresh Install (Not Upgrading)?
|
||||||
|
|
||||||
|
If you're starting fresh with 7.3, you don't need this guide!
|
||||||
|
|
||||||
|
**All you need:**
|
||||||
|
```bash
|
||||||
|
# 1. Download docker-compose.yaml
|
||||||
|
wget https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose.yaml
|
||||||
|
|
||||||
|
# 2. Start (creates everything automatically)
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 3. Done! Visit http://localhost
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional: Add customizations**
|
||||||
|
```bash
|
||||||
|
# Create custom/ directory
|
||||||
|
mkdir -p custom/static/{images,css}
|
||||||
|
|
||||||
|
# Download example settings
|
||||||
|
wget -O custom/local_settings.py.example \
|
||||||
|
https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/custom/local_settings.py.example
|
||||||
|
|
||||||
|
# Edit and use
|
||||||
|
cp custom/local_settings.py.example custom/local_settings.py
|
||||||
|
nano custom/local_settings.py
|
||||||
|
|
||||||
|
# Restart
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
See [`custom/README.md`](https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/custom/README.md) for customization options.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Upgrading from 7.x? Continue reading...
|
||||||
|
|
||||||
|
## What Changed in 7.3
|
||||||
|
|
||||||
|
### Architecture Changes
|
||||||
|
- **Before**: Monolithic container (supervisor + nginx + uwsgi + celery in one)
|
||||||
|
- **After**: Microservices (separate nginx, web, celery_beat, celery_short, celery_long containers)
|
||||||
|
|
||||||
|
### Volume Strategy Changes
|
||||||
|
- **Before**: Entire project directory mounted (`./:/home/mediacms.io/mediacms/`)
|
||||||
|
- **After**: Named volumes for data, bind mount only for `custom/` directory
|
||||||
|
|
||||||
|
### Specific Changes
|
||||||
|
|
||||||
|
| Component | Before (7.x) | After (7.3) |
|
||||||
|
|-----------|-------------|-------------|
|
||||||
|
| media_files | Bind mount `./media_files` | Named volume `media_files` |
|
||||||
|
| static files | Bind mount `./static` | Named volume `static_files` (built into image) |
|
||||||
|
| logs | Bind mount `./logs` | Named volume `logs` |
|
||||||
|
| postgres_data | `../postgres_data` | Named volume `postgres_data` |
|
||||||
|
| Custom config | `cms/local_settings.py` in mounted dir | `custom/local_settings.py` bind mount |
|
||||||
|
| Static collection | Runtime (via entrypoint) | Build time (in Dockerfile) |
|
||||||
|
| User | Root with gosu switch | www-data from start |
|
||||||
|
|
||||||
|
## What You Need for 7.3
|
||||||
|
|
||||||
|
**Minimal deployment - NO CODE REQUIRED:**
|
||||||
|
|
||||||
|
1. ✅ `docker-compose.yaml` (download from release or docs)
|
||||||
|
2. ✅ Docker images (pulled from Docker Hub)
|
||||||
|
3. ⚠️ `custom/` directory (only if you have customizations)
|
||||||
|
|
||||||
|
**That's it!** No git repo, no code checkout needed.
|
||||||
|
|
||||||
|
## Pre-Upgrade Checklist
|
||||||
|
|
||||||
|
### 1. Backup Everything
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop services
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Backup media files
|
||||||
|
tar -czf backup_media_$(date +%Y%m%d).tar.gz media_files/
|
||||||
|
|
||||||
|
# Backup database
|
||||||
|
docker compose up -d db
|
||||||
|
docker compose exec db pg_dump -U mediacms mediacms > backup_db_$(date +%Y%m%d).sql
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Backup logs (optional)
|
||||||
|
tar -czf backup_logs_$(date +%Y%m%d).tar.gz logs/
|
||||||
|
|
||||||
|
# Backup local settings if you had them
|
||||||
|
cp cms/local_settings.py backup_local_settings.py 2>/dev/null || echo "No local_settings.py found"
|
||||||
|
|
||||||
|
# Backup current docker-compose.yaml
|
||||||
|
cp docker-compose.yaml docker-compose.yaml.old
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Document Current Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Save current docker-compose version
|
||||||
|
git branch backup-pre-7.3-upgrade
|
||||||
|
|
||||||
|
# Document current state
|
||||||
|
docker compose ps > pre_upgrade_state.txt
|
||||||
|
docker compose config > pre_upgrade_config.yaml
|
||||||
|
df -h > pre_upgrade_disk_usage.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Check Disk Space
|
||||||
|
|
||||||
|
You'll need enough space for:
|
||||||
|
- Existing data (media_files, postgres_data)
|
||||||
|
- New Docker volumes (will copy data here)
|
||||||
|
- Database dump
|
||||||
|
|
||||||
|
```bash
|
||||||
|
du -sh media_files/ postgres_data/ logs/
|
||||||
|
df -h .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Upgrade Methods
|
||||||
|
|
||||||
|
### Method 1: Clean Migration (Recommended)
|
||||||
|
|
||||||
|
This method migrates your data to the new volume structure.
|
||||||
|
|
||||||
|
#### Step 1: Get New docker-compose.yaml
|
||||||
|
|
||||||
|
**Option A: Download from release**
|
||||||
|
```bash
|
||||||
|
# Download docker-compose.yaml for 7.3
|
||||||
|
wget https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose.yaml
|
||||||
|
|
||||||
|
# Or using curl
|
||||||
|
curl -O https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose.yaml
|
||||||
|
|
||||||
|
# Optional: Download HTTPS version
|
||||||
|
wget https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/docker-compose-cert.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option B: Copy from docs/release notes**
|
||||||
|
- Copy the docker-compose.yaml content from release notes
|
||||||
|
- Save as `docker-compose.yaml` in your deployment directory
|
||||||
|
|
||||||
|
#### Step 2: Prepare Custom Configuration (if needed)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create custom directory structure (only if you need customizations)
|
||||||
|
mkdir -p custom/static/{images,css}
|
||||||
|
touch custom/static/{images,css}/.gitkeep
|
||||||
|
|
||||||
|
# If you had local_settings.py, create it in custom/
|
||||||
|
if [ -f backup_local_settings.py ]; then
|
||||||
|
# Copy your old settings
|
||||||
|
cp backup_local_settings.py custom/local_settings.py
|
||||||
|
echo "✓ Migrated local_settings.py"
|
||||||
|
else
|
||||||
|
# Download example template (optional)
|
||||||
|
wget -O custom/local_settings.py.example \
|
||||||
|
https://raw.githubusercontent.com/mediacms-io/mediacms/v7.3/custom/local_settings.py.example
|
||||||
|
echo "Downloaded example template to custom/local_settings.py.example"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy any custom logos/css you had
|
||||||
|
# (adjust paths as needed for your old setup)
|
||||||
|
# cp my-old-logo.png custom/static/images/logo_dark.png
|
||||||
|
# cp my-custom.css custom/static/css/custom.css
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3: Start New Stack (Without Data)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull new images
|
||||||
|
docker compose pull
|
||||||
|
|
||||||
|
# Start database first
|
||||||
|
docker compose up -d db redis
|
||||||
|
|
||||||
|
# Wait for DB to be ready
|
||||||
|
sleep 10
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4: Restore Database
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copy backup into container
|
||||||
|
docker compose cp backup_db_*.sql db:/tmp/backup.sql
|
||||||
|
|
||||||
|
# Restore database
|
||||||
|
docker compose exec db psql -U mediacms mediacms < /tmp/backup.sql
|
||||||
|
|
||||||
|
# Or from host:
|
||||||
|
cat backup_db_*.sql | docker compose exec -T db psql -U mediacms mediacms
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 5: Restore Media Files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start all services (will create volumes)
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Find the volume name
|
||||||
|
docker volume ls | grep media_files
|
||||||
|
|
||||||
|
# Copy media files to volume
|
||||||
|
# Method A: Using a temporary container
|
||||||
|
docker run --rm \
|
||||||
|
-v $(pwd)/media_files:/source:ro \
|
||||||
|
-v mediacms_media_files:/dest \
|
||||||
|
alpine sh -c "cp -av /source/* /dest/"
|
||||||
|
|
||||||
|
# Method B: Using existing container
|
||||||
|
docker compose exec web sh -c "exit" # Ensure web is running
|
||||||
|
# Then copy from host
|
||||||
|
tar -C media_files -cf - . | docker compose exec -T web tar -C /home/mediacms.io/mediacms/media_files -xf -
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 6: Verify and Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
docker compose logs -f web
|
||||||
|
|
||||||
|
# Verify media files are accessible
|
||||||
|
docker compose exec web ls -la /home/mediacms.io/mediacms/media_files/
|
||||||
|
|
||||||
|
# Check database connection
|
||||||
|
docker compose exec web python manage.py dbshell
|
||||||
|
|
||||||
|
# Access the site
|
||||||
|
curl http://localhost
|
||||||
|
|
||||||
|
# Check admin panel
|
||||||
|
# Visit http://localhost/admin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: In-Place Migration with Symlinks (Advanced)
|
||||||
|
|
||||||
|
**Warning**: This is more complex but avoids data copying.
|
||||||
|
|
||||||
|
#### Step 1: Keep Old Data Locations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Modify docker-compose.yaml to mount old locations temporarily
|
||||||
|
# Add to appropriate services:
|
||||||
|
volumes:
|
||||||
|
- ./media_files:/home/mediacms.io/mediacms/media_files
|
||||||
|
- ./logs:/home/mediacms.io/mediacms/logs
|
||||||
|
# Instead of named volumes
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2: Gradually Migrate
|
||||||
|
|
||||||
|
After confirming everything works:
|
||||||
|
1. Copy data to named volumes
|
||||||
|
2. Remove bind mounts
|
||||||
|
3. Switch to named volumes
|
||||||
|
|
||||||
|
### Method 3: Fresh Install (If Possible)
|
||||||
|
|
||||||
|
If your MediaCMS instance is new or test:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup what you need
|
||||||
|
# ...
|
||||||
|
|
||||||
|
# Clean slate
|
||||||
|
docker compose down -v
|
||||||
|
rm -rf media_files/ logs/ static/
|
||||||
|
|
||||||
|
# Fresh start
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Post-Upgrade Steps
|
||||||
|
|
||||||
|
### 1. Verify Everything Works
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check all services are running
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
# Should see: migrations (exited 0), web, nginx, celery_beat, celery_short, celery_long, db, redis
|
||||||
|
|
||||||
|
# Check logs for errors
|
||||||
|
docker compose logs web
|
||||||
|
docker compose logs nginx
|
||||||
|
|
||||||
|
# Test upload functionality
|
||||||
|
# Test video encoding (check celery_long logs)
|
||||||
|
# Test frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Verify Media Files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check media files are accessible
|
||||||
|
docker compose exec web ls -lh /home/mediacms.io/mediacms/media_files/
|
||||||
|
|
||||||
|
# Check file counts match
|
||||||
|
# Old: ls media_files/ | wc -l
|
||||||
|
# New: docker compose exec web sh -c "ls /home/mediacms.io/mediacms/media_files/ | wc -l"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Verify Database
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check users
|
||||||
|
docker compose exec db psql -U mediacms mediacms -c "SELECT count(*) FROM users_user;"
|
||||||
|
|
||||||
|
# Check videos
|
||||||
|
docker compose exec db psql -U mediacms mediacms -c "SELECT count(*) FROM files_media;"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Update Backups
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Update your backup scripts for new volume locations
|
||||||
|
# Use: make backup-db (if Makefile target exists)
|
||||||
|
# Or: docker compose exec db pg_dump ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rollback Procedure
|
||||||
|
|
||||||
|
If something goes wrong:
|
||||||
|
|
||||||
|
### Quick Rollback
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop new version
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Restore old docker-compose file
|
||||||
|
mv docker-compose.yaml.old docker-compose.yaml
|
||||||
|
|
||||||
|
# Pull old images (if you had old image tags documented)
|
||||||
|
docker compose pull
|
||||||
|
|
||||||
|
# Start old version
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Full Rollback with Data Restore
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop everything
|
||||||
|
docker compose down -v
|
||||||
|
|
||||||
|
# Restore old docker-compose
|
||||||
|
mv docker-compose.yaml.old docker-compose.yaml
|
||||||
|
|
||||||
|
# Restore backups
|
||||||
|
tar -xzf backup_media_*.tar.gz -C ./media_files
|
||||||
|
cat backup_db_*.sql | docker compose exec -T db psql -U mediacms mediacms
|
||||||
|
|
||||||
|
# Start old version
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues & Solutions
|
||||||
|
|
||||||
|
### Issue: "Volume not found"
|
||||||
|
|
||||||
|
**Solution**: Volumes are created with project name prefix. Check:
|
||||||
|
```bash
|
||||||
|
docker volume ls
|
||||||
|
# Look for: mediacms_media_files, mediacms_static_files, etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Permission denied" on media files
|
||||||
|
|
||||||
|
**Solution**: Files must be owned by www-data (UID 33)
|
||||||
|
```bash
|
||||||
|
docker compose exec web chown -R www-data:www-data /home/mediacms.io/mediacms/media_files
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: Static files not loading
|
||||||
|
|
||||||
|
**Solution**: Rebuild image (collectstatic runs at build time)
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
docker compose build --no-cache web
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: Database connection refused
|
||||||
|
|
||||||
|
**Solution**: Check database is healthy
|
||||||
|
```bash
|
||||||
|
docker compose logs db
|
||||||
|
docker compose exec db pg_isready -U mediacms
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: Custom settings not loading
|
||||||
|
|
||||||
|
**Solution**: Check custom/local_settings.py exists and syntax
|
||||||
|
```bash
|
||||||
|
docker compose exec web cat /home/mediacms.io/mediacms/custom/local_settings.py
|
||||||
|
docker compose exec web python -m py_compile /home/mediacms.io/mediacms/custom/local_settings.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
### New Volume Performance
|
||||||
|
|
||||||
|
Named volumes are typically faster than bind mounts:
|
||||||
|
- **Before**: Filesystem overhead on host
|
||||||
|
- **After**: Direct container filesystem (better I/O)
|
||||||
|
|
||||||
|
### Monitoring Volume Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check volume sizes
|
||||||
|
docker system df -v
|
||||||
|
|
||||||
|
# Check specific volume
|
||||||
|
docker volume inspect mediacms_media_files
|
||||||
|
```
|
||||||
|
|
||||||
|
## New Backup Strategy
|
||||||
|
|
||||||
|
With named volumes, backups change:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Database backup
|
||||||
|
docker compose exec db pg_dump -U mediacms mediacms > backup.sql
|
||||||
|
|
||||||
|
# Media files backup
|
||||||
|
docker run --rm \
|
||||||
|
-v mediacms_media_files:/data:ro \
|
||||||
|
-v $(pwd):/backup \
|
||||||
|
alpine tar czf /backup/media_backup_$(date +%Y%m%d).tar.gz -C /data .
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use the Makefile:
|
||||||
|
```bash
|
||||||
|
make backup-db
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
If you encounter issues:
|
||||||
|
|
||||||
|
1. **Check logs**: `docker compose logs <service>`
|
||||||
|
2. **Check GitHub Issues**: Search for similar problems
|
||||||
|
3. **Rollback**: Use the rollback procedure above
|
||||||
|
4. **Report**: Open an issue with:
|
||||||
|
- Your docker-compose.yaml
|
||||||
|
- Output of `docker compose ps`
|
||||||
|
- Relevant logs
|
||||||
|
- Steps to reproduce
|
||||||
|
|
||||||
|
## Summary of Benefits
|
||||||
|
|
||||||
|
After upgrading to 7.3:
|
||||||
|
|
||||||
|
✅ **Better separation of concerns** - each service has one job
|
||||||
|
✅ **Easier scaling** - scale web/workers independently
|
||||||
|
✅ **Better security** - containers run as www-data, not root
|
||||||
|
✅ **Faster deployments** - static files built into image
|
||||||
|
✅ **Cleaner customization** - dedicated custom/ directory
|
||||||
|
✅ **Easier SSL setup** - docker-compose-cert.yaml overlay
|
||||||
|
✅ **Better volume management** - named volumes instead of bind mounts
|
||||||
|
|
||||||
|
## Timeline Recommendation
|
||||||
|
|
||||||
|
- **Small instance** (<100 videos): 30-60 minutes
|
||||||
|
- **Medium instance** (100-1000 videos): 1-3 hours
|
||||||
|
- **Large instance** (>1000 videos): Plan for several hours
|
||||||
|
|
||||||
|
Schedule during low-traffic period!
|
||||||
@@ -112,18 +112,22 @@ SITE_ID = 1
|
|||||||
# set new paths for svg or png if you want to override
|
# set new paths for svg or png if you want to override
|
||||||
# svg has priority over png, so if you want to use
|
# svg has priority over png, so if you want to use
|
||||||
# custom pngs and not svgs, remove the lines with svgs
|
# custom pngs and not svgs, remove the lines with svgs
|
||||||
# or set as empty strings
|
# Logo paths (served from /static/)
|
||||||
|
# Default logos are built into the image
|
||||||
|
# To customize: place files in custom/static/images/ and reference as /custom/static/images/file.png
|
||||||
|
# or set as empty strings to disable
|
||||||
# example:
|
# example:
|
||||||
|
# PORTAL_LOGO_DARK_PNG = "/custom/static/images/my-logo.png"
|
||||||
# PORTAL_LOGO_DARK_SVG = ""
|
# PORTAL_LOGO_DARK_SVG = ""
|
||||||
# PORTAL_LOGO_LIGHT_SVG = ""
|
|
||||||
# place the files on static/images folder
|
|
||||||
PORTAL_LOGO_DARK_SVG = "/static/images/logo_dark.svg"
|
PORTAL_LOGO_DARK_SVG = "/static/images/logo_dark.svg"
|
||||||
PORTAL_LOGO_DARK_PNG = "/static/images/logo_dark.png"
|
PORTAL_LOGO_DARK_PNG = "/static/images/logo_dark.png"
|
||||||
PORTAL_LOGO_LIGHT_SVG = "/static/images/logo_light.svg"
|
PORTAL_LOGO_LIGHT_SVG = "/static/images/logo_light.svg"
|
||||||
PORTAL_LOGO_LIGHT_PNG = "/static/images/logo_dark.png"
|
PORTAL_LOGO_LIGHT_PNG = "/static/images/logo_dark.png"
|
||||||
|
|
||||||
# paths to extra css files to be included, eg "/static/css/custom.css"
|
# Extra CSS files to include in templates
|
||||||
# place css inside static/css folder
|
# To add custom CSS: place files in custom/static/css/ and add paths here
|
||||||
|
# Use /custom/static/ prefix for files in custom/ directory
|
||||||
|
# Example: EXTRA_CSS_PATHS = ["/custom/static/css/custom.css"]
|
||||||
EXTRA_CSS_PATHS = []
|
EXTRA_CSS_PATHS = []
|
||||||
# protection agains anonymous users
|
# protection agains anonymous users
|
||||||
# per ip address limit, for actions as like/dislike/report
|
# per ip address limit, for actions as like/dislike/report
|
||||||
@@ -179,6 +183,10 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
STATIC_URL = "/static/" # where js/css files are stored on the filesystem
|
STATIC_URL = "/static/" # where js/css files are stored on the filesystem
|
||||||
MEDIA_URL = "/media/" # URL where static files are served from the server
|
MEDIA_URL = "/media/" # URL where static files are served from the server
|
||||||
STATIC_ROOT = BASE_DIR + "/static/"
|
STATIC_ROOT = BASE_DIR + "/static/"
|
||||||
|
# Additional locations for static files
|
||||||
|
# Note: custom/static is NOT included here because it's served directly by nginx
|
||||||
|
# at /custom/static/ and doesn't need collectstatic
|
||||||
|
STATICFILES_DIRS = []
|
||||||
# where uploaded + encoded media are stored
|
# where uploaded + encoded media are stored
|
||||||
MEDIA_ROOT = BASE_DIR + "/media_files/"
|
MEDIA_ROOT = BASE_DIR + "/media_files/"
|
||||||
|
|
||||||
@@ -589,13 +597,15 @@ WHISPER_MODEL = "base"
|
|||||||
SIDEBAR_FOOTER_TEXT = ""
|
SIDEBAR_FOOTER_TEXT = ""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# keep a local_settings.py file for local overrides
|
# Load custom settings from custom/local_settings.py
|
||||||
from .local_settings import * # noqa
|
import sys
|
||||||
|
sys.path.insert(0, BASE_DIR)
|
||||||
|
from custom.local_settings import * # noqa
|
||||||
|
|
||||||
# ALLOWED_HOSTS needs a url/ip
|
# ALLOWED_HOSTS needs a url/ip
|
||||||
ALLOWED_HOSTS.append(FRONTEND_HOST.replace("http://", "").replace("https://", ""))
|
ALLOWED_HOSTS.append(FRONTEND_HOST.replace("http://", "").replace("https://", ""))
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# local_settings not in use
|
# custom/local_settings.py not in use or empty
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Don't add new settings below that could be overridden in local_settings.py!!!
|
# Don't add new settings below that could be overridden in local_settings.py!!!
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ server {
|
|||||||
alias /var/www/static ;
|
alias /var/www/static ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /custom/static {
|
||||||
|
alias /var/www/custom ;
|
||||||
|
}
|
||||||
|
|
||||||
location /media/original {
|
location /media/original {
|
||||||
alias /var/www/media/original;
|
alias /var/www/media/original;
|
||||||
}
|
}
|
||||||
|
|||||||
0
custom/.gitkeep
Normal file
0
custom/.gitkeep
Normal file
238
custom/README.md
Normal file
238
custom/README.md
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
# Custom Configuration
|
||||||
|
|
||||||
|
This directory allows you to customize MediaCMS without modifying the codebase or rebuilding images.
|
||||||
|
|
||||||
|
## How It Works - Production Ready!
|
||||||
|
|
||||||
|
**The Flow:**
|
||||||
|
|
||||||
|
```
|
||||||
|
1. CI/CD builds base image: docker build (no custom files)
|
||||||
|
↓
|
||||||
|
Pushes to Docker Hub
|
||||||
|
|
||||||
|
2. Production pulls image: docker compose pull
|
||||||
|
↓
|
||||||
|
Mounts custom/ directory
|
||||||
|
|
||||||
|
3. You add files: custom/static/css/custom.css
|
||||||
|
custom/static/images/logo.png
|
||||||
|
↓
|
||||||
|
Nginx serves directly!
|
||||||
|
|
||||||
|
4. You reference in settings: EXTRA_CSS_PATHS = ["/custom/static/css/custom.css"]
|
||||||
|
PORTAL_LOGO_DARK_PNG = "/custom/static/images/logo.png"
|
||||||
|
↓
|
||||||
|
Restart containers
|
||||||
|
|
||||||
|
5. Done! No rebuild needed!
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Points:**
|
||||||
|
- ✅ Files go in `custom/static/` on your host
|
||||||
|
- ✅ Nginx serves them directly from `/custom/static/` URL
|
||||||
|
- ✅ **NO rebuild needed** - just restart containers!
|
||||||
|
- ✅ Works with pre-built images from Docker Hub
|
||||||
|
- ✅ Perfect for production deployments
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Option 1: No Customization (Default)
|
||||||
|
Just run docker compose - everything works out of the box:
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: With Customization
|
||||||
|
Add your custom files, then restart:
|
||||||
|
```bash
|
||||||
|
# 1. Copy example settings
|
||||||
|
cp custom/local_settings.py.example custom/local_settings.py
|
||||||
|
|
||||||
|
# 2. Edit settings
|
||||||
|
nano custom/local_settings.py
|
||||||
|
|
||||||
|
# 3. Restart containers (no rebuild!)
|
||||||
|
docker compose restart web celery_beat celery_short celery_long
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization Options
|
||||||
|
|
||||||
|
### 1. Django Settings (`local_settings.py`)
|
||||||
|
|
||||||
|
**Create the file:**
|
||||||
|
```bash
|
||||||
|
cp custom/local_settings.py.example custom/local_settings.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**Edit with your settings:**
|
||||||
|
```python
|
||||||
|
# custom/local_settings.py
|
||||||
|
DEBUG = False
|
||||||
|
ALLOWED_HOSTS = ['example.com']
|
||||||
|
PORTAL_NAME = "My Media Site"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Apply changes (restart only - no rebuild):**
|
||||||
|
```bash
|
||||||
|
docker compose restart web celery_beat celery_short celery_long
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Custom Logo
|
||||||
|
|
||||||
|
**Add your logo:**
|
||||||
|
```bash
|
||||||
|
cp ~/my-logo.png custom/static/images/logo_dark.png
|
||||||
|
```
|
||||||
|
|
||||||
|
**Reference it in settings:**
|
||||||
|
```bash
|
||||||
|
cat >> custom/local_settings.py <<EOF
|
||||||
|
PORTAL_LOGO_DARK_PNG = "/custom/static/images/logo_dark.png"
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Restart (no rebuild needed!):**
|
||||||
|
```bash
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Custom CSS
|
||||||
|
|
||||||
|
**Create CSS file:**
|
||||||
|
```bash
|
||||||
|
cat > custom/static/css/custom.css <<EOF
|
||||||
|
body {
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Reference it in settings:**
|
||||||
|
```bash
|
||||||
|
cat >> custom/local_settings.py <<EOF
|
||||||
|
EXTRA_CSS_PATHS = ["/custom/static/css/custom.css"]
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Restart (no rebuild needed!):**
|
||||||
|
```bash
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
custom/
|
||||||
|
├── README.md # This file
|
||||||
|
├── local_settings.py.example # Template (copy to local_settings.py)
|
||||||
|
├── local_settings.py # Your settings (gitignored)
|
||||||
|
└── static/
|
||||||
|
├── images/ # Custom logos (gitignored)
|
||||||
|
│ └── logo_dark.png
|
||||||
|
└── css/ # Custom CSS (gitignored)
|
||||||
|
└── custom.css
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
✅ **No rebuild needed** - nginx serves custom/ files directly
|
||||||
|
✅ **Works with pre-built images** - perfect for production
|
||||||
|
✅ **Files are gitignored** - your customizations won't be committed
|
||||||
|
✅ **Settings need restart only** - just restart containers
|
||||||
|
✅ **Static files also just restart** - served directly by nginx
|
||||||
|
|
||||||
|
## Complete Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create settings file
|
||||||
|
cp custom/local_settings.py.example custom/local_settings.py
|
||||||
|
|
||||||
|
# 2. Add custom logo
|
||||||
|
cp ~/logo.png custom/static/images/logo_dark.png
|
||||||
|
|
||||||
|
# 3. Add custom CSS
|
||||||
|
echo "body { background: #f5f5f5; }" > custom/static/css/custom.css
|
||||||
|
|
||||||
|
# 4. Configure settings to use them
|
||||||
|
cat >> custom/local_settings.py <<EOF
|
||||||
|
|
||||||
|
# Custom branding
|
||||||
|
PORTAL_NAME = "My Media Portal"
|
||||||
|
PORTAL_LOGO_DARK_PNG = "/custom/static/images/logo_dark.png"
|
||||||
|
EXTRA_CSS_PATHS = ["/custom/static/css/custom.css"]
|
||||||
|
|
||||||
|
# Security
|
||||||
|
DEBUG = False
|
||||||
|
ALLOWED_HOSTS = ['media.example.com']
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 5. Apply changes (just restart!)
|
||||||
|
docker compose restart web
|
||||||
|
|
||||||
|
# Done! No rebuild needed.
|
||||||
|
```
|
||||||
|
|
||||||
|
## URL Paths Explained
|
||||||
|
|
||||||
|
| Your file | nginx serves at | You reference as |
|
||||||
|
|-----------|----------------|------------------|
|
||||||
|
| `custom/static/css/custom.css` | `http://localhost/custom/static/css/custom.css` | `"/custom/static/css/custom.css"` |
|
||||||
|
| `custom/static/images/logo.png` | `http://localhost/custom/static/images/logo.png` | `"/custom/static/images/logo.png"` |
|
||||||
|
|
||||||
|
**Why `/custom/static/`?**
|
||||||
|
- Distinguishes from core `/static/` (built into image)
|
||||||
|
- Allows nginx to serve from different mount point
|
||||||
|
- No rebuild needed when files change
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Changes not appearing?**
|
||||||
|
- Restart containers: `docker compose restart web nginx`
|
||||||
|
- Check nginx has custom/ mounted: `docker compose exec nginx ls /var/www/custom`
|
||||||
|
- Check file exists: `docker compose exec nginx ls /var/www/custom/css/`
|
||||||
|
- Test URL: `curl http://localhost/custom/static/css/custom.css`
|
||||||
|
|
||||||
|
**Import errors?**
|
||||||
|
- Make sure `local_settings.py` has valid Python syntax
|
||||||
|
- Check logs: `docker compose logs web`
|
||||||
|
|
||||||
|
**Logo not showing?**
|
||||||
|
- Verify file is in `custom/static/images/`
|
||||||
|
- Check path in `local_settings.py` uses `/custom/static/` prefix
|
||||||
|
- Restart web container: `docker compose restart web`
|
||||||
|
|
||||||
|
## Advanced: Multiple CSS Files
|
||||||
|
|
||||||
|
```python
|
||||||
|
# custom/local_settings.py
|
||||||
|
EXTRA_CSS_PATHS = [
|
||||||
|
"/custom/static/css/colors.css",
|
||||||
|
"/custom/static/css/fonts.css",
|
||||||
|
"/custom/static/css/layout.css",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced: Environment-Specific Settings
|
||||||
|
|
||||||
|
```python
|
||||||
|
# custom/local_settings.py
|
||||||
|
import os
|
||||||
|
|
||||||
|
if os.getenv('ENVIRONMENT') == 'production':
|
||||||
|
DEBUG = False
|
||||||
|
ALLOWED_HOSTS = ['media.example.com']
|
||||||
|
else:
|
||||||
|
DEBUG = True
|
||||||
|
ALLOWED_HOSTS = ['*']
|
||||||
|
```
|
||||||
|
|
||||||
|
Then set in docker-compose.yaml:
|
||||||
|
```yaml
|
||||||
|
web:
|
||||||
|
environment:
|
||||||
|
ENVIRONMENT: production
|
||||||
|
```
|
||||||
57
custom/local_settings.py.example
Normal file
57
custom/local_settings.py.example
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# MediaCMS Local Settings Example
|
||||||
|
# Copy this file to local_settings.py and customize as needed:
|
||||||
|
# cp custom/local_settings.py.example custom/local_settings.py
|
||||||
|
|
||||||
|
# ===== Basic Settings =====
|
||||||
|
|
||||||
|
# DEBUG = False
|
||||||
|
# ALLOWED_HOSTS = ['example.com', 'www.example.com']
|
||||||
|
# PORTAL_NAME = "My Media Portal"
|
||||||
|
|
||||||
|
# ===== Database Settings =====
|
||||||
|
|
||||||
|
# DATABASES = {
|
||||||
|
# 'default': {
|
||||||
|
# 'ENGINE': 'django.db.backends.postgresql',
|
||||||
|
# 'NAME': 'mediacms',
|
||||||
|
# 'USER': 'mediacms',
|
||||||
|
# 'PASSWORD': 'mediacms',
|
||||||
|
# 'HOST': 'db',
|
||||||
|
# 'PORT': '5432',
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# ===== Custom Branding =====
|
||||||
|
|
||||||
|
# Custom logos (place files in custom/static/images/)
|
||||||
|
# Nginx serves these directly from /custom/static/ (no rebuild needed!)
|
||||||
|
# PORTAL_LOGO_DARK_SVG = "/custom/static/images/logo_dark.svg"
|
||||||
|
# PORTAL_LOGO_DARK_PNG = "/custom/static/images/logo_dark.png"
|
||||||
|
# PORTAL_LOGO_LIGHT_SVG = "/custom/static/images/logo_light.svg"
|
||||||
|
# PORTAL_LOGO_LIGHT_PNG = "/custom/static/images/logo_light.png"
|
||||||
|
|
||||||
|
# Custom CSS (place files in custom/static/css/)
|
||||||
|
# Nginx serves these directly from /custom/static/ (no rebuild needed!)
|
||||||
|
# EXTRA_CSS_PATHS = ["/custom/static/css/custom.css"]
|
||||||
|
|
||||||
|
# ===== Email Settings =====
|
||||||
|
|
||||||
|
# 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@example.com'
|
||||||
|
# EMAIL_HOST_PASSWORD = 'your-password'
|
||||||
|
# DEFAULT_FROM_EMAIL = 'noreply@example.com'
|
||||||
|
|
||||||
|
# ===== Security Settings =====
|
||||||
|
|
||||||
|
# SECRET_KEY = 'your-secret-key-here'
|
||||||
|
# SECURE_SSL_REDIRECT = True
|
||||||
|
# SESSION_COOKIE_SECURE = True
|
||||||
|
# CSRF_COOKIE_SECURE = True
|
||||||
|
|
||||||
|
# ===== Other Settings =====
|
||||||
|
|
||||||
|
# Any other Django setting can be overridden here
|
||||||
|
# See cms/settings.py for available settings
|
||||||
0
custom/static/.gitkeep
Normal file
0
custom/static/.gitkeep
Normal file
0
custom/static/css/.gitkeep
Normal file
0
custom/static/css/.gitkeep
Normal file
0
custom/static/images/.gitkeep
Normal file
0
custom/static/images/.gitkeep
Normal file
@@ -1,9 +1,18 @@
|
|||||||
version: "3.8"
|
version: "3.8"
|
||||||
|
|
||||||
# Production setup with automatic HTTPS via Let's Encrypt
|
# HTTPS/SSL certificate overlay for docker-compose.yaml
|
||||||
# Uses https://github.com/nginx-proxy/acme-companion
|
# Uses nginx-proxy with Let's Encrypt via acme-companion
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# docker compose -f docker-compose.yaml -f docker-compose-cert.yaml up -d
|
||||||
|
#
|
||||||
|
# Before running:
|
||||||
|
# 1. Change VIRTUAL_HOST to your domain
|
||||||
|
# 2. Change LETSENCRYPT_HOST to your domain
|
||||||
|
# 3. Change LETSENCRYPT_EMAIL to your email
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
# Reverse proxy with automatic SSL
|
||||||
nginx-proxy:
|
nginx-proxy:
|
||||||
image: nginxproxy/nginx-proxy
|
image: nginxproxy/nginx-proxy
|
||||||
container_name: nginx-proxy
|
container_name: nginx-proxy
|
||||||
@@ -20,6 +29,7 @@ services:
|
|||||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
- ./config/nginx-proxy/client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro
|
- ./config/nginx-proxy/client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro
|
||||||
|
|
||||||
|
# Let's Encrypt certificate manager
|
||||||
acme-companion:
|
acme-companion:
|
||||||
image: nginxproxy/acme-companion
|
image: nginxproxy/acme-companion
|
||||||
container_name: nginx-proxy-acme
|
container_name: nginx-proxy-acme
|
||||||
@@ -31,131 +41,22 @@ services:
|
|||||||
- acme:/etc/acme.sh
|
- acme:/etc/acme.sh
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
|
||||||
migrations:
|
# Override nginx to work with nginx-proxy
|
||||||
image: mediacms/mediacms:7.3
|
|
||||||
command: ["/bin/bash", "/home/mediacms.io/mediacms/scripts/run-migrations.sh"]
|
|
||||||
environment:
|
|
||||||
ADMIN_USER: 'admin'
|
|
||||||
ADMIN_EMAIL: 'admin@localhost'
|
|
||||||
# ADMIN_PASSWORD: 'uncomment_and_set_password_here'
|
|
||||||
restart: "no"
|
|
||||||
depends_on:
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- static_files:/home/mediacms.io/mediacms/static_files
|
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
|
||||||
|
|
||||||
web:
|
|
||||||
image: mediacms/mediacms:7.3
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
|
||||||
- "9000"
|
|
||||||
depends_on:
|
|
||||||
migrations:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- static_files:/home/mediacms.io/mediacms/static_files
|
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
image: mediacms/mediacms-nginx:7.3
|
|
||||||
restart: unless-stopped
|
|
||||||
expose:
|
expose:
|
||||||
- "80"
|
- "80"
|
||||||
|
ports: [] # Remove ports, nginx-proxy handles external access
|
||||||
environment:
|
environment:
|
||||||
# These are required for nginx-proxy to route traffic correctly
|
# CHANGE THESE VALUES:
|
||||||
VIRTUAL_HOST: 'mediacms.example.com' # CHANGE THIS to your domain
|
VIRTUAL_HOST: 'mediacms.example.com'
|
||||||
LETSENCRYPT_HOST: 'mediacms.example.com' # CHANGE THIS to your domain
|
LETSENCRYPT_HOST: 'mediacms.example.com'
|
||||||
LETSENCRYPT_EMAIL: 'admin@example.com' # CHANGE THIS to your email
|
LETSENCRYPT_EMAIL: 'admin@example.com'
|
||||||
depends_on:
|
|
||||||
- web
|
|
||||||
volumes:
|
|
||||||
- static_files:/var/www/static:ro
|
|
||||||
- media_files:/var/www/media:ro
|
|
||||||
- logs:/var/log/mediacms
|
|
||||||
|
|
||||||
celery_beat:
|
|
||||||
image: mediacms/mediacms-worker:7.3
|
|
||||||
restart: unless-stopped
|
|
||||||
command: ["/home/mediacms.io/bin/celery", "-A", "cms", "beat", "--loglevel=INFO"]
|
|
||||||
depends_on:
|
|
||||||
migrations:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
|
||||||
|
|
||||||
celery_short:
|
|
||||||
image: mediacms/mediacms-worker:7.3
|
|
||||||
restart: unless-stopped
|
|
||||||
command: ["/home/mediacms.io/bin/celery", "-A", "cms", "worker", "-Q", "short_tasks", "-c", "10", "--soft-time-limit=300", "--loglevel=INFO", "-n", "short@%h"]
|
|
||||||
depends_on:
|
|
||||||
migrations:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
|
||||||
|
|
||||||
celery_long:
|
|
||||||
image: mediacms/mediacms-worker:7.3
|
|
||||||
# To use extra codecs, change image to: mediacms/mediacms-worker:7.3-full
|
|
||||||
restart: unless-stopped
|
|
||||||
command: ["/home/mediacms.io/bin/celery", "-A", "cms", "worker", "-Q", "long_tasks", "-c", "1", "-Ofair", "--prefetch-multiplier=1", "--loglevel=INFO", "-n", "long@%h"]
|
|
||||||
depends_on:
|
|
||||||
migrations:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: postgres:17.2-alpine
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: mediacms
|
|
||||||
POSTGRES_PASSWORD: mediacms
|
|
||||||
POSTGRES_DB: mediacms
|
|
||||||
TZ: Europe/London
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:alpine
|
|
||||||
restart: unless-stopped
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "redis-cli", "ping"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
# nginx-proxy volumes
|
||||||
conf:
|
conf:
|
||||||
vhost:
|
vhost:
|
||||||
html:
|
html:
|
||||||
dhparam:
|
dhparam:
|
||||||
certs:
|
certs:
|
||||||
acme:
|
acme:
|
||||||
postgres_data:
|
|
||||||
static_files:
|
|
||||||
media_files:
|
|
||||||
logs:
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ services:
|
|||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./custom:/home/mediacms.io/mediacms/custom:ro
|
||||||
- static_files:/home/mediacms.io/mediacms/static
|
- static_files:/home/mediacms.io/mediacms/static
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
- media_files:/home/mediacms.io/mediacms/media_files
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
- logs:/home/mediacms.io/mediacms/logs
|
||||||
@@ -32,6 +33,7 @@ services:
|
|||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./custom:/home/mediacms.io/mediacms/custom:ro
|
||||||
- static_files:/home/mediacms.io/mediacms/static
|
- static_files:/home/mediacms.io/mediacms/static
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
- media_files:/home/mediacms.io/mediacms/media_files
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
- logs:/home/mediacms.io/mediacms/logs
|
||||||
@@ -44,6 +46,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- web
|
- web
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./custom/static:/var/www/custom:ro
|
||||||
- static_files:/var/www/static:ro
|
- static_files:/var/www/static:ro
|
||||||
- media_files:/var/www/media:ro
|
- media_files:/var/www/media:ro
|
||||||
- logs:/var/log/mediacms
|
- logs:/var/log/mediacms
|
||||||
@@ -58,6 +61,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./custom:/home/mediacms.io/mediacms/custom:ro
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
- media_files:/home/mediacms.io/mediacms/media_files
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
- logs:/home/mediacms.io/mediacms/logs
|
||||||
|
|
||||||
@@ -71,6 +75,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./custom:/home/mediacms.io/mediacms/custom:ro
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
- media_files:/home/mediacms.io/mediacms/media_files
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
- logs:/home/mediacms.io/mediacms/logs
|
||||||
|
|
||||||
@@ -85,6 +90,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./custom:/home/mediacms.io/mediacms/custom:ro
|
||||||
- media_files:/home/mediacms.io/mediacms/media_files
|
- media_files:/home/mediacms.io/mediacms/media_files
|
||||||
- logs:/home/mediacms.io/mediacms/logs
|
- logs:/home/mediacms.io/mediacms/logs
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Fix permissions on volume mounts
|
|
||||||
chown -R www-data:www-data \
|
|
||||||
/home/mediacms.io/mediacms/logs \
|
|
||||||
/home/mediacms.io/mediacms/media_files \
|
|
||||||
/home/mediacms.io/mediacms/static \
|
|
||||||
2>/dev/null || true
|
|
||||||
|
|
||||||
# Run as www-data user
|
|
||||||
exec gosu www-data "$@"
|
|
||||||
@@ -46,10 +46,6 @@ else
|
|||||||
echo "========================================="
|
echo "========================================="
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect static files
|
|
||||||
echo "Collecting static files..."
|
|
||||||
$PYTHON manage.py collectstatic --noinput
|
|
||||||
|
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo "Migrations completed successfully!"
|
echo "Migrations completed successfully!"
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
|
|||||||
Reference in New Issue
Block a user