A containerized Apache CloudStack management server with separate MySQL/MariaDB database and usage server, based on AlmaLinux 9.6.
# Build the container
docker compose build
# Start CloudStack with MySQL
docker compose up -d
# View logs
docker compose logs -f
# Stop and DESTROY ALL DATA
docker compose down -vAccess the CloudStack UI at: http://localhost:8080/client/
- Default credentials: admin / password
This setup uses two separate containers:
- MySQL/MariaDB container: Dedicated database server
- CloudStack container: Management server and usage server
- Apache CloudStack management server with usage server
- Separate MySQL/MariaDB database container
- Automatic database initialization on first run
- Persistent data volumes
- Supervisord process management
- Health checks for service dependencies
Environment variables can be set in .env file:
# CloudStack version
CLOUDSTACK_VERSION=4.22
# Database configuration
DB_HOST=mysql
DB_PORT=3306
DB_PASSWORD=cloud
DB_ROOT_PASSWORD=root
# Management server IP (auto-detected if not set)
MANAGEMENT_SERVER_IP=- Image:
mariadb:10.11 - Port:
3306 - Health check included for automatic startup sequencing
- Management server
- Usage server
- Depends on MySQL service health
3306- MySQL/MariaDB database8080- Management UI8250- Cluster management8251- System VM communication9090- Integration API8096- Usage server
mysql-data- MySQL/MariaDB database filescloudstack-data- CloudStack datacloudstack-logs- CloudStack logs
To use an external MySQL/MariaDB instance instead of the containerized one:
- Remove or comment out the
mysqlservice fromdocker-compose.yml - Update the environment variables to point to your external database:
DB_HOST=your-mysql-host DB_PORT=3306 DB_PASSWORD=your-password DB_ROOT_PASSWORD=your-root-password
- Ensure your external database is accessible from the CloudStack container
If you see "Access denied for user 'root'@'x.x.x.x'" errors:
-
On first run, ensure the MySQL container is fully initialized:
# Remove existing volumes and start fresh docker compose down -v docker compose up -d mysql # Wait for MySQL to be ready docker compose logs -f mysql # Once ready, start CloudStack docker compose up -d cloudstack
-
Verify MySQL is accepting connections:
# Test connection from host mysql -h localhost -P 3306 -u root -p # Password: root (or your DB_ROOT_PASSWORD) # Test from CloudStack container docker compose exec cloudstack mysql -h mysql -u root -p
-
Check MySQL permissions:
docker compose exec mysql mysql -u root -p -e "SELECT Host, User FROM mysql.user;"
-
Manually grant permissions if needed:
docker compose exec mysql mysql -u root -p # Then run: GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;
docker compose exec cloudstack tail -f /var/log/cloudstack/management/management-server.logdocker compose exec cloudstack bashIf you need to start completely fresh:
# Stop and remove all containers and volumes
docker compose down -v
# Remove any cached images
docker compose down --rmi all
# Rebuild and start
docker compose build --no-cache
docker compose up -dApache License 2.0