From 0886dbf79230bf5886ef0a30d275c890329bd373 Mon Sep 17 00:00:00 2001 From: berkay Date: Sat, 19 Apr 2025 18:36:04 +0300 Subject: [PATCH] Initial commit: MongoDB production setup for Proxmox LXC container --- .env | 7 ++ README.md | 187 +++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 68 +++++++++++++++++ init-mongo.js | 45 +++++++++++ 4 files changed, 307 insertions(+) create mode 100644 .env create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 init-mongo.js diff --git a/.env b/.env new file mode 100644 index 0000000..5b1f8b1 --- /dev/null +++ b/.env @@ -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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..8dbf7eb --- /dev/null +++ b/README.md @@ -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 -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. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4813f96 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/init-mongo.js b/init-mongo.js new file mode 100644 index 0000000..5f05e1e --- /dev/null +++ b/init-mongo.js @@ -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!");