Skip to content

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.1

Create .env

Create a .env file in the runtime folder. Set these values before starting the stack:

VariableRequiredHow to set it
DASHBOARD_PORTyesPublic HTTPS port for the local dashboard. Use 443 unless another service already uses it.
ADMIN_USERNAMEyesInitial local dashboard admin username. Default is admin.
ADMIN_PASSWORDyesInitial local dashboard admin password. Use a site-specific password.
JWT_SECRET_KEYyesRandom secret for API tokens. Use a long random hex or base64 value.
POSTGRES_PASSWORDyesRandom database password. The same value must be used inside DATABASE_URL.
DATABASE_URLyespostgresql://tiltmeter:<POSTGRES_PASSWORD>@postgres:5432/lora
DEFAULT_MQTT_HOSTyesWisGate LAN IP address. Change this to the gateway IP for the site.
DEFAULT_MQTT_SERVER_PORTyesWisGate MQTT port. Default is 1883.
DEFAULT_MQTT_SUBSCRIBE_TOPICyesWisGate application topic. Default is application/#.
DEFAULT_CLOUD_AUTH_API_URLnoKeep https://api.neogt.com.au/auth/api-client/authenticate unless Neotech provides another URL.
DEFAULT_CLOUD_SYNC_API_URLnoKeep 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/readings

Generate strong values for the secrets:

bash
openssl rand -hex 32
powershell
[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.pem

For 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 ps

Open the dashboard:

txt
https://localhost:<DASHBOARD_PORT>

For logs:

bash
docker compose logs --tail 300

Neotech Geotechnical Engineering documentation.