Appearance
Collector manual installation
Use manual installation when Docker is already installed and you want to manage the collector runtime files yourself. Create a dedicated folder for the stack, then add the environment file, SSL certificate files, and Docker Compose file.
Create the runtime folder
bash
mkdir -p "$HOME/Library/Application Support/TiltmeterPlatform/certs"
cd "$HOME/Library/Application Support/TiltmeterPlatform"powershell
mkdir "$env:LOCALAPPDATA\TiltmeterPlatform\certs"
cd "$env:LOCALAPPDATA\TiltmeterPlatform"bash
mkdir -p "$HOME/.local/share/tiltmeter-platform/certs"
cd "$HOME/.local/share/tiltmeter-platform"Pull the production images
bash
docker pull ghcr.io/neotech-australia/tiltmeter-platform/collector:latest
docker pull ghcr.io/neotech-australia/tiltmeter-platform/dashboard:latest
docker pull postgres:18.1Create .env
Create a .env file in the runtime folder. Set these values before starting the stack:
| Variable | Required | How to set it |
|---|---|---|
DASHBOARD_PORT | yes | Public HTTPS port for the local dashboard. Use 443 unless another service already uses it. |
ADMIN_USERNAME | yes | Initial local dashboard admin username. Default is admin. |
ADMIN_PASSWORD | yes | Initial local dashboard admin password. Use a site-specific password. |
JWT_SECRET_KEY | yes | Random secret for API tokens. Use a long random hex or base64 value. |
POSTGRES_PASSWORD | yes | Random database password. The same value must be used inside DATABASE_URL. |
DATABASE_URL | yes | postgresql://tiltmeter:<POSTGRES_PASSWORD>@postgres:5432/lora |
DEFAULT_MQTT_HOST | yes | WisGate LAN IP address. Change this to the gateway IP for the site. |
DEFAULT_MQTT_SERVER_PORT | yes | WisGate MQTT port. Default is 1883. |
DEFAULT_MQTT_SUBSCRIBE_TOPIC | yes | WisGate application topic. Default is application/#. |
DEFAULT_CLOUD_AUTH_API_URL | no | Keep https://api.neogt.com.au/auth/api-client/authenticate unless Neotech provides another URL. |
DEFAULT_CLOUD_SYNC_API_URL | no | Keep https://api.neogt.com.au/devices/readings unless Neotech provides another URL. |
Example:
txt
DASHBOARD_IMAGE=ghcr.io/neotech-australia/tiltmeter-platform/dashboard:latest
COLLECTOR_IMAGE=ghcr.io/neotech-australia/tiltmeter-platform/collector:latest
DASHBOARD_PORT=443
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change-this-admin-password
JWT_SECRET_KEY=change-this-to-a-long-random-secret
ALLOW_INSECURE_JWT_SECRET=false
ACCESS_TOKEN_EXPIRE_MINUTES=15
REFRESH_TOKEN_EXPIRE_DAYS=7
POSTGRES_DB=lora
POSTGRES_USER=tiltmeter
POSTGRES_PASSWORD=change-this-local-db-password
DATABASE_URL=postgresql://tiltmeter:change-this-local-db-password@postgres:5432/lora
API_SSL_CERTFILE=/app/certs/localhost.pem
API_SSL_KEYFILE=/app/certs/localhost-key.pem
CORS_ORIGINS=https://localhost,https://127.0.0.1,https://localhost:443,https://127.0.0.1:443
DEFAULT_MQTT_HOST=192.168.1.42
DEFAULT_MQTT_SERVER_PORT=1883
DEFAULT_MQTT_SUBSCRIBE_TOPIC=application/#
DEFAULT_LOG_RETENTION_DAYS=30
DEFAULT_LOG_MAX_ROWS=10000
DEFAULT_CLOUD_AUTH_API_URL=https://api.neogt.com.au/auth/api-client/authenticate
DEFAULT_CLOUD_SYNC_API_URL=https://api.neogt.com.au/devices/readingsGenerate strong values for the secrets:
bash
openssl rand -hex 32powershell
[Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Maximum 256 }))Set up SSL
The stack expects these files:
txt
certs/localhost.pem
certs/localhost-key.pemFor a local self-signed certificate, run:
bash
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout certs/localhost-key.pem \
-out certs/localhost.pem \
-days 825 \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"powershell
openssl req -x509 -newkey rsa:2048 -nodes `
-keyout certs\localhost-key.pem `
-out certs\localhost.pem `
-days 825 `
-subj "/CN=localhost" `
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"If the site has a trusted certificate, place the certificate and private key in the same paths instead. The dashboard container reads the certificate from ./certs, and the collector container reads it from /app/certs.
Create docker-compose.yml
Create docker-compose.yml in the runtime folder:
yaml
services:
dashboard:
restart: always
image: ${DASHBOARD_IMAGE:-ghcr.io/neotech-australia/tiltmeter-platform/dashboard:latest}
environment:
DASHBOARD_API_UPSTREAM: https://collector:8000
ports:
- "${DASHBOARD_PORT:-443}:443"
volumes:
- ./certs:/etc/nginx/certs:ro
depends_on:
- collector
collector:
restart: always
image: ${COLLECTOR_IMAGE:-ghcr.io/neotech-australia/tiltmeter-platform/collector:latest}
env_file:
- .env
environment:
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?Set ADMIN_PASSWORD in .env}
JWT_SECRET_KEY: ${JWT_SECRET_KEY:?Set JWT_SECRET_KEY in .env}
DATABASE_URL: ${DATABASE_URL}
API_SSL_CERTFILE: ${API_SSL_CERTFILE:-/app/certs/localhost.pem}
API_SSL_KEYFILE: ${API_SSL_KEYFILE:-/app/certs/localhost-key.pem}
DEFAULT_MQTT_HOST: ${DEFAULT_MQTT_HOST}
DEFAULT_MQTT_SERVER_PORT: ${DEFAULT_MQTT_SERVER_PORT:-1883}
DEFAULT_MQTT_SUBSCRIBE_TOPIC: ${DEFAULT_MQTT_SUBSCRIBE_TOPIC:-application/#}
DEFAULT_CLOUD_AUTH_API_URL: ${DEFAULT_CLOUD_AUTH_API_URL:-https://api.neogt.com.au/auth/api-client/authenticate}
DEFAULT_CLOUD_SYNC_API_URL: ${DEFAULT_CLOUD_SYNC_API_URL:-https://api.neogt.com.au/devices/readings}
expose:
- "8000"
volumes:
- ./certs:/app/certs:ro
depends_on:
- postgres
postgres:
restart: always
image: postgres:18.1
expose:
- "5432"
environment:
POSTGRES_DB: ${POSTGRES_DB:-lora}
POSTGRES_USER: ${POSTGRES_USER:-tiltmeter}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
PGDATA: /var/lib/postgresql/18/data
volumes:
- postgres-data:/var/lib/postgresql
volumes:
postgres-data:Start the stack
bash
docker compose --env-file .env up -d
docker compose psOpen the dashboard:
txt
https://localhost:<DASHBOARD_PORT>For logs:
bash
docker compose logs --tail 300