Run Tiled Server in a Container
There is an official Tiled container image for use with Docker or podman.
Download the Tiled container image.
docker pull ghcr.io/bluesky/tiled:latest
It is best practice to use a specific tag instead of latest
.
See the list of tiled image versions on GitHub
for tags.
Note
Some of the examples below set an environment variable
TILED_SINGLE_USER_API_KEY
to secret
, as a placeholder. For actual use, use
a difficult-to-guess secret. Two equally good ways to generate a secure
secret…
With openssl
:
openssl rand -hex 32
With python
:
python -c "import secrets; print(secrets.token_hex(32))"
Example: A writable catalog
docker run \
-p 8000:8000 \
-e TILED_SINGLE_USER_API_KEY=secret \
ghcr.io/bluesky/tiled:latest
The data and database are inside the container and will not persist outside it. Read on to persist it.
Example: A persistent writable catalog
We will create and mount a local directory, ./storage
which will be used to
hold uploaded data and # a (SQLite) database to index the metadata.
mkdir storage/
docker run \
-p 8000:8000 \
-e TILED_SINGLE_USER_API_KEY=secret \
-v ./storage:/storage ghcr.io/bluesky/tiled:latest
Example: Serve a directory of existing files
We will point Tiled at a (read-only) directory of files and ask it to crawl and serve them. If you don’t have scientific data files at hand to try this with, you can quickly generate some with:
# Optional: Generate sample files... TIFF, Excel, HDF5, etc.
python -m tiled.examples.generate_files data/
Quick Start (Not Scalable)
This approach is nice for development and rapid iteration. It indexes the files at server startup.
docker run \
-p 8000:8000 \
-e TILED_SINGLE_USER_API_KEY=secret \
-v ./data:/data:ro \
ghcr.io/bluesky/tiled:latest \
tiled serve directory --host 0.0.0.0 /data
Two problems with this one-line approach:
If you restart the server, all the indexing work is re-done from scratch.
If you horizontally scale with multiple containers, each one will crawl the filesystem individually, putting load on the filesystem and potentially getting views of the filesystem that are out of sync.
Read on for a scalable approach.
Scalable to Multiple Processes
Create a place outside the container to store the “catalog”, catalog.db
.
mkdir storage/
Start the server, potentially multiple on different ports.
docker run \
-p 8000:8000 \
-e TILED_SINGLE_USER_API_KEY=secret \
-v ./data:/data:ro \
-v ./storage:/storage \
ghcr.io/bluesky/tiled:latest
Register the files in the directory data/
with the catalog.
docker run \
-e TILED_SINGLE_USER_API_KEY=secret \
-v ./data:/data:ro \
ghcr.io/bluesky/tiled:latest \
tiled register http://localhost:8000/ /data --verbose
Scalable to Multiple Hosts
We will use one container to run a database server, and additional containers to run tiled services. To connect these services we create a bridge network.
docker network create -d bridge tilednet
Note
We chose to use a custom bridge network here for two reasons:
The host network is not supported for Docker Desktop for Mac/Windows
The default bridge network does not resolve container DNS entries by hostname
Instead of the default SQLite database, we need to use a PostgreSQL database. One way to run a PostgresSQL database is:
export TILED_DATABASE_PASSWORD=db_secret
mkdir postgres-data
docker run -d \
--name tiled-test-postgres \
--net=tilednet \
-p 5432:5432 \
-e POSTGRES_PASSWORD=${TILED_DATABASE_PASSWORD} \
-v ./postgres-data:/var/lib/postgresql/data \
docker.io/postgres:16
Initialize the database. (This creates the tables, indexes, and so on used by Tiled.)
export TILED_DATABASE_URI=postgresql+asyncpg://postgres:${TILED_DATABASE_PASSWORD}@tiled-test-postgres:5432
docker run --net=tilednet ghcr.io/bluesky/tiled:latest tiled catalog init $TILED_DATABASE_URI
Create a directory for Tiled configuration, e.g. config/
.
mkdir config/
Place a copy of example_configs/single_catalog_single_user.yml
, from the Tiled
repository root, in this config/
directory.
Replace the line:
uri: "sqlite+aiosqlite:////storage/catalog.db"
with a PostgreSQL database URI, such as:
uri: "postgresql+asyncpg://postgres:${TILED_DATABASE_PASSWORD}@tiled-test-postgres:5432"
Start the server, potentially multiple servers across many hosts.
docker run \
--net=tilednet \
-p 8000:8000 \
-e TILED_SINGLE_USER_API_KEY=secret \
-e TILED_DATABASE_PASSWORD=${TILED_DATABASE_PASSWORD} \
-v ./config:/deploy/config:ro \
-v ./data:/data:ro \
ghcr.io/bluesky/tiled:latest
Register the files in the directory data/
with this catalog.
docker run \
--net=tilednet \
-e TILED_SINGLE_USER_API_KEY=secret \
-v ./data:/data:ro \
ghcr.io/bluesky/tiled:latest \
tiled register http://localhost:8000/ /data --verbose
Example: Custom configuration
There are configuration examples located in the directory example_configs
under the Tiled repository root. The container image has one in particular,
single_user_single_catalog.yml
, copied into the container under
/deploy/config/
. Override it by mounting a local directory an
/deploy/config
as shown:
docker run \
-p 8000:8000 \
-e TILED_SINGLE_USER_API_KEY=secret \
-v ./config:/deploy/config:ro \
ghcr.io/bluesky/tiled:latest
You may need to mount additional volumes as well.
Example: Run Tiled with a dashboard of metrics
See Prometheus Metrics.
Next Steps
See Security and Access Control for examples addressing authentication and authorization.
See Service Configuration Reference for a comprehensive reference.