A production-ready Ghost blog platform configured with MinIO object storage for media files, using Docker Compose for container orchestration.
This file covers local development and testing. For deployment to Dokku, see DOKKU_DEPLOYMENT.md.
This project sets up a complete Ghost blogging platform with the following components:
- Ghost: Version 6.7.0 - Modern publishing platform
- MySQL: Version 8.4.7 - Database for content management
- MinIO: S3-compatible object storage for media files
- Custom Storage Adapter: Object store adapter for S3-compatible storage
- Docker Engine
- Docker Compose
- At least 2GB of RAM available
- Clone this repository
- Copy the sample environment file:
cp .env.sample .env
- Review and customize the environment variables in
.envas needed - Start the services:
docker compose up
- Access Ghost at
http://localhost:8069 - Access MinIO Console at
http://localhost:9001
The .env file contains configuration for all services:
MinIO Configuration:
MINIO_ROOT_USER- MinIO admin usernameMINIO_ROOT_PASSWORD- MinIO admin passwordMINIO_ENDPOINT- MinIO endpoint URLMINIO_BUCKET_NAME- Bucket name for media storageMINIO_ACCESS_KEY- Access key for object storageMINIO_SECRET_KEY- Secret key for object storageMINIO_REGION- Region for object storageMINIO_USE_SSL- SSL usage flag (true/false)
MySQL Configuration:
MYSQL_HOST- Database host nameMYSQL_ROOT_PASSWORD- Root password for MySQLMYSQL_DATABASE- Database name
Ghost Configuration:
url- Public URL for the Ghost instance- Database connection settings
- Image optimization settings
- Object storage adapter settings
- Ghost: Runs on port 8069 (mapped from 2368)
- MySQL: Runs on port 13306 (mapped from 3306)
- MinIO: Runs on ports 9000 (API) and 9001 (Console)
The system uses a custom object storage adapter to store media files in MinIO instead of the local filesystem. This setup provides:
- Scalable media storage
- Better separation of concerns
- Easy backup and migration
- S3-compatible storage backend
The following volumes are created for data persistence:
ghost- Ghost content (themes, apps, images)db- MySQL database dataminio_data- MinIO object storage data
To build and run the application:
# Build and start all services
docker compose up --build -d
# View logs
docker compose logs -f
# Stop services
docker compose down
# Stop and remove volumes (data will be lost)
docker compose down -v- Ghost fails to start: Check that MySQL and MinIO are healthy before Ghost starts
- Media upload fails: Verify MinIO connectivity and bucket permissions
- Database connection errors: Check MySQL health and credentials in
.env - MinIO not accessible: Confirm that the initialization container completed successfully
Each service includes health checks:
- MySQL: Pings the database every 7 seconds
- MinIO: Checks health endpoint every 10 seconds
- Ghost: Starts after both MySQL and MinIO are healthy
View service logs with:
docker compose logs ghost
docker compose logs db
docker compose logs minio