
Building Your Portfolio Experience
Loading Tariqul Islam's projects...
Loading Tariqul Islam's projects...
A complete step-by-step guide to install, secure, and configure MongoDB useing docker on a VPS. Includes local and S3 backup automation for production.
Hostinger VPS (Ubuntu 22.04 or later)
Docker & Docker Compose installed
Domain or VPS IP address
Firewall enabled (UFW)
(Optional) AWS CLI configured for cloud backups
ssh root@your-vps-ip
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | bash
apt install -y docker-compose-plugin
Check versions:
docker --version
docker compose version
mkdir -p /srv/apps/mongodb/{backups,init-scripts,scripts}
cd /srv/apps/mongodb
.env
Filenano .env
Paste:
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=
# Mongo Express GUI
ME_BASIC_AUTH_USER=
ME_BASIC_AUTH_PASS=
Save and exit.
create a network:
docker network create appnet
nano docker-compose.yml
Paste:
volumes:
mongo_data:
mongo_backups:
networks:
appnet:
external: true
internal:
driver: bridge
services:
mongodb:
image: mongo:8.0
container_name: mongodb
restart: unless-stopped
env_file: .env
command: ["--auth"]
networks:
- appnet
- internal
volumes:
- mongo_data:/data/db
- mongo_backups:/backups
- ./init-scripts:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "mongosh -u \"$${MONGO_INITDB_ROOT_USERNAME}\" -p \"$${MONGO_INITDB_ROOT_PASSWORD}\" --authenticationDatabase admin --quiet --eval \"db.runCommand({ ping: 1 })\""]
interval: 30s
timeout: 5s
retries: 10
start_period: 20s
ulimits:
nofile:
soft: 64000
hard: 64000
environment:
- TZ=Asia/Dhaka
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
docker compose up -d
Check running containers:
docker ps
View logs:
docker logs -f mongodb
MongoDB stores all data in the Docker volume mongo_data
.
If the container is stopped, removed, or restarted → data remains safe.
To verify:
docker volume ls
docker volume inspect mongo_data
Login to Mongo shell:
docker exec -it mongodb mongosh -u admin -p SuperSecret123 --authenticationDatabase admin
Inside Mongo:
use newdatabase
db.createUser({
user: "newuser",
pwd: passwordPrompt(),
roles: [{ role: "readWrite", db: "newdatabase" }]
});
Exit:
exit
Remove the line ports: "27017:27017"
from docker-compose.yml
.
Your apps can still connect using the internal Docker network hostname mongodb:27017
.
No public exposure.
Do not expose MongoDB publicly. Instead:
Close port 27017 in firewall:
ufw deny 27017
From your local computer, create SSH tunnel:
ssh -L 27017:localhost:27017 root@your-vps-ip
connect using MongoDB compass
mongodb://admin:SuperSecret123@127.0.0.1:27017/myappdb?authSource=admin
Add this service in docker-compose.yml
:
mongo-express:
image: mongo-express:1.0.2
container_name: mongo-express
restart: unless-stopped
depends_on:
mongodb:
condition: service_healthy
env_file: .env
environment:
ME_CONFIG_MONGODB_URL: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongodb:27017/?authSource=admin"
ME_CONFIG_MONGODB_ENABLE_ADMIN: "true"
ME_CONFIG_BASICAUTH_USERNAME: "${ME_BASIC_AUTH_USER}"
ME_CONFIG_BASICAUTH_PASSWORD: "${ME_BASIC_AUTH_PASS}"
ME_CONFIG_SITE_HTTPS_ENABLED: "false"
TZ: Asia/Dhaka
networks:
- internal
- appnet
labels:
- "traefik.enable=true"
- "traefik.docker.network=appnet"
- "traefik.http.routers.mongo-express.rule=Host(`mongo.naturalsefaa.com`)"
- "traefik.http.routers.mongo-express.entrypoints=websecure"
- "traefik.http.routers.mongo-express.tls=true"
- "traefik.http.routers.mongo-express.tls.certresolver=letsencrypt"
- "traefik.http.services.mongo-express.loadbalancer.server.port=8081"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
Access in browser:http://your-vps-ip:8081
Create script:
nano /srv/apps/mongodb/backups/scripts/dbname_backup.sh
Paste:
#!/bin/bash
DB_NAME=dbname
DB_USER=db_user
DB_PASS=db_pass
BACKUP_DIR=/srv/apps/mongodb/backups/$DB_NAME
TIMESTAMP=$(date +%F-%H-%M-%S)
BACKUP_NAME="backup-$DB_NAME-$TIMESTAMP.gz"
mkdir -p $BACKUP_DIR
docker exec mongodb mkdir -p /backups/$DB_NAME
docker exec mongodb mongodump \
--db $DB_NAME \
-u $DB_USER \
-p $DB_PASS \
--authenticationDatabase $DB_NAME \
--archive=/backups/$DB_NAME/$BACKUP_NAME --gzip
ls -t $BACKUP_DIR/backup-$DB_NAME-*.gz | tail -n +15 | xargs -r rm --
echo "[$(date '+%F %T')] Backup saved to $BACKUP_DIR/$BACKUP_NAME"
Make it executable:
chmod +x /srv/apps/mongodb/backups/scripts/dbname_backup.sh
Run test:
/srv/apps/mongodb/backups/scripts/dbname_backup.sh
crontab -e
Add (hourly backups):
0 0 * * * /root/backups/scripts/dbname_backup.sh >> /var/log/mongo-backup.log 2>&1
docker exec -i mongodb mongorestore \
--db myappdb \
-u $MONGO_APP_USER \
-p $MONGO_APP_PASS \
--authenticationDatabase myappdb \
--gzip --archive < backup-myappdb-2025-08-24-12-00-00.gz
MongoDB 8.0 running in Docker
Persistent data stored in Docker volumes (no data loss if container restarts)
Admin + app user created securely
No public exposure (use SSH tunnel or mongo-express if needed)
Automated backup & restore system
Ready for production use 🚀