tessera

Getting started

Run it, then sign in

tessera is a self-hosted file courier. Upload a file, get a retrieval code, hand the code to whoever needs it.

The upload page

Upload page: drop files, paste text, or add a link

The page shown after uploading

After uploading: link, QR code, expiry

Run it

Pull the image

docker pull ghcr.io/limatura/tessera:latest

:latest is the newest release, and :sha-<commit> pins one build. amd64 and arm64 are both published, so a Pi or a NAS works.

To build it yourself instead, docker build -f apps/server/Dockerfile -t tessera . compiles the frontend in as well.

Start it

docker run -p 12923:12923 -v tessera-data:/data ghcr.io/limatura/tessera:latest

The data lives in a named volume, tessera-data. Docker creates it on first run and it is already writable by the server. To keep the data in a directory you choose instead, use the Docker Compose tab.

Take the admin password from the log

The image logs JSON, one object per line. Pick it out with:

docker logs <container> 2>&1 | grep password

With Compose, use docker compose logs tessera 2>&1 | grep password.

The line looks like this:

{
  "timestamp": "…",
  "level": "WARN",
  "message": "created the first administrator with a generated password; sign in and change it",
  "username": "admin",
  "password": "1e3bc629…",
  "target": "tessera_server::auth::bootstrap"
}

This line is printed once

Restarts will not print it again. If you miss it, set a new one with reset-password.

Sign in, then change the password

You will be blocked from everything else until you do.

Without Docker

Each release also carries the server on its own, for Linux (x86_64 and arm64, static, so any distribution) and macOS (Intel and Apple Silicon). There is none for Windows; use Docker there. The web interface is built in, so the one file is the whole instance.

curl -fsSL https://github.com/Limatura/tessera/releases/latest/download/tessera-server-linux-x86_64.tar.gz | tar -xz
./tessera-server

Started like this, it differs from the image in three ways:

  • It listens on 127.0.0.1:12923, so only this machine can reach it. Put a reverse proxy in front, or set TESSERA_SERVER__HOST=0.0.0.0.
  • The data goes in data/ under the directory you start it from.
  • The log is plain text, and the admin password is on the line that ends username=admin password=….

To keep the data somewhere else, set both of these:

TESSERA_SERVER__DATA_DIR=/var/lib/tessera \
TESSERA_DATABASE__URL=sqlite:///var/lib/tessera/tessera.db \
./tessera-server

The database does not follow the data directory

Set only TESSERA_SERVER__DATA_DIR and the database stays in data/tessera.db under wherever you started it. The admin commands such as tessera-server reset-password read the same settings, so run them with the same variables, from the same directory. Otherwise they work on a different, empty database.

What ends up in /data

tessera.db
secret.key

blobs holds the uploaded content until you add somewhere else to keep it. secret.key encrypts the credentials stored in the database: storage backend addresses, the mail password, sign-in providers' secrets.

Back up secret.key with the database

A database restored without it still opens, but every sealed credential in it is unreadable and has to be entered again. See configuration.

Settings are not in the volume. They come from the environment and from the admin panel, at /admin/ on the same address.

Without a volume on /data, everything is gone the next time the container is rebuilt.

Next

On this page