Initial commit: MongoDB production setup for Proxmox LXC container
This commit is contained in:
commit
0886dbf792
|
|
@ -0,0 +1,7 @@
|
||||||
|
# MongoDB credentials
|
||||||
|
MONGO_ROOT_USERNAME=admin
|
||||||
|
MONGO_ROOT_PASSWORD=change_this_password
|
||||||
|
|
||||||
|
# Mongo Express credentials
|
||||||
|
MONGOEXPRESS_USERNAME=mexpress
|
||||||
|
MONGOEXPRESS_PASSWORD=change_this_password_too
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
# MongoDB Production Setup for Proxmox LXC Container
|
||||||
|
|
||||||
|
This repository contains a production-ready MongoDB setup using Docker Compose, designed to run on a Proxmox LXC container.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The configuration includes:
|
||||||
|
|
||||||
|
- MongoDB 6.0 with replica set configuration
|
||||||
|
- Mongo Express for web-based administration
|
||||||
|
- Persistent data storage
|
||||||
|
- Security features
|
||||||
|
- Health checks
|
||||||
|
- Resource limits
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Proxmox VE with LXC container support
|
||||||
|
- Docker and Docker Compose installed on the LXC container
|
||||||
|
- Proper network configuration in Proxmox
|
||||||
|
|
||||||
|
## Configuration Details
|
||||||
|
|
||||||
|
### docker-compose.yml Explained
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8' # Docker Compose file format version
|
||||||
|
|
||||||
|
services:
|
||||||
|
mongodb:
|
||||||
|
image: mongo:6.0 # Using MongoDB 6.0
|
||||||
|
container_name: mongodb
|
||||||
|
restart: always # Ensures MongoDB restarts automatically
|
||||||
|
environment:
|
||||||
|
# Environment variables for authentication
|
||||||
|
- MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USERNAME:-admin} # Default: admin
|
||||||
|
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD:-password} # Default: password
|
||||||
|
volumes:
|
||||||
|
# Persistent data storage
|
||||||
|
- mongodb_data:/data/db # Database files
|
||||||
|
- mongodb_config:/data/configdb # Configuration files
|
||||||
|
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro # Initialization script
|
||||||
|
ports:
|
||||||
|
- "27017:27017" # Expose MongoDB port
|
||||||
|
command: ["--auth", "--bind_ip_all", "--replSet", "rs0"] # Enable authentication and replica set
|
||||||
|
healthcheck:
|
||||||
|
# Regular health checks
|
||||||
|
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/admin --quiet
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 40s
|
||||||
|
networks:
|
||||||
|
- mongo_network
|
||||||
|
ulimits:
|
||||||
|
# Increase file descriptor limits for production
|
||||||
|
nofile:
|
||||||
|
soft: 64000
|
||||||
|
hard: 64000
|
||||||
|
logging:
|
||||||
|
# Log rotation to prevent disk space issues
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "200m"
|
||||||
|
max-file: "10"
|
||||||
|
|
||||||
|
mongo-express:
|
||||||
|
image: mongo-express:latest
|
||||||
|
container_name: mongo-express
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
# Authentication for MongoDB connection
|
||||||
|
- ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_ROOT_USERNAME:-admin}
|
||||||
|
- ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_ROOT_PASSWORD:-password}
|
||||||
|
- ME_CONFIG_MONGODB_SERVER=mongodb
|
||||||
|
# Basic authentication for web interface
|
||||||
|
- ME_CONFIG_BASICAUTH_USERNAME=${MONGOEXPRESS_USERNAME:-mexpress}
|
||||||
|
- ME_CONFIG_BASICAUTH_PASSWORD=${MONGOEXPRESS_PASSWORD:-mexpress}
|
||||||
|
- ME_CONFIG_MONGODB_ENABLE_ADMIN=true
|
||||||
|
- ME_CONFIG_SITE_BASEURL=/mongo-express
|
||||||
|
ports:
|
||||||
|
- "8081:8081" # Web interface port
|
||||||
|
depends_on:
|
||||||
|
- mongodb
|
||||||
|
networks:
|
||||||
|
- mongo_network
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "50m"
|
||||||
|
max-file: "5"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mongo_network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mongodb_data: # Persistent volume for database files
|
||||||
|
driver: local
|
||||||
|
mongodb_config: # Persistent volume for configuration
|
||||||
|
driver: local
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **Authentication**: MongoDB is configured with authentication enabled by default
|
||||||
|
2. **Environment Variables**: Sensitive information is passed via environment variables
|
||||||
|
3. **Network Isolation**: Services run on a dedicated bridge network
|
||||||
|
4. **Mongo Express Security**: Basic authentication is enabled for the web interface
|
||||||
|
|
||||||
|
## Initialization Script
|
||||||
|
|
||||||
|
The `init-mongo.js` script:
|
||||||
|
- Initializes a MongoDB replica set (rs0)
|
||||||
|
- Creates a default application database (appdb)
|
||||||
|
- Sets up a dedicated user for application access
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Create a `.env` file with your custom credentials:
|
||||||
|
|
||||||
|
```
|
||||||
|
MONGO_ROOT_USERNAME=your_admin_username
|
||||||
|
MONGO_ROOT_PASSWORD=your_secure_password
|
||||||
|
MONGOEXPRESS_USERNAME=your_express_username
|
||||||
|
MONGOEXPRESS_PASSWORD=your_express_password
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start the services:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Access Mongo Express at `http://your-server-ip:8081`
|
||||||
|
|
||||||
|
4. Connect to MongoDB:
|
||||||
|
|
||||||
|
```
|
||||||
|
mongodb://appuser:apppassword@your-server-ip:27017/appdb?authSource=appdb&replicaSet=rs0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Proxmox LXC Container Configuration
|
||||||
|
|
||||||
|
For optimal performance in a Proxmox LXC container:
|
||||||
|
|
||||||
|
1. Ensure the container has sufficient resources:
|
||||||
|
- At least 2 CPU cores
|
||||||
|
- Minimum 4GB RAM
|
||||||
|
- At least 20GB storage
|
||||||
|
|
||||||
|
2. Enable necessary features in the LXC container:
|
||||||
|
```
|
||||||
|
pct set <container-id> -features nesting=1
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Configure container for Docker:
|
||||||
|
```
|
||||||
|
echo 'kernel.unprivileged_userns_clone=1' > /etc/sysctl.d/unprivileged-userns-clone.conf
|
||||||
|
sysctl -p /etc/sysctl.d/unprivileged-userns-clone.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
- **Backups**: MongoDB data is stored in named volumes. Use Docker's volume backup mechanisms:
|
||||||
|
```bash
|
||||||
|
docker run --rm -v mongodb_data:/data -v $(pwd):/backup alpine tar -czf /backup/mongodb-data-backup.tar.gz /data
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Monitoring**: Consider adding Prometheus and Grafana for monitoring
|
||||||
|
|
||||||
|
- **Updating**: To update MongoDB version, change the image tag in docker-compose.yml and restart:
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
# Edit docker-compose.yml to update image version
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **Connection Issues**: Ensure ports are not blocked by firewall
|
||||||
|
- **Replica Set Problems**: Check MongoDB logs with `docker-compose logs mongodb`
|
||||||
|
- **Performance Issues**: Monitor resource usage and adjust container limits if needed
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mongodb:
|
||||||
|
image: mongo:6.0
|
||||||
|
container_name: mongodb
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USERNAME:-admin}
|
||||||
|
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD:-password}
|
||||||
|
volumes:
|
||||||
|
- mongodb_data:/data/db
|
||||||
|
- mongodb_config:/data/configdb
|
||||||
|
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
|
||||||
|
ports:
|
||||||
|
- "27017:27017" # Expose MongoDB port to external machines
|
||||||
|
command: ["--auth", "--bind_ip_all", "--replSet", "rs0"]
|
||||||
|
healthcheck:
|
||||||
|
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/admin --quiet
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 40s
|
||||||
|
networks:
|
||||||
|
- mongo_network
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 64000
|
||||||
|
hard: 64000
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "200m"
|
||||||
|
max-file: "10"
|
||||||
|
|
||||||
|
mongo-express:
|
||||||
|
image: mongo-express:latest
|
||||||
|
container_name: mongo-express
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_ROOT_USERNAME:-admin}
|
||||||
|
- ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_ROOT_PASSWORD:-password}
|
||||||
|
- ME_CONFIG_MONGODB_SERVER=mongodb
|
||||||
|
- ME_CONFIG_BASICAUTH_USERNAME=${MONGOEXPRESS_USERNAME:-mexpress}
|
||||||
|
- ME_CONFIG_BASICAUTH_PASSWORD=${MONGOEXPRESS_PASSWORD:-mexpress}
|
||||||
|
- ME_CONFIG_MONGODB_ENABLE_ADMIN=true
|
||||||
|
- ME_CONFIG_SITE_BASEURL=/mongo-express
|
||||||
|
ports:
|
||||||
|
- "8081:8081" # Expose Mongo Express web interface to external machines
|
||||||
|
depends_on:
|
||||||
|
- mongodb
|
||||||
|
networks:
|
||||||
|
- mongo_network
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "50m"
|
||||||
|
max-file: "5"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mongo_network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mongodb_data:
|
||||||
|
driver: local
|
||||||
|
mongodb_config:
|
||||||
|
driver: local
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// This script initializes MongoDB with a replica set and creates a default database with user
|
||||||
|
db = db.getSiblingDB('admin');
|
||||||
|
|
||||||
|
// Wait for the MongoDB instance to be ready
|
||||||
|
print("Waiting for MongoDB to be ready...");
|
||||||
|
let counter = 0;
|
||||||
|
while (!db.adminCommand({ ping: 1 }).ok && counter < 30) {
|
||||||
|
sleep(1000);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize replica set if not already initialized
|
||||||
|
try {
|
||||||
|
rs.status();
|
||||||
|
} catch (err) {
|
||||||
|
print("Initializing replica set...");
|
||||||
|
rs.initiate({
|
||||||
|
_id: "rs0",
|
||||||
|
members: [{ _id: 0, host: "localhost:27017" }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for replica set to initialize
|
||||||
|
print("Waiting for replica set to initialize...");
|
||||||
|
counter = 0;
|
||||||
|
while (rs.status().ok !== 1 && counter < 30) {
|
||||||
|
sleep(1000);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create application database and user if they don't exist
|
||||||
|
db = db.getSiblingDB('appdb');
|
||||||
|
|
||||||
|
if (!db.getUser('appuser')) {
|
||||||
|
print("Creating application user...");
|
||||||
|
db.createUser({
|
||||||
|
user: 'appuser',
|
||||||
|
pwd: 'apppassword',
|
||||||
|
roles: [
|
||||||
|
{ role: 'readWrite', db: 'appdb' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
print("MongoDB initialization completed successfully!");
|
||||||
Loading…
Reference in New Issue