How to Deploy Nginx Proxy Manager on MikroTik RouterOS Using Containers
Use the MikroTik RouterOS device as a reverse proxy server using Nginx Proxy Manager container. This guide walks you through enabling container support on RouterOS v7.4+, setting up external storage to protect your device's flash memory, and deploying a fully functional reverse proxy with SSL certificate management.
Alert: for some reason, the container performance currently is terrible, without a proper solution. During my investigation, the CPU usage for containers is very limited no matter how powerful you router is:
- https://forum.mikrotik.com/t/horrible-container-performance-from-7-14-up-to-7-15rc2/175900/32
This guides was based on the following video:
Prerequisites
NOTE: RouterOS already provides a reverse proxy server but it doesn't have a so powerful feature set as Nginx Proxy Manager.
1. Enable Container Support on RouterOS
📖 Official Documentation: Container - MikroTik Documentation
Prerequisites:
- RouterOS device with v7.4beta or later
- Container package installed (available since RouterOS 7.18+ via System Packages, or manual installation)
- Physical access to the device (required for container mode activation)
- At least 512 MB of RAM
I'm using the "Chateau Pro ax / 7.19.4 (stable)".
Steps:
- First, install the container package if not already installed:
- RouterOS 7.18+: Go to System > Packages > select Container package > Enable
- Earlier versions: Download and install manually from MikroTik downloads
- Enable container support:
# Connect to your RouterOS via SSH or terminal
# Enable container support (requires physical confirmation)
/system/device-mode/update container=yes
- Important: After running the command, you'll see a message about "too many unsuccessful attempts". You must physically press the reset button or power cycle the device to confirm this change.
- Verify that container support is enabled:
/system/device-mode/print
📖 More Info: Device Mode Configuration
2. USB External Storage (Highly Recommended)
📖 Related Documentation: System Packages | Device Mode
Critical: Using external storage (HDD, SSD, or USB) is required for container operations. Internal flash memory can be damaged by constant read/write operations.
- Connect a USB storage device
- Format the drive with a RouterOS-supported filesystem:
# List available storage devices
/disk/print
# Format the USB drive (replace usb1 with your device name)
# Use ext4 filesystem with MBR partition table
/disk format usb1 file-system=ext4 label=containers mbr-partition-table=yes
- Configure container registry and storage:
# List available storage devices again to know which partition you will use
/disk/print
# Set registry URL and temporary directory on external storage
# Note: this is optional, since I'm using the full path in the example.
/container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1-part1/tmp
Deployment Steps
3. Network Configuration
📖 Network Documentation: Bridge Interface | Firewall NAT
First, set up the network infrastructure for containers:
# Create veth interface for the container
/interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1 comment=Container
# Create bridge interface for container networking
/interface/bridge/add name=containers comment=Container
/ip/address/add address=172.17.0.1/24 interface=containers comment=Container
# Add veth to bridge
/interface/bridge/port/add bridge=containers interface=veth1 comment=Container
# Add NAT rule for outgoing traffic
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 comment=Container
4. Deploy Nginx Proxy Manager Container
📖 Container Management: Container Commands | NPM Docker Hub
Now deploy the Nginx Proxy Manager container:
# List available storage devices again to know which partition you will use
/disk/print
# First, create mount points for persistent data storage
/container/mounts/add name=npm-data src=usb1-part1/npm-data dst=/data
/container/mounts/add name=npm-letsencrypt src=usb1-part1/npm-letsencrypt dst=/etc/letsencrypt
# Add and configure the Nginx Proxy Manager container
# Note: to get the latest image, go to Docker Hub and
# grab the offical digest for linux/arm64:
# https://hub.docker.com/r/jc21/nginx-proxy-manager/tags
/container/add remote-image=docker.io/jc21/nginx-proxy-manager:latest@sha256:6ab097814f54b1362d5fd3c5884a01ddd5878aaae9992ffd218439180f0f92f3 interface=veth1 root-dir=usb1-part1/npm-container logging=yes start-on-boot=yes mounts=npm-data,npm-letsencrypt name=nginx-proxy-manager
# (this may take a long time 10min+, you can check the WinBox GUI for status or print it as shown below)
# Start the container (replace [number] with actual container number from print command)
/container/print
/container/start [number]
5. Configure External Network Access
📖 Firewall Documentation: Firewall Filter Rules | NAT Rules
Port Conflict Solution:
Since Nginx Proxy Manager exposes ports 80 and 443 which are already used by RouterOS, we need to create a separate IP address for the container interface to avoid port collisions.
First, add a secondary IP address to your main interface:
# Add a secondary IP address to your main interface (adjust interface name as needed)
# Example: if your router's main IP is 192.168.88.1, add 192.168.88.4
/ip/address/add address=192.168.88.4/24 interface=bridge comment="Container services"
# Verify the new IP address was added
/ip/address/print
Then configure NAT rules to forward traffic to the container, using the new IP address as destination:
# Add firewall rules to allow access to the web interface
# Forward traffic to the new IP address (192.168.88.4) to the container
/ip/firewall/nat/add chain=dstnat protocol=tcp dst-address=192.168.88.4 dst-port=81 action=dst-nat to-addresses=172.17.0.2 to-ports=81 comment="NPM Admin Interface"
/ip/firewall/nat/add chain=dstnat protocol=tcp dst-address=192.168.88.4 dst-port=80 action=dst-nat to-addresses=172.17.0.2 to-ports=80 comment="NPM HTTP"
/ip/firewall/nat/add chain=dstnat protocol=tcp dst-address=192.168.88.4 dst-port=443 action=dst-nat to-addresses=172.17.0.2 to-ports=443 comment="NPM HTTPS"
Access Methods:
- NPM Admin Interface:
http://192.168.88.4:81
(instead of main router IP) - HTTP Traffic:
http://192.168.88.4:80
- HTTPS Traffic:
https://192.168.88.4:443
This approach completely eliminates port conflicts while maintaining full functionality.
6. First Time Setup
📖 NPM Setup Guide: Nginx Proxy Manager Quick Setup
After deployment, access the Nginx Proxy Manager web interface:
- Open your web browser and navigate to
http://192.168.88.4:81
- Default login credentials:
- Email:
admin@example.com
- Password:
changeme
- Email:
- Change the default credentials immediately after first login
Performance Optimization
📖 Container Documentation: Container Performance
Memory Optimization
Configure memory limits to prevent the container from consuming excessive RAM:
# Set soft RAM limit for containers (recommended: 200M-500M for NPM)
/container/config/set ram-high=300M
# Verify the configuration
/container/config/print
Important Notes:
- Memory limits in RouterOS 7.14+ may cause slow container startup
- If experiencing performance issues, try removing the limit:
/container/config/set ram-high=0
- Monitor memory usage:
/system/resource/print
Storage Performance
For optimal performance, ensure you're using fast external storage:
# Check current disk performance
/system/resource/print
# Monitor disk usage
/disk/print
# Use faster storage options when possible:
# - USB 3.0 drives over USB 2.0
# - SSD over HDD via USB-to-SATA adapters
# - NVMe drives if supported by your device
Container Resource Monitoring
Monitor your container performance with these commands:
# Check overall system resources
/system/resource/print
# View container status and resource usage
/container/print detail
# Check container logs for performance issues
/container/log/print name=nginx-proxy-manager
# Monitor network performance
/interface/monitor-traffic interface=veth1 duration=10
Performance Troubleshooting
If experiencing slow container performance:
- Use faster external storage (SSD recommended over USB drives)
Monitor for memory pressure:
/log/print where topics~"system" and message~"memory"
Restart the container:
/container/stop nginx-proxy-manager
/container/start nginx-proxy-manager
Disable memory limits temporarily:
/container/config/set ram-high=0
Check RouterOS version: Versions 7.14+ have known performance issues
/system/package/update/print
Known Limitations:
- CPU limits are not available in RouterOS (feature requested)
- Memory limits may cause startup delays in newer RouterOS versions
- Container performance varies significantly based on external storage speed
Maintenance
📖 Container Management: Container Operations
Upgrading Nginx Proxy Manager
To update to the latest version of Nginx Proxy Manager:
# First, check current containers and note the container number
/container/print
# Stop the current container (replace [number] with actual container number)
/container/stop [number]
# Remove the old container (data is preserved in mounted volumes)
/container/remove [number]
# Add the updated container with latest image (mounts should already exist)
# Note: to get the latest image, go to Docker Hub and
# grab the offical digest for linux/arm64:
# https://hub.docker.com/r/jc21/nginx-proxy-manager/tags
/container/add remote-image=docker.io/jc21/nginx-proxy-manager:latest@sha256:6ab097814f54b1362d5fd3c5884a01ddd5878aaae9992ffd218439180f0f92f3 interface=veth1 root-dir=usb1-part1/npm-container logging=yes start-on-boot=yes mounts=npm-data,npm-letsencrypt name=nginx-proxy-manager
# (this may take a long time 10min+, you can check the WinBox GUI for status or print it as shown below)
# Check the new container number and start it
/container/print
/container/start [new-number]
Container Management Commands
Essential commands for managing your containers:
# List all containers with their status and numbers
/container/print
# Start a container
/container/start [number]
# Stop a container
/container/stop [number]
# Access container shell (for troubleshooting)
/container/shell [number]
# View container configuration
/container/print detail where .id=[number]
# View system logs for container activity
/log/print where topics~"container"
# Monitor container resource usage
/system/resource/print
Backup Recommendations
📖 File System: Files and Folders | NPM Backup Guide
Regularly backup your container data from external storage:
# Important directories to backup from your external drive:
# - usb1-part1/npm-data (contains database and configuration)
# - usb1-part1/npm-letsencrypt (contains SSL certificates)
# You can access these via SFTP/SCP or by mounting the drive on another system
# Example: backup via RouterOS file system
/file/print where name~"usb1-part1"
Security Considerations
📖 Security Documentation: Container Security
⚠️ Important Security Warning: If your RouterOS device is compromised, containers can be used to easily install malicious software. Ensure proper security measures:
- Keep RouterOS updated to the latest stable version
- Use strong authentication credentials
- Limit access to the RouterOS device
- Regularly monitor container activities and logs
- Only run trusted container images from reputable sources
Troubleshooting
Common Issues
- Container fails to start: Check if container mode is properly enabled and device was rebooted
- Verify:
/system/device-mode/print
shows container=yes - Check logs:
/log/print where topics~"container"
- Verify:
- Web interface not accessible: Verify firewall rules and network configuration
- Test container networking:
/ping 172.17.0.2
- Check NAT rules:
/ip/firewall/nat/print
- Test container networking:
- SSL certificate issues: Ensure proper port forwarding (80/443) from your internet router to the RouterOS device
- Verify Let's Encrypt can reach your domain on ports 80/443
- Check NPM logs for certificate errors
- Storage issues: Monitor USB drive health and free space regularly
- Check disk usage:
/system/resource/print
- Verify mount status:
/disk/print
- Check disk usage:
- Container won't pull image: Check internet connectivity and registry access
- Test DNS resolution:
/ping registry-1.docker.io
- Verify registry URL:
/container/config/print
- Test DNS resolution:
Additional Resources
MikroTik RouterOS Documentation
- Command Line Interface - Complete CLI reference
- Container Feature - Official container documentation
- RouterOS Manual - Complete RouterOS documentation
Nginx Proxy Manager Documentation
- Official Setup Guide - Complete NPM documentation
- Advanced Configuration - Advanced NPM features
- Docker Hub Repository - Container image details
Community Resources
- MikroTik Community Forum - Community support and discussions
- RouterOS Container Examples - Additional container deployment examples