Multilingual CMS with SvelteKit admin panel, Laravel API, and Go microservices in one container.
2.6K
A multilingual content management system with SvelteKit frontend and Laravel backend, packaged as a unified Docker container.
This unified container includes:
docker pull powerit/cms:latest
The CMS requires these external services to run:
| Service | Image | Purpose | Required |
|---|---|---|---|
| PostgreSQL | postgres:16-alpine | Database | Yes |
| Redis | redis:7-alpine | Cache, sessions, queues | Yes |
| MinIO | minio/minio:latest | S3-compatible file storage | Yes |
| Meilisearch | getmeili/meilisearch:v1.10 | Full-text search | Yes |
| ClamAV | clamav/clamav:latest | Antivirus scanning | Optional |
Create a docker-compose.yml:
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: cms_api
POSTGRES_USER: cms_user
POSTGRES_PASSWORD: your_secure_password
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U cms_user -d cms_api"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
command: redis-server --requirepass "your_redis_password" --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
minio:
image: minio/minio:latest
restart: unless-stopped
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: your_minio_password
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 20s
retries: 3
meilisearch:
image: getmeili/meilisearch:v1.10
restart: unless-stopped
environment:
MEILI_MASTER_KEY: your_meilisearch_key
MEILI_NO_ANALYTICS: "true"
MEILI_ENV: production
volumes:
- meilisearch_data:/meili_data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7700/health"]
interval: 10s
timeout: 5s
retries: 5
clamav:
image: clamav/clamav:latest
restart: unless-stopped
volumes:
- clamav_data:/var/lib/clamav
healthcheck:
test: ["CMD", "clamdscan", "--ping", "3"]
interval: 60s
timeout: 30s
retries: 5
start_period: 300s
cms:
image: powerit/cms:latest
restart: unless-stopped
ports:
- "80:80"
environment:
# Application
APP_NAME: CMS
APP_ENV: production
APP_DEBUG: "false"
APP_URL: http://localhost
APP_KEY: base64:your_generated_app_key_here
# Database
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_PORT: 5432
DB_DATABASE: cms_api
DB_USERNAME: cms_user
DB_PASSWORD: your_secure_password
# Redis
REDIS_HOST: redis
REDIS_PASSWORD: your_redis_password
REDIS_PORT: 6379
# Cache & Queue
CACHE_STORE: redis
SESSION_DRIVER: redis
QUEUE_CONNECTION: redis
# MinIO
MINIO_ENDPOINT: http://minio:9000
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: your_minio_password
MINIO_BUCKET: media
MINIO_URL: http://localhost:9000/media
# ClamAV
CLAMAV_HOST: clamav
CLAMAV_PORT: 3310
CLAMAV_ENABLED: "true"
# Meilisearch
MEILISEARCH_HOST: http://meilisearch:7700
MEILISEARCH_KEY: your_meilisearch_key
# Mail (configure for your SMTP provider)
MAIL_MAILER: smtp
MAIL_HOST: smtp.example.com
MAIL_PORT: 587
MAIL_USERNAME: your_mail_user
MAIL_PASSWORD: your_mail_password
MAIL_ENCRYPTION: tls
MAIL_FROM_ADDRESS: [email protected]
MAIL_FROM_NAME: CMS
# Frontend URLs
VITE_API_URL: http://localhost/api/v1
PUBLIC_API_URL: http://127.0.0.1/api/v1
ORIGIN: http://localhost
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
meilisearch:
condition: service_healthy
clamav:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
postgres_data:
redis_data:
minio_data:
meilisearch_data:
clamav_data:
Before starting, generate a Laravel application key:
# Generate a random key
echo "base64:$(openssl rand -base64 32)"
Add this to your APP_KEY environment variable.
docker compose up -d
After the containers are healthy:
docker compose exec cms php /var/www/api/artisan migrate --force
| Variable | Description | Example |
|---|---|---|
APP_KEY | Laravel encryption key | base64:... |
DB_PASSWORD | PostgreSQL password | secure_password |
DB_DATABASE | Database name | cms_api |
DB_USERNAME | Database user | cms_user |
| Variable | Default | Description |
|---|---|---|
APP_NAME | CMS | Application name |
APP_ENV | production | Environment |
APP_DEBUG | false | Debug mode |
REDIS_PASSWORD | `` | Redis password |
CLAMAV_ENABLED | true | Enable virus scanning |
MEILISEARCH_KEY | masterKey123 | Meilisearch API key |
| Port | Service | Description |
|---|---|---|
| 80 | Nginx | Main entry point (Admin + API) |
| 3000 | Node.js | Admin SvelteKit (internal) |
| 9000 | PHP-FPM | Laravel API (internal) |
| 8080 | Go | Media Processor (internal) |
| 50051 | gRPC | Analytics service (internal) |
Only port 80 needs to be exposed externally.
docker compose logs -f cms
docker compose exec cms php /var/www/api/artisan <command>
docker compose exec cms php /var/www/api/artisan cache:clear
docker compose exec cms php /var/www/api/artisan config:clear
docker compose exec cms php /var/www/api/artisan route:clear
docker compose exec cms php /var/www/api/artisan view:clear
docker compose exec cms bash
docker compose exec cms php /var/www/api/artisan db:seed --force
Clone the repository and build:
git clone https://github.com/powerit/cms.git
cd cms
make release-build
Or with custom registry:
make release-full DOCKER_REGISTRY=docker.io/yourusername DOCKER_IMAGE=cms
latest - Latest stable releasex.y.z - Specific version (e.g., 0.1.0)<git-sha> - Specific commit (e.g., fba1496)MIT License
Content type
Image
Digest
sha256:498d1eeee…
Size
205.1 MB
Last updated
8 months ago
docker pull popcornrus/cms