This guide shows an example of configuring The Things Stack using configuration files, with an example domain
thethings.example.com and TLS certificates from Let’s Encrypt.
Note:If configuring The Things Stack as
localhoston a machine with no public IP or DNS address, see the
The Things Stack requires two configuration files when installing with Docker:
Example files for Enterprise and Open source are provided below.
docker-compose.yml defines the Docker services of The Things Stack and its dependencies, and is used to configure Docker.
ttn-lw-stack-docker.yml contains the configuration specific to The Things Stack deployment and is used to configure The Things Stack. When The Things Stack starts, it searches through
ttn-lw-stack-docker.yml for component server addresses, a TLS certificate source, client authentication credentials, and other configuration parameters.
The configuration options in
ttn-lw-stack-docker can also be specified using command-line flags or environment variables. All configuration options have a corresponding environment variable and command-line flag. See the Configuration Reference for more information about the configuration options.
This guide assumes the following directory hierarchy:
docker-compose.yml # defines Docker services for running The Things Stack config/ └── stack/ └── ttn-lw-stack-docker.yml # configuration file for The Things Stack
Example Configuration Files
Download the example
docker-compose.yml for The Things Stack Enterprise here.
Download the example
ttn-lw-stack-docker.yml for The Things Stack Enterprise here.
Download the example
docker-compose.yml for The Things Stack Open Source here.
Download the example
ttn-lw-stack-docker.yml for The Things Stack Open Source here.
These example configuration files contain all of the configuration settings you need to run The Things Stack for development. Be sure to update
ttn-lw-stack-docker.yml with your server address, generate keys in
http.cookie and set
For an extended explanation of the configuration settings, keep reading.
ttn-lw-stack-docker.yml files are explained in detail in Docker Configuration and The Things Stack Configuration sections. Further, we provide tips for running The Things Stack in production.
Understanding Docker Configuration
In this section, configuring Docker is explained with an example
Docker runs an instance of The Things Stack, as well as an SQL database and a Redis database, which The Things Stack depends on to store data.
docker-compose.yml file, Docker is configured to run three services:
- An SQL database (CockroachDB and PostgreSQL are supported)
- The Things Stack
To configure an SQL database, a single instance of CockroachDB is used in this guide. Note that the
volumes need to be set up correctly so that the database is persisted on your server’s disk.
In production, replace the
image with a working, stable tag from Docker Hub - CoackroachDB.
It is also possible (and even preferred) to use a managed SQL database. In this case, you will need to configure the managed database URI with the
is.database-uri configuration option or
TTN_LW_IS_DATABASE_URI environment variable.
The simplest configuration for CockroachDB looks like this (excerpted from the example
The configuration in this guide uses a single instance of Redis. Again, note that the
volumes need to be set up correctly so that the datastore is persisted on your server’s disk.
Note:The Things Stack requires Redis version 5.0 or newer.
In production, replace the
image with a working, stable tag from Docker Hub - Redis.
It is also possible (and even preferred) to use a managed Redis database. In this case, you will need to configure the managed database address with the
redis-address configuration option or
TTN_LW_REDIS_ADDRESS environment variable.
The simplest configuration for Redis looks like this (excerpted from the example
The Things Stack
Entrypoint and dependencies
Docker Compose uses
ttn-lw-stack -c /config/ttn-lw-stack-docker.yml as the container entry point, so that
ttn-lw-stack-docker.yml configuration file is always loaded (more on the config file below).
The default command is
start, which starts The Things Stack.
depends_on field tells Docker Compose that The Things Stack depends on CockroachDB and Redis. With this, Docker Compose will wait for CockroachDB and Redis to come online before starting The Things Stack.
Note:If using a managed SQL or Redis database, these can be removed from
depends_onand the services do not need to be started in Docker.
volumes section, volumes for the files that need to be persisted on the disk are defined. There are stored blob files (such as profile pictures) and certificate files retrieved with ACME (if required). Also, local
./config/stack/ directory is mounted on the container under
/config, so that The Things Stack can find the configuration file at
ttn-lw-stack-docker.ymlis in a directory other than
./config/stack, you will need to change this volume accordingly.
Environment and Ports
The databases used by The Things Stack are configured in the
environment section. In this guide, these are set to the CockroachDB and Redis instances that are mentioned above.
Note:If using managed databases, the
environmentports need to be changed to the ports of the managed databases.
ports section exposes The Things Stack’s ports outside the Docker container. Port
443 are mapped to the internal HTTP and HTTPS ports. The other ports have a direct mapping. If you don’t need support for gateways and applications that don’t use TLS, you can remove ports starting with
Understanding The Things Stack Configuration
Configuration options for running The Things Stack are specified in the
ttn-lw-stack-docker.yml file. This section points out the required configuration options.
ttn-lw-stack-docker.yml file for The Things Stack Enterprise shown below contains details which help you follow this section.
Example ttn-lw-stack-docker.yml file
ttn-lw-stack-docker.ymlfile is available for download in the Example Configuration Files section.
The Things Stack Enterprise requires a license, which can be purchased at the products page. This is specified in the
license field, and can be either a
key string, or a
filepath. See the License configuration reference for more information.
This example shows the configuration for using TLS with Let’s Encrypt. Since The Things Stack is being deployed on
thethings.example.com in this guide, it is configured to only request certificates for that
host, and also to use it as the default host.
If using Let’s Encrypt, certificates will automatically be requested the first time you access The Things Stack. You will notice that the page takes some time to load while certificates are obtained in the background.
See the TLS Options configuration reference for more information.
Note:Make sure that you use the correct
tlsconfiguration depending on whether you are using Let’s Encrypt or your own certificate files.
Note:If you are using your own certificate files, make sure to uncomment the lines that define
key. The paths assigned to these do not need to be altered, because they point to the location of these files inside the Docker container, and not on your machine.
http section, HTTP server keys for encrypting and verifying cookies are configured, as well
as passwords for endpoints that you may want to keep for the internal use.
The Things Stack sends emails to users, so the
console section configures the URLs for the Web UI and the secret used
by the console client. These tell The Things Stack where all its components are accessible.
client-secretwill be needed later when authorizing the Console. Be sure to set and remember it!
Warning:Failure to correctly configure component URLs is a common problem that will prevent the stack from starting. Be sure to replace all instances of
thethings.example.comwith your domain name!
If running a multi-tenant environment, we need to configure the default tenant ID, and the base domain from which tenant IDs are inferred. See the
tenancy configuration reference.
Running The Things Stack as
Follow this section if you are configuring and running The Things Stack on a local machine with no public IP or DNS address.
localhost has a different meaning on your machine than inside the Docker container where The Things Stack runs, which can cause problems if you use
localhost in your configuration.
localhost addresses on your machine will resolve to your machine, while
localhost inside the Docker container will resolve inside the Docker container. In
docker-compose.yml, we forward requests on ports 80 and 443 to ports 1885 and 8885 inside the container, so visiting
localhost (which is really
localhost:80) on your machine actually takes you to
localhost:1885 within the container.
If you configure your
localhost, this causes Token Exchange Refused errors when you try to log in to The Things Stack Console, because an authorization request generated from within the container will not be redirected to port 1885 or 8885, where The Things Stack is listening.
Solution 1: Use the IP address of your computer on your local network
The best solution is to configure and use a static IP address for your machine on your local network so that redirects from your machine, from the Docker container, or from anywhere inside your local network, all resolve at the same place, on your machine.
Follow instructions here for configuring a static IP address on your computer. Use that IP address as your server address, i.e replace
thethings.example.com with that IP address. You may also generate a self-signed certificate for that IP address by following instructions in the Certificates section.
Note:ACME will not work on
localhost, so you must either generate custom certificates for your IP address as shown in the Custom Certificate Authority instructions, or use
http(unsecure) in your configuration.
This will still allow you to see The Things Stack Console by entering
localhost or your local IP address in your browser. It will also allow you to connect to The Things Stack from any machine inside your local network.
You will also need to configure the CLI, to use the static IP of your machine as the address of The Things Stack.
Solution 2: Specify the internal ports that The Things Stack listens on in your configuration files
By default, The Things Stack listens on ports 1885 and 8885 inside Docker. To make
localhost work both on your local machine and within the Docker container, append the port to
localhost and make sure port forwarding is enabled in your
docker-compose.yml for that port.
You must also remove ports 80 and 443 from your The Things Stack Docker configuration.
is: oauth: ui: canonical-url: 'https://thethings.example.com/oauth' is: base-url: 'https://thethings.example.com/api/v3'
is: oauth: ui: canonical-url: 'https://localhost:8885/oauth' is: base-url: 'https://localhost:8885/api/v3'
docker-compose.yml, add the following port forwarding configuration (if it does not already exist), while removing ports 80 and 443:
services: stack: ports: stack: - "1885:1885" - "8885:8885" # - "80:80" # Do not forward port 80 # - "443:443" # Do not forward port 443
This will result in visits from both outside and inside the Docker container being received at the correct port by The Things Stack.