MuMo is a comprehensive monitoring and data visualization platform that provides real-time sensor data collection, user management, and interactive dashboards for monitoring various environmental and operational metrics.
MuMo consists of several interconnected components orchestrated with Docker Compose:
- Dashboard (PHP/Apache): Web interface for data visualization and system management
- Pipeline (Node.js/RDF): Data processing pipeline using RDF Connect framework
- Database (MySQL): Data storage for users, sensors, and measurements
- Nginx: Reverse proxy and SSL termination
Browser → Nginx → (PHP | Adminer | Solid | Pipeline)
↓
MySQL
mumo-full/
├── dashboard/ # PHP web application
│ ├── pages/ # PHP pages and functionalities
│ ├── assets/ # CSS, JS, images
│ ├── handlers/ # API endpoints
│ └── readme.md # Detailed dashboard documentation
├── pipeline/ # RDF data processing pipeline
│ ├── pipeline/ # TTL pipeline definitions
│ ├── proc/ # Custom processors
│ └── README.md # Pipeline technical documentation
├── data/ # LDES data storage
├── nginx.conf # Nginx configuration
├── docker-compose.yml # Container orchestration
└── settings.php # Configuration file
- Role: Reverse proxy and SSL termination
- Ports: 80:80, 443:443 (SSL)
- Configuration: Routes requests to backend services
- Role: RDF/Linked Data pipeline with authentication
- Technology: RDF-Connect framework
- Pipeline:
./pipeline/pipeline/auth-pipeline.ttl - Components: Community Solid Server, ACL generator, Identity Provider
- Documentation: See pipeline/README.md
- Role: Main data-processing RDF pipeline
- Technology: RDF-Connect framework
- Pipeline:
./pipeline/pipeline/pipeline.ttl - Documentation: See pipeline/README.md for detailed architecture
- Role: Relational database
- Image: mysql:8.0
- Initialization:
./dashboard/database_withDeviceChannelIndex.sql
- Role: PHP web backend
- Built from:
./dashboard/ - Documentation: See dashboard/readme.md for complete setup guide
- Role: Database management UI
- Access: Internal only (port 8080)
- Docker and Docker Compose
- Git submodules support
- Clone with submodules:
git clone --recursive git@github.com:MuseumMonitoring/mumo-platform.git
cd mumo-full
git submodule update --init --recursive- Configure settings:
# Copy and edit settings configuration
cp settings.php.example settings.php
# See dashboard/readme.md for detailed configuration- Start the application:
docker-compose up --build- Access the application:
- Dashboard: http://localhost
- Adminer: http://localhost:8080
settings.php: Database connection, domain settings, cluster namedocker-compose.yml: Service definitions and environment variablesnginx.conf: Reverse proxy configuration
- Dashboard Configuration: See dashboard/readme.md for complete settings.php setup
- Pipeline Configuration: See pipeline/README.md for environment variables
- Database Setup: See dashboard/readme.md for initial database configuration
This section guides you through deploying MuMo in a production environment with SSL encryption and a custom domain. The examples use mumo.faro.be as the domain - replace this with your actual domain throughout all configurations.
- Ubuntu/Debian server with Docker and Docker Compose installed
- Domain name pointing to your server's IP address
- Root or sudo access for SSL certificate installation
- Install Certbot:
sudo apt update
sudo apt install certbot python3-certbot-nginx- Obtain SSL certificate (replace with your domain):
sudo certbot --nginx -d your-domain.com- Set up automatic renewal:
sudo crontab -e
# Add this line for daily certificate renewal check:
0 12 * * * /usr/bin/certbot renew --quietModify your docker-compose.yml file with the following changes:
Nginx Service - Add SSL support:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443" # Add SSL port
expose:
- "443"
- "80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
# Mount SSL certificates (update paths with your domain)
- /etc/letsencrypt/live/your-domain.com/fullchain.pem:/etc/letsencrypt/live/your-domain.com/fullchain.pem
- /etc/letsencrypt/live/your-domain.com/privkey.pem:/etc/letsencrypt/live/your-domain.com/privkey.pem
- /etc/letsencrypt/options-ssl-nginx.conf:/etc/letsencrypt/options-ssl-nginx.conf
- /etc/letsencrypt/ssl-dhparams.pem:/etc/letsencrypt/ssl-dhparams.pem
networks:
public:
aliases:
- api.local
- your-domain.com # Add your domainSolid Service - Use HTTPS baseUrl:
solid:
build: ./pipeline/
command: /app/pipeline/auth-pipeline.ttl
environment:
DEBUG: rdfc
groupHistory: http://php/history.php?groups
userHistory: http://php/history.php?users
sensorHistory: http://php/history.php?sensors
baseUrl: "https://your-domain.com/" # Important: Use HTTPS for internal requests
volumes:
- ./data/:/app/pipeline/ldes/
- ./pipeline/pipeline/:/app/pipeline/Adminer Service - Remove external port exposure:
adminer:
image: adminer
expose:
- "8080"
# Remove ports mapping for security - only accessible internallyReplace the entire nginx.conf file with this SSL-enabled configuration:
# Docker network detection - redirects internal traffic to HTTP, external to HTTPS
map $remote_addr $from_docker {
default 1;
172.18.0.0/16 0;
}
server {
listen 80;
# Redirect external requests to HTTPS
if ($from_docker) {
return 301 https://$host$request_uri;
break;
}
location = / {
proxy_pass http://php:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ \.php$ {
proxy_pass http://php:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /assets {
proxy_pass http://php:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://solid:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# HTTPS server block with SSL configuration
server {
listen 443 ssl;
# Update these paths with your domain
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location = / {
proxy_pass http://php:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ \.php$ {
proxy_pass http://php:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /assets {
proxy_pass http://php:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://solid:3000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Modify settings.php to use your domain and HTTPS:
<?php session_start ();
if($_SERVER['HTTP_HOST'] != "db"){
// Production settings
$con = mysqli_connect("db", "user", "userpass", "mumo_test", 3306);
$url = "https://your-domain.com"; // Use HTTPS
$domain = "your-domain.com"; // Your domain
$clustername = "Mumo";
$logo = "assets\images\logo\mumoLogo.png";
$logo_w = "assets\images\logo\mumoLogoW.png";
}else{
// Development settings (can keep local or use same domain)
$con = mysqli_connect("db", "user", "userpass", "mumo_test", 3306);
$url = "https://your-domain.com"; # Keep consistent with production
$domain = "your-domain.com";
$clustername = "Mumo";
$logo = "assets\images\logo\Mumo final.png";
$logo_w = "assets\images\logo\Mumo final_w.png";
}
?>- Build and start the containers:
docker-compose down
docker-compose up --build -d- Verify the deployment:
- Access your dashboard at:
https://your-domain.com - Check that HTTP redirects to HTTPS
- Verify all services are running:
docker-compose ps
Why HTTPS in docker-compose?
The Solid container needs to make requests to itself using the public endpoint. Since the public endpoint uses HTTPS, the baseUrl environment variable must use https:// even for internal Docker communications.
Security Considerations:
- Change default MySQL passwords in production
- Adminer is only accessible internally (good for security)
- All external traffic is forced to use HTTPS
- SSL certificates auto-renew with the cron job
Troubleshooting:
- If SSL certificates aren't found, verify Certbot installation and domain ownership
- Check container logs:
docker-compose logs nginx solid php - Ensure your domain DNS points to the server IP before running Certbot
- Database: Change default MySQL passwords in production
- SSL: Always use HTTPS in production environments
- Firewall: Configure firewall to allow only necessary ports (80, 443)
- Adminer: Consider removing or securing database admin interface in production
- Backups: Implement regular database and file backups
For development without SSL:
- Use the default
docker-compose.ymlconfiguration - Access via http://localhost
- Adminer available at http://localhost:8080
- Dashboard Development: See dashboard/readme.md for PHP application development
- Pipeline Development: See pipeline/README.md for RDF pipeline modifications
- Database Schema: See dashboard/database.sql for complete schema
The dashboard provides these endpoints used by the pipeline:
/history.php?users: User history data/history.php?groups: Group history data/history.php?sensors: Sensor history data/history.php?data: Measurement data/endpoint.php: TTN webhook endpoint/export.php: Data export functionality
All services communicate via a shared Docker network:
- Internal URLs:
http://php/,http://db:3306,http://solid:3000 - Architecture Overview: See Overview.drawio.svg
- Submodule issues:
git submodule update --init --recursive - Database connection: Check MySQL logs and credentials
- Pipeline failures: See pipeline/README.md for debugging
- SSL errors: Verify certificate paths and domain configuration
docker-compose logs nginx # Nginx/proxy issues
docker-compose logs php # PHP application errors
docker-compose logs db # Database issues
docker-compose logs solid # Pipeline problemsStart the Stack:
docker compose up --buildStop the stack:
docker compose down- Fork the repository
- Create a feature branch
- Make your changes
- Test with
docker-compose up --build - Submit a pull request
This project is licensed under the terms specified in the LICENSE file.
For support and questions:
- Check the troubleshooting section
- Review container logs
- Examine the documentation in the
dashboard/documentation/directory