Unable to connect to web console

Hi, I’m hoping someone can give me some direction on where to look to help me solve my issue. I’m new to TTN and also to Docker.

The summary of what I’m trying to do is to run TTN docker container on a local machine. I’ve got the docker container running but cannot load the web page console from my browser.

Detail of what I’ve done and where I’m up to…

  • I started by reading all of the Docker docs here: Docker | The Things Stack for LoRaWAN
  • I’ve watched the YouTube videos on setting up TTN and setting up TTN to run on a local machine.
  • Because I am trying to run on a local machine I did the steps to create custom certificates by downloading the CloudFlare SSL certificate creation tool and following the instructions.
  • I’ve got the docker container to the point where it runs and there are no errors output on the terminal any more
  • When the docker container is running I open a browser and try to log onto https://192.168.1.11 or http://localhost:1885 or http://localhost:8885 and the web page never loads.

Here is my docker-compose.yml:

version: "3.7"
services:
  postgres:
    image: postgres:14
    restart: unless-stopped
    environment:
      - POSTGRES_PASSWORD=root
      - POSTGRES_USER=root
      - POSTGRES_DB=ttn_lorawan_dev
    volumes:
      - ${DEV_DATA_DIR:-.env/data}/postgres:/var/lib/postgresql/data
      - .env/cache:/var/lib/ttn-lorawan/cache
    ports:
      - "127.0.0.1:5432:5432"

  redis:
    image: redis:7
    command: redis-server --appendonly yes
    restart: unless-stopped
    volumes:
      - ${DEV_DATA_DIR:-.env/data}/redis:/data
    ports:
      - "127.0.0.1:6379:6379"

  stack:
    image: thethingsnetwork/lorawan-stack
    entrypoint: ttn-lw-stack -c /config/ttn-lw-stack-docker.yml
    command: start
    restart: unless-stopped
    depends_on:
      - redis
      - postgres
    volumes:
      - ./blob:/srv/ttn-lorawan/public/blob
      - ./config/stack:/config:ro
      # If using Let's Encrypt:
      # - ./acme:/var/lib/acme
    environment:
      TTN_LW_BLOB_LOCAL_DIRECTORY: /srv/ttn-lorawan/public/blob
      TTN_LW_REDIS_ADDRESS: redis:6379
      TTN_LW_IS_DATABASE_URI: postgres://root:root@postgres:5432/ttn_lorawan_dev?sslmode=disable
      TTN_LW_OAUTH_SERVER_ADDRESS: https://192.168.1.11:8885/oauth

    ports:
      # If deploying on a public server:
      # - "80:1885"
      # - "443:8885"
      - "1881:1881"
      - "8881:8881"
      - "1882:1882"
      - "8882:8882"
      - "1883:1883"
      - "8883:8883"
      - "1884:1884"
      - "8884:8884"
      - "1885:1885"
      - "8885:8885"
      - "1887:1887"
      - "8887:8887"
      - "1700:1700/udp"

    # If using custom certificates:
    secrets:
      - ca.pem
      - cert.pem
      - key.pem

# If using custom certificates:
secrets:
  ca.pem:
    file: ./ca.pem
  cert.pem:
    file: ./cert.pem
  key.pem:
    file: ./key.pem

Here is my ttn-lw-stack-docker.yml:

# Example ttn-lw-stack configuration file

# Identity Server configuration
# is:
  # Email configuration for "thethings.example.com"
  # email:
    # sender-name: 'The Things Stack'
    # sender-address: 'noreply@thethings.example.com'
    # network:
    #   name: 'The Things Stack'
    #   console-url: 'https://thethings.example.com/console'
    #   identity-server-url: 'https://thethings.example.com/oauth'

    # If sending email with Sendgrid
    # provider: sendgrid
    # sendgrid:
    #   api-key: '...'              # enter Sendgrid API key

    # If sending email with SMTP
    # provider: smtp
    # smtp:
    #   address:  '...'             # enter SMTP server address
    #   username: '...'             # enter SMTP server username
    #   password: '...'             # enter SMTP server password

  # Web UI configuration for "thethings.example.com":
  # oauth:
  #   ui:
  #     canonical-url: 'https://thethings.example.com/oauth'
  #     is:
  #       base-url: 'https://thethings.example.com/api/v3'

# HTTP server configuration
http:
  cookie:
    block-key: 'cf7e5e2a37b54b96d288cbe6bc36735c18eb709ba618a243a88c7fa5e1bb698e'                # generate 32 bytes (openssl rand -hex 32)
    hash-key: 'e335d2c31bc3795e309d488c9312f060c79b06ad49c06e31a3e5e9469db08fc0db62fc7e4c8b3fb754fbb9908876fe447793694d51cdc30b225994f030a052dc'                 # generate 64 bytes (openssl rand -hex 64)
  metrics:
    password: 'metrics'               # choose a password
  pprof:
    password: 'pprof'                 # choose a password

# If using custom certificates:
tls:
  source: file
  root-ca: /run/secrets/ca.pem
  certificate: /run/secrets/cert.pem
  key: /run/secrets/key.pem

# Let's encrypt for "thethings.example.com"
# tls:
#   source: 'acme'
#   acme:
#     dir: '/var/lib/acme'
#     email: 'you@thethings.example.com'
#     hosts: ['thethings.example.com']
#     default-host: 'thethings.example.com'

# If Gateway Server enabled, defaults for "thethings.example.com":
gs:
  mqtt:
    public-address: 'localhost:1882'
    public-tls-address: 'localhost:8882'
  mqtt-v2:
    public-address: 'localhost:1881'
    public-tls-address: 'localhost:8881'

# If Gateway Configuration Server enabled, defaults for "thethings.example.com":
gcs:
  basic-station:
    default:
      lns-uri: 'wss://localhost:8887'
  the-things-gateway:
    default:
      mqtt-server: 'mqtts://localhost:8881'

# Web UI configuration for "thethings.example.com":
console:
  ui:
    canonical-url: 'https://localhost/console'
    is:
      base-url: 'https://localhost/api/v3'
    gs:
      base-url: 'https://localhost/api/v3'
    ns:
      base-url: 'https://localhost/api/v3'
    as:
      base-url: 'https://localhost/api/v3'
    js:
      base-url: 'https://localhost/api/v3'
    qrg:
      base-url: 'https://localhost/api/v3'
    edtc:
      base-url: 'https://localhost/api/v3'
    dcs:
      base-url: 'https://localhost/api/v3'

#   oauth:
#     authorize-url: 'https://thethings.example.com/oauth/authorize'
#     token-url: 'https://thethings.example.com/oauth/token'
#     client-id: 'console'
#     client-secret: 'console'          # choose or generate a secret

Here is the logs from the terminal when I execute docker-compose up:

Starting the-things-stack_redis_1    ... done
Starting the-things-stack_postgres_1 ... done
Recreating the-things-stack_stack_1  ... done
Attaching to the-things-stack_redis_1, the-things-stack_postgres_1, the-things-stack_stack_1
postgres_1  | 
postgres_1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres_1  | 
postgres_1  | 2023-07-05 06:44:53.994 UTC [1] LOG:  starting PostgreSQL 14.8 (Debian 14.8-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres_1  | 2023-07-05 06:44:53.999 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres_1  | 2023-07-05 06:44:53.999 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres_1  | 2023-07-05 06:44:54.001 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1  | 2023-07-05 06:44:54.012 UTC [26] LOG:  database system was shut down at 2023-07-05 06:44:22 UTC
postgres_1  | 2023-07-05 06:44:54.035 UTC [1] LOG:  database system is ready to accept connections
redis_1     | 1:C 05 Jul 2023 06:44:52.875 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1     | 1:C 05 Jul 2023 06:44:52.876 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1     | 1:C 05 Jul 2023 06:44:52.876 # Configuration loaded
redis_1     | 1:M 05 Jul 2023 06:44:52.877 * monotonic clock: POSIX clock_gettime
redis_1     | 1:M 05 Jul 2023 06:44:52.881 * Running mode=standalone, port=6379.
redis_1     | 1:M 05 Jul 2023 06:44:52.881 # Server initialized
redis_1     | 1:M 05 Jul 2023 06:44:52.881 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1     | 1:M 05 Jul 2023 06:44:52.886 * Reading RDB base file on AOF loading...
redis_1     | 1:M 05 Jul 2023 06:44:52.887 * Loading RDB produced by version 7.0.11
redis_1     | 1:M 05 Jul 2023 06:44:52.887 * RDB age 605217 seconds
redis_1     | 1:M 05 Jul 2023 06:44:52.887 * RDB memory usage when created 0.82 Mb
redis_1     | 1:M 05 Jul 2023 06:44:52.888 * RDB is base AOF
redis_1     | 1:M 05 Jul 2023 06:44:52.888 * Done loading RDB, keys loaded: 0, keys expired: 0.
redis_1     | 1:M 05 Jul 2023 06:44:52.890 * DB loaded from base file appendonly.aof.1.base.rdb: 0.006 seconds
redis_1     | 1:M 05 Jul 2023 06:44:52.892 * DB loaded from incr file appendonly.aof.1.incr.aof: 0.002 seconds
redis_1     | 1:M 05 Jul 2023 06:44:52.893 * DB loaded from append only file: 0.009 seconds
redis_1     | 1:M 05 Jul 2023 06:44:52.911 * Opening AOF incr file appendonly.aof.1.incr.aof on server start
redis_1     | 1:M 05 Jul 2023 06:44:52.911 * Ready to accept connections
stack_1     | INFO	Setting up core component
stack_1     | INFO	Setting up Identity Server
stack_1     | INFO	Setting up Gateway Server
stack_1     | INFO	Setting up Network Server
stack_1     | INFO	Setting up Application Server
stack_1     | INFO	Setting up Join Server
stack_1     | INFO	Setting up Console
stack_1     | INFO	Setting up Gateway Configuration Server
stack_1     | INFO	Setting up Device Template Converter
stack_1     | INFO	Setting up QR Code Generator
stack_1     | INFO	Setting up Packet Broker Agent
stack_1     | INFO	Setting up Device Repository
stack_1     | INFO	Setting up Device Claiming Server
stack_1     | INFO	Starting...
stack_1     | WARN	No cluster key configured, generated a random one	{"key": "cc0483488db8e7c63ffd470becd8ff3019a66e47ba9ac98b90bab819b8693ca2", "namespace": "cluster"}
stack_1     | INFO	Listening for connections	{"address": ":1884", "namespace": "grpc", "protocol": "gRPC"}
stack_1     | INFO	Listening for connections	{"address": ":8884", "namespace": "grpc", "protocol": "gRPC/tls"}
stack_1     | INFO	Listening for connections	{"address": ":1885", "namespace": "web", "protocol": "Web"}
stack_1     | INFO	Listening for connections	{"address": ":8885", "namespace": "web", "protocol": "Web/tls"}
stack_1     | INFO	Listening for connections	{"address": ":1886", "namespace": "interop", "protocol": "Interop"}
stack_1     | INFO	Listening for connections	{"address": ":8886", "namespace": "interop", "protocol": "Interop/tls"}
stack_1     | WARN	Failed to check version update	{"error": "Get \"https://www.thethingsindustries.com/releases/thethingsstack-open-source.json\": dial tcp 65.8.33.103:443: connect: no route to host"}
stack_1     | WARN	Task failed	{"error": "Get \"https://www.thethingsindustries.com/releases/thethingsstack-open-source.json\": dial tcp 65.8.33.89:443: connect: no route to host", "invocation": 3, "task_id": "version_check"}
stack_1     | INFO	Request handled	{"duration": 0.0013, "http.method": "GET", "http.path": "/healthz", "http.status": 200, "namespace": "web", "peer.address": "127.0.0.1:52042", "request_id": "01H4JCSVHCJR7ATJKWRD0KECDA"}

Note the last line here looks to me like TTN is receiving the GET request from the browser. To me, the issue feels like it is a problem with getting the response data out of the docker container.

I appreciate anyone who can point me in a direction to help me get this working. TIA.

Can you confirm you looked at, read, digested and applied the section on why localhost is a bad bad bad move and a mess to implement and when you get it right it still isn’t right as you don’t know which localhost something may be using (hint, where is localhost when you are inside Docker and where is localhost when you are outside it and where is localhost is another computer on your network)

Whereas using an IP address mostly just works.

Yes, I have seen that somewhere. I have tried many iterations of these two configuration files including specifying my local IP address “192.168.1.11” in place of “localhost”. I will go back to trying this again and see if it will solve the issue.

Any suggestion of where I can look at logs or network traces or something to help me track down where the issue is?

Not really as I try to keep it all simple - so I follow the instructions in the documentation that are specifically written for local in-office test instances using an IP address and have domain named instance on external servers. Although I will take some of the credit for the doc’s regarding IP vs localhost arriving where they are having run TTS OS since release, and I set an IP address one on Saturday (ten minutes), so I’m pretty confident that if you go with the flow of docs, you’ll find it’s all good.

I’ve got TTN to the point where I can load the login page now. I got this by specifying my local IP address instead of “localhost” in the configuration files. Thanks for your input.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.