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 versionshould 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.
-
Copy the settings template.
cd deploy cp .env.example .env -
Generate a random password for the database.
openssl rand -hex 32 -
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
-
Start Anten.
docker compose up -d --buildThe first build takes a few minutes.
-
Check the containers.
docker compose psBoth containers should be
Up;antendshowshealthyshortly after. -
Open
http://localhost:8080in your browser and connect with a nickname. -
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.
-
Set these two lines in
.env(removing the#at the start of theRTC_HOSTSline).ANTEN_BIND=0.0.0.0 RTC_HOSTS=192.168.1.20 -
Restart Anten with the new settings.
docker compose up -d -
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.
-
Point your domain’s DNS record to the server’s IP address.
Wait for the record to spread before you go on.
-
Set these two lines in
.env(removing the#at their start).ANTEN_DOMAIN=anten.example.org COMPOSE_FILE=docker-compose.yml:docker-compose.server.ymlWith
COMPOSE_FILEyou need not name the addition in every command. LeaveANTEN_COOKIE_SECURE,ANTEN_BINDandRTC_HOSTSalone: the addition sets them and tells clients to reach voice at your domain. -
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 enableThe example is for
ufw. Docker opens the ports it publishes ahead of theufwrules; 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. -
Start Anten.
sudo docker compose up -d --build -
Open
https://anten.example.organd 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.
-
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.
-
Set these two lines in
.env.ANTEN_DOMAIN=anten.example.org COMPOSE_FILE=docker-compose.yml:docker-compose.nginx.yml -
Create a site for the domain on your web server and get its certificate.
-
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
UpgradeandConnectionheaders and the long timeouts.client_max_body_sizeshould be a little larger than Largest file in the server settings and than your backup files (nginx’s default limit is 1 MB). -
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.
-
Find the privilege key in the logs.
docker compose logs antend -
Connect to Anten with a nickname.
-
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;
0means 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.
-
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).
-
Press Download the backup.
The whole server (rooms, groups and permissions, members, bans, messages, sent files, profile pictures) is written to a single
.antenfile. Sessions are not included. People can keep using the server meanwhile. -
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.
-
Back up the database to
anten.dumpin 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 -
Back up the files to
anten-dosyalar.tgzin 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:
-
Start only the database.
docker compose up -d postgres -
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 -
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 -
Start Anten.
docker compose up -d
Move to another server
-
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.
-
On the old server, make a backup from the app.
-
Set up the new server with the same Anten version and become an administrator with its first privilege key.
-
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.
-
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
-
Get the new version’s files.
-
Build and start the new version.
docker compose up -d --buildOnly 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.
-
Open Server settings → Desktop updates.
-
Press Upload a new version and choose the installer together with its
latest.jsonfile.
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…”
-
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.
-
Look at the address clients are told to use for voice.
sudo docker compose logs antend | grep rtcThe
rtc_hostsvalue in the start line should show the server’s public address. -
If it does not, uncomment the
RTC_HOSTSline in.envand put the server’s public IP address there.RTC_HOSTS=192.0.2.10 -
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 |