Production Install
This guide covers deploying MJC Job Manager on a Linux host using Docker Compose. The chosen machine is Ubuntu Server 22.04, but the process would be identical for most distributions, or if you were running embedded WSL/Docker Desktop for Windows.
Prerequisites
- Docker + Docker Compose
- A Linux host (VM or bare metal) - This guide will be using Ubuntu
- A domain name (recommended) and the ability to point DNS to your server
Install
- The simplest way to install mjc-job-manager is with the bootstrap file.
- This will get the latest version, performa hash verification, and setup and commence the install process.
curl -fsSL https://raw.githubusercontent.com/michaeljclarkk/mjc-job-manager/main/bootstrap.sh | bash
cd /opt/mjc/current
./install.sh
Install Steps
-
mjc-job-manager comes with several install options
-
It is very possible to have app.YOUR_DOMAIN.com or similar, that requires either port forwarding 80 or 443 & 25, or the usage of a service like Tailscale
-
For this install, the choice will be #2 (this provides a self signed SSL certificate with Caddy, and also allows for no third-party feature limitations):
=============================================================================
MJC Job Manager - Production Installation
=============================================================================
Checking prerequisites...
✓ Prerequisites check passed
=== Deployment Mode ===
Choose your deployment mode:
1) Production with domain (HTTPS via Let's Encrypt)
- Requires a domain pointing to this server
- Automatic SSL certificate
2) Production with self-signed HTTPS (LAN/IP access)
- Access via IP address or hostname
- Self-signed SSL certificate (browser warning expected)
- Required for voice assistant/microphone features
3) Production without SSL (HTTP only)
- Access via IP address or hostname
- No SSL (not recommended - some features won't work)
4) Cloudflare Proxy (HTTPS via Cloudflare)
- Cloudflare handles SSL termination
- Server runs on custom port (avoids router conflicts)
- Requires Cloudflare DNS with proxy enabled (orange cloud)
5) Headless (BYO Reverse Proxy)
- No Caddy - use your own Traefik/nginx/Caddy
- Exposes frontend and API on configurable ports
- For integration with existing Docker stacks
Enter choice [1-5]:
- Next, you'll be asked to enter an IP or hostname, for this case, i'll use my servers internal IP address, but this can be anything you want. For instance, if you wanted to run it at app.mjcit.com.au, youd enter your custom domain here:
-
The script will ask you whether or not you want to download some maps (for the geo-coding and tile server) to choose an installation directory. this can be skipped, however, the software will fallback to using to OSM Tiles and Public Nominatim which is subject to public api rate limiting.
-
In this install, i'll use the Aus geofabrik. Its important to not that anywhere outside of this area, will fallback to the above public API's & the script will fail if given a non-existant GeoFabrik dataset:
=== Map Data Storage ===
The tile server and geocoding services require 50GB+ of storage.
Choose a directory on a drive with sufficient space.
Available storage:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv 455G 108G 329G 25% /
/dev/sda2 2.0G 198M 1.6G 11% /boot
/dev/sda1 1.1G 6.2M 1.1G 1% /boot/efi
Enter directory for map data [/opt/mjc/shared/osm-data]:
Creating OSM data directories...
✓ OSM data directory: /opt/mjc/shared/osm-data
✓ Available space on /: 329G
=== Map Region Selection ===
Choose the OpenStreetMap region to download:
1) Australia (~2.5GB download, ~25GB extracted)
2) New Zealand (~300MB download, ~3GB extracted)
3) Australia + New Zealand/Oceania (~3GB download, ~30GB extracted)
4) United Kingdom (~1.5GB download, ~15GB extracted)
5) United States (~10GB download, ~100GB extracted)
6) Germany (~4GB download, ~40GB extracted)
7) Custom (enter Geofabrik path)
Enter choice [1]: 7
Enter the Geofabrik path (see https://download.geofabrik.de/)
Example: europe/france-latest.osm.pbf
PBF path: australia-oceania/australia/queensland-latest.osm.pbf
✓ Map region: Custom
- Once the script is complete, the progress of the download/import progress of the tile-server and nominatim can be checked with:
# Check tile-server download/import progress
docker logs mjc-tile-server -f --tail 50
# Check nominatim download/import progress
docker logs mjc-nominatim -f --tail 50
- The installation will continue with its other processes, such as running migrations, generating secrets, config files, and bringing the services up. The frontend is created/built towards the end of this, to where all required containers are confirmed as created:
[+] up 23/23
✔ Image mjc-job-manager-frontend Built 281.1s
✔ Volume mjc-caddy-data Created 0.1s
✔ Volume mjc-caddy-config Created 0.1s
✔ Volume mjc-storage-data Created 0.1s
✔ Volume mjc-postfix-spool Created 0.1s
✔ Container mjc-nominatim Created 13.3s
✔ Container mjc-tile-server Created 13.9s
✔ Container mjc-db Healthy 43.5s
✔ Container mjc-imgproxy Created 12.6s
✔ Container mjc-functions Created 12.3s
✔ Container mjc-realtime Created 11.9s
✔ Container mjc-migrator Created 11.3s
✔ Container mjc-auth Created 11.4s
✔ Container mjc-meta Created 12.8s
✔ Container mjc-studio Created 13.6s
✔ Container mjc-rest Created 13.1s
✔ Container mjc-storage Created 1.9s
✔ Container mjc-text-extractor Created 2.1s
✔ Container mjc-kong Created 2.1s
✔ Container mjc-frontend Created 2.5s
✔ Container mjc-mailhook Created 2.1s
✔ Container mjc-postfix Created 3.3s
✔ Container mjc-caddy Created 2.3s
- It will then commence the verification process, to ensure all are in a running state.
- You'll be presented with creating the first user, this should be the main business_admin
=== Creating Initial Admin User ===
Enter admin email address: michaeljclarkk@outlook.com
Enter admin password (8+ chars, must have uppercase, lowercase, digit):
Re-type password to confirm:
Enter admin first name: Michael
Enter admin last name: Clark
Creating admin user: my@email.com
id
--------------------------------------
A BIG USER ID WILL BE SHOWN HERE
(1 row)
If all is successful, you'll be presenteed with the final stage of the install script:
Installation Complete!
=============================================================================
Your MJC Job Manager instance is now running.
Access URLs:
Application: https://192.168.1.9
Note: Using self-signed certificate. Your browser will show a
security warning - this is expected. Click 'Advanced' and
'Proceed to 192.168.1.9' to continue.
Supabase Studio: http://localhost:54323 (localhost only)
Steps:
1. Open the application URL in your browser
2. Log in with your admin credentials:
Email: your@email.com
3. Configure SMTP in Settings > Business > Email Settings (optional)
Note: Email confirmation is disabled by default.
You can enable it after configuring SMTP by setting
MAILER_AUTOCONFIRM=false in .env.production
Important:
- Your secrets are stored in /opt/mjc/shared/.env.production
- Back up this file securely!
- To view logs: docker compose -f docker-compose.prod.yml logs -f
- To stop: docker compose -f docker-compose.prod.yml down
- To update: sudo /opt/mjc/shared/update-release.sh --to <version> --repo <owner>/<repo>
Next Steps
- Access the front end at the IP/Hostname added during setup, in this case the hostname is https://192.168.1.9.
- Login with your admin username and password

Notes
- Supabase Studio is bound to localhost by default for safety.
- If you need Studio remotely, prefer an SSH tunnel or VPN.
Switching to a different Hostname or Mode Later on
There may be a need to switch different modes or change hosts - whatever this may be, you can update the related services to support the new host:
#1 Regenerate certificates
cd /opt/mjc/shared/certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key -out server.crt \
-subj "/CN=NEW_IP_OR_HOSTNAME" \
-addext "subjectAltName=IP:NEW_IP_OR_HOSTNAME"
#2 Update the CaddyFile
sed -i 's/OLD_IP/NEW_IP/g' /opt/mjc/shared/Caddyfile
#3 Update .env.production
sed -i 's/OLD_IP/NEW_IP/g' /opt/mjc/shared/.env.production
#4 Rebuild Containers and Restart
cd /opt/mjc/current
docker compose --env-file /opt/mjc/shared/.env.production -f docker-compose.prod.yml up -d --build frontend
docker compose --env-file /opt/mjc/shared/.env.production -f docker-compose.prod.yml restart caddy
Uninstallation
- The simplest way to start over - or remove forever, is to shut everything down, and nuke the install directory. (After you have made appropriate backups of course)