Anten
Türkçe

Operator guide

Setup

Try Anten on your own computer first, or put it straight on a server with a domain name and HTTPS. Becoming an administrator, access, backups and updates are on this page too.

For
Anyone running their own Anten
Time
The first build takes a few minutes
You need
Docker Compose, 2 GB of memory
You get
An Anten others can connect to

You can try Anten on your own computer first, or put it straight on a server with a domain name and HTTPS. Both ways use the same files and the same .env file.

Anten runs in two containers: antend (one program holding the web client, the voice server and the API) and a PostgreSQL database. Docker Compose starts and manages them.

What you need

  • Docker Engine and Docker Compose v2. Use Docker Engine on a server, or Docker Desktop on your own computer. docker compose version should print a version number.
  • At least 2 GB of memory. Anten is built from its source files on first start; this takes a few minutes.
  • For an internet-facing installation, also:
    • a server with a public IP address,
    • a domain name (for example anten.example.org) whose DNS A record (and AAAA record, if any) points to the server’s address,
    • open ports: 80/TCP, 443/TCP and UDP (web), 50000/UDP and TCP (voice and video).

Prepare the settings

Every command here runs in the deploy folder of Anten’s files. The settings live in that folder’s .env file, and .env.example is its template.

  1. Copy the settings template.

    cd deploy
    cp .env.example .env
    
  2. Generate a random password for the database.

    openssl rand -hex 32
    
  3. Add that value to the end of the POSTGRES_PASSWORD= line in .env.

    The password becomes part of the database address, so keep it hexadecimal.

ANTEN_SERVER_NAME sets the server’s name, and ANTEN_LANGUAGE the language (tr or en) of the groups and rooms made on first start. The other settings are under Reference.

Try it on your computer

  1. Start Anten.

    docker compose up -d --build
    

    The first build takes a few minutes.

  2. Check the containers.

    docker compose ps
    

    Both containers should be Up; antend shows healthy shortly after.

  3. Open http://localhost:8080 in your browser and connect with a nickname.

  4. Become an administrator.

    Follow the steps in Become an administrator.

To connect as a second person on the same computer, open http://127.0.0.1:8080 in another tab; the browser treats it as a separate site. Wear headphones when trying voice, or you will hear yourself with a delay.

Connect from your network

Other computers at home or in the office can connect too. In the examples, this computer’s local network address is 192.168.1.20.

  1. Set these two lines in .env (removing the # at the start of the RTC_HOSTS line).

    ANTEN_BIND=0.0.0.0
    RTC_HOSTS=192.168.1.20
    
  2. Restart Anten with the new settings.

    docker compose up -d
    
  3. On the other computers, open http://192.168.1.20:8080.

Because these computers connect over HTTP, they can only listen; speaking needs an installation with HTTPS. If this computer’s network address changes, update RTC_HOSTS too.

Put the server online

The docker-compose.server.yml addition puts Caddy in front of Anten. Caddy is a reverse proxy: it takes web requests and passes them on to Anten, and gets and renews the Let’s Encrypt certificate for your domain on its own. The voice port is public and goes straight to Anten.

On a Linux server, run the commands with sudo if your user is not in the docker group; the examples in this section are written that way.

  1. Point your domain’s DNS record to the server’s IP address.

    Wait for the record to spread before you go on.

  2. Set these two lines in .env (removing the # at their start).

    ANTEN_DOMAIN=anten.example.org
    COMPOSE_FILE=docker-compose.yml:docker-compose.server.yml
    

    With COMPOSE_FILE you need not name the addition in every command. Leave ANTEN_COOKIE_SECURE, ANTEN_BIND and RTC_HOSTS alone: the addition sets them and tells clients to reach voice at your domain.

  3. Open the needed ports in the firewall.

    sudo ufw allow 22/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443
    sudo ufw allow 50000
    sudo ufw enable
    

    The example is for ufw. Docker opens the ports it publishes ahead of the ufw rules; the rules still show in one place what is open. If your provider’s panel has a firewall of its own, open the same ports there. If you can, open SSH (22) only to your own address, or allow key login only.

  4. Start Anten.

    sudo docker compose up -d --build
    
  5. Open https://anten.example.org and connect with a nickname.

    The certificate is issued within a few seconds of the first start. If it is not, see The certificate is not issued.

  6. Become an administrator.

    Follow the steps in Become an administrator.

Behind an existing web server

If a web server such as nginx already uses ports 80 and 443 for other sites, do not install Caddy; use the docker-compose.nginx.yml addition instead of docker-compose.server.yml. With it, antend listens only at 127.0.0.1:8088, reachable from inside the server; the voice port (50000) stays public.

  1. Set these two lines in .env.

    ANTEN_DOMAIN=anten.example.org
    COMPOSE_FILE=docker-compose.yml:docker-compose.nginx.yml
    
  2. Create a site for the domain on your web server and get its certificate.

  3. Add a rule to the site that passes requests on to 127.0.0.1:8088.

    location / {
    	proxy_pass http://127.0.0.1:8088;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection "upgrade";
    	proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $remote_addr;
    	proxy_set_header X-Forwarded-Proto $scheme;
    	proxy_read_timeout 1h;
    	proxy_send_timeout 1h;
    	client_max_body_size 510m;
    }
    

    Anten’s live connection is a WebSocket, hence the Upgrade and Connection headers and the long timeouts. client_max_body_size should be a little larger than Largest file in the server settings and than your backup files (nginx’s default limit is 1 MB).

  4. Start Anten.

    sudo docker compose up -d --build
    

This addition makes antend read people’s real address from the proxy’s X-Forwarded-For header. If you put a proxy of your own in front of Anten in some other arrangement, add ANTEN_TRUSTED_PROXIES=private to .env. Otherwise everyone seems to come from the proxy’s address, and address bans and per-address limits do not work.

Become an administrator

On first start, while there is no administrator yet, antend writes a framed, single-use privilege key to its logs. The key adds whoever uses it to the administrator group.

  1. Find the privilege key in the logs.

    docker compose logs antend
    
  2. Connect to Anten with a nickname.

  3. In the server menu, choose Use a privilege key, enter the key and press Use.

If you lost the key or need a second administrator, make a new one:

docker compose exec antend /antend privilege-key

Later, administrators can make keys for any server group under Server settings → Privilege keys. Give keys only to people you trust.

Choose who may connect

You decide who may connect under Server settings → Access. Changes apply at once.

  • New users can connect: When off, only identities and accounts that connected before can sign in.
  • Account sign-in: Besides identity keys, lets people make accounts with a username and password. Off by default. The password itself is never sent to the server.
  • Server password: When on, everyone connecting has to enter this password.
  • Connections per address: At most 5 people at once and 3 new identities an hour from one internet address (the defaults). Raise them for a busy home, dorm or office; 0 means no limit. Administrators are not counted; IPv6 addresses are counted by /64 block.

Besides these, a user may hold at most 10 connections at once, and sign-in attempts, messages and signals in voice rooms are rate limited. Identity and address bans are managed under Server settings → Bans.

Make backups

Back up from the app

This is the recommended way. Only administrators see Server settings → Backups.

  1. Under Make a backup, enter a backup password of at least 10 characters, and repeat it.

    The backup is encrypted with this password (age, scrypt).

  2. Press Download the backup.

    The whole server (rooms, groups and permissions, members, bans, messages, sent files, profile pictures) is written to a single .anten file. Sessions are not included. People can keep using the server meanwhile.

  3. Keep the file and its password in separate, safe places.

To restore, under Restore from a backup press Choose a backup file, type the backup’s password and, to confirm, RESTORE, then press Restore the server. All of the server’s data is replaced by the backup’s; anything written after the backup is gone. It is a single database transaction: a wrong password or a broken file changes nothing. When it is done, everyone is disconnected and the pages reload.

A backup can only be restored to the same Anten version (the same database schema). If Anten is behind a proxy, the proxy’s request size limit must be larger than the backup file.

Back up from the command line

Lasting data lives in two places: PostgreSQL (users, rooms, messages) and the uploads volume (sent files, profile pictures). They depend on each other, so back up both at the same time.

  1. Back up the database to anten.dump in the current folder.

    docker compose exec postgres pg_dump -U anten -d anten -Fc -f /tmp/anten.dump
    docker compose cp postgres:/tmp/anten.dump ./anten.dump
    docker compose exec postgres rm /tmp/anten.dump
    
  2. Back up the files to anten-dosyalar.tgz in the current folder.

    docker run --rm -v anten_uploads:/data -v "${PWD}:/yedek" postgres:18.6-alpine tar czf /yedek/anten-dosyalar.tgz -C /data .
    

Keep this backup somewhere safe: it holds users, rooms, and the messages the server keeps in readable form. The secret half of the identity keys is not in it; that stays only on people’s devices.

Restore a command-line backup to an empty installation, before antend has ever started:

  1. Start only the database.

    docker compose up -d postgres
    
  2. Restore the database backup.

    docker compose cp ./anten.dump postgres:/tmp/anten.dump
    docker compose exec postgres pg_restore -U anten -d anten --no-owner /tmp/anten.dump
    docker compose exec postgres rm /tmp/anten.dump
    
  3. Restore the files.

    docker run --rm -v anten_uploads:/data -v "${PWD}:/yedek" postgres:18.6-alpine tar xzf /yedek/anten-dosyalar.tgz -C /data
    
  4. Start Anten.

    docker compose up -d
    

Move to another server

  1. Ask people to back up their identities.

    Each person uses Privacy and security → Back up the identity in their own settings. The identity key is kept in the browser, tied to the server’s address; at a new address the browser does not know it.

  2. On the old server, make a backup from the app.

  3. Set up the new server with the same Anten version and become an administrator with its first privilege key.

  4. Restore the backup on the new server.

    The administrators in the backup come back. If the identity you used on the new installation is not in the backup, it connects as an ordinary member.

  5. Ask people to choose their file with Load an identity from a backup on the connect screen at the new address.

    They then connect with their old identity and groups. Someone who did not back up their identity counts as a new user and cannot use their old nickname.

Update

  1. Get the new version’s files.

  2. Make a backup.

  3. Build and start the new version.

    docker compose up -d --build
    

    Only the containers that changed restart. Database updates apply by themselves on start; connected people reconnect by themselves within a few seconds.

The desktop app

The desktop app gets its updates from the server it connects to; the server needs nothing extra for this. The app looks for a new version when it starts and every six hours.

  1. Open Server settings → Desktop updates.

  2. Press Upload a new version and choose the installer together with its latest.json file.

The app installs only an update signed with the publisher’s key and newer than itself. Even if the server is taken over, it cannot make people install a fake version.

Fix problems

Most problems show in the logs of antend or Caddy. To follow antend’s logs live:

docker compose logs -f antend

Press Ctrl+C to stop following.

Voice stays at “Connecting…”

  1. Check that port 50000 is open for UDP and TCP in the firewall.

    If it is closed, chat works but nobody can join voice. Do not forget the firewall in your provider’s panel.

  2. Look at the address clients are told to use for voice.

    sudo docker compose logs antend | grep rtc
    

    The rtc_hosts value in the start line should show the server’s public address.

  3. If it does not, uncomment the RTC_HOSTS line in .env and put the server’s public IP address there.

    RTC_HOSTS=192.0.2.10
    
  4. Restart Anten with the new setting.

    sudo docker compose up -d
    

On networks that block UDP, the browser connects over TCP on the same port; the delay grows a little, but voice works. Some browsers’ privacy settings restrict WebRTC (the connection browsers use for voice and video); if voice still does not connect, set the browser’s WebRTC setting back to its default.

The certificate is not issued

Caddy’s logs say why:

sudo docker compose logs caddy

Most often the DNS record has not spread yet, or port 80 or 443 is closed.

Large files cannot be sent

A request size limit on a proxy in front of Anten cuts files off before they reach antend; the client then shows a warning. Set the limit a little larger than Largest file in the server settings (client_max_body_size in nginx). Caddy sets no such limit. If your domain goes through a content delivery network, it may have a limit too.

Reference

Commands

All run in the deploy folder.

Command What it does
docker compose up -d Starts Anten in the background
docker compose up -d --build Builds from new files and starts
docker compose stop Stops; the data stays in place
docker compose ps Shows the containers’ state
docker compose logs -f antend Shows antend’s logs live
docker compose exec antend /antend privilege-key Makes a new privilege key for the administrator group

The containers run with restart: unless-stopped: unless you stopped them by hand, Anten starts whenever Docker does. docker compose down removes the containers but keeps the data.

Settings

The settings in .env:

Setting Default Meaning
POSTGRES_PASSWORD (required) The database password; Anten does not start without it
ANTEN_SERVER_NAME Anten Sunucusu The name of the server made on first start; change it later in the server settings
ANTEN_LANGUAGE tr tr or en: the language of the groups and rooms made on first start and of the server’s own notices
ANTEN_DOMAIN The server’s domain name on an internet-facing installation
COMPOSE_FILE The additions to use; saves adding -f to every command
ANTEN_BIND 127.0.0.1 The address antend is published at; by default only this computer reaches it
ANTEN_HTTP_PORT 8080 The web port of a local installation
ANTEN_COOKIE_SECURE false Sends the session cookie over HTTPS only; the HTTPS additions turn it on themselves
RTC_HOSTS The address clients reach the voice port at; left empty on an internet-facing installation (the domain is used)
RTC_BIND The address the voice port is published at; usually left empty
ANTEN_TRUSTED_PROXIES private if a proxy of your own runs in front of Anten on the same machine
ANTEN_GIF_PROVIDER, ANTEN_GIF_KEY Optional GIF search: tenor or giphy and that service’s API key; off without a key

With GIF search on, searches and GIFs go through the server: the service sees the server’s address, not the users’. If Link previews is turned on in the server settings, the server itself reads the page of the first link in messages that are not encrypted. People’s browsers never connect to an outside service.

Ports

Port What for When
80/TCP Getting the certificate and redirecting to HTTPS With the HTTPS addition
443/TCP and UDP The web interface (HTTPS) With the HTTPS addition
50000/UDP and TCP Voice and video Always
8080/TCP The web interface (HTTP) Local installations only
127.0.0.1:8088/TCP Where your web server reaches Anten With docker-compose.nginx.yml
22/TCP Connecting to the server over SSH On a server