Use this pattern for local development, staging, or controlled lab environments. Updated for current best practices with MariaDB 11.4+.
sudo mkdir -p /opt/mariadb
cd /opt/mariadb
compose.yaml (Production-Ready)services:
mariadb:
image: mariadb:11.4 # Pin to specific version in production
restart: unless-stopped
ports:
- "3306:3306"
environment:
- MARIADB_ROOT_PASSWORD=change-me # Use docker secrets in production
- MARIADB_DATABASE=appdb
- MARIADB_USER=appuser
- MARIADB_PASSWORD=change-me-app
volumes:
- ./data:/var/lib/mysql
- ./config:/etc/mysql/conf.d # Mount custom configuration
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
networks:
- mariadb-network
# For production, consider adding resource limits
# deploy:
# resources:
# limits:
# memory: 1G
# reservations:
# memory: 512M
networks:
mariadb-network:
driver: bridge
compose.yamlFor production environments, use this more secure and optimized configuration:
services:
mariadb:
image: mariadb:11.4.10 # Pin to specific version
restart: unless-stopped
# Don't expose port directly - use a reverse proxy or VPN
# ports:
# - "3306:3306"
environment:
- MARIADB_ROOT_PASSWORD_FILE=/run/secrets/db_root_password
- MARIADB_DATABASE=appdb
- MARIADB_USER=appuser
- MARIADB_PASSWORD_FILE=/run/secrets/db_app_password
volumes:
- mariadb_data:/var/lib/mysql
- ./custom.cnf:/etc/mysql/conf.d/custom.cnf:ro
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
networks:
- internal
# Resource limits
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
volumes:
mariadb_data:
networks:
internal:
driver: bridge
internal: true # No external connectivity
secrets:
db_root_password:
file: ./secrets/root_password.txt
db_app_password:
file: ./secrets/app_password.txt
Key environment variables for MariaDB Docker container:
MARIADB_ROOT_PASSWORD or MARIADB_ROOT_PASSWORD_FILE: Root password (required unless importing data)MARIADB_DATABASE: Database to create on startupMARIADB_USER: User to create with access to the databaseMARIADB_PASSWORD or MARIADB_PASSWORD_FILE: Password for the created userMARIADB_RANDOM_ROOT_PASSWORD: Generate random root password (alternative to MARIADB_ROOT_PASSWORD)MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: Allow empty root password (not recommended)MARIADB_INITDB_SKIP_TZINFO: Skip timezone initializationCreate a custom configuration file custom.cnf to override default settings:
[mysqld]
# Connection settings
max_connections = 100
bind-address = 0.0.0.0
# InnoDB settings
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
# Security settings
local_infile = 0
# Logging
slow_query_log = 1
long_query_time = 1
# Create secrets directory
mkdir -p secrets
echo "your-root-password" > secrets/root_password.txt
echo "your-app-password" > secrets/app_password.txt
# Start the service
docker compose up -d
docker compose ps
# Check logs
docker compose logs -f mariadb
--ssl-verify-server-cert enabled# Backup all databases
docker exec mariadb mariadb-dump -u root -p$(cat secrets/root_password.txt) --all-databases > backup.sql
# Backup specific database
docker exec mariadb mariadb-dump -u root -p$(cat secrets/root_password.txt) appdb > appdb_backup.sql
# Restore from backup
docker exec -i mariadb mariadb -u root -p$(cat secrets/root_password.txt) < backup.sql
mariadb:11.4.10)