Manual Installation
Build and run AirTrail from source without Docker.
This guide is for people comfortable running a Node.js service and PostgreSQL themselves. Docker Compose is easier to install and update.
Requirements
- Git
- Node.js 22 (runs the server)
- Bun (installs dependencies and builds the app)
- PostgreSQL 16, with an empty database and a user that owns it
Install
Get the source
Clone the repository and check out the latest release, so you run a tested version rather than the development branch:
git clone https://github.com/JohanOhly/AirTrail.git
cd AirTrail
git checkout "$(git describe --tags --abbrev=0)"Install dependencies
bun installConfigure
cp .env.example .envIn .env:
- Set
ORIGINto the exact URL you will open AirTrail at. - Set
DB_URLto your database, for examplepostgres://airtrail:secret@localhost:5432/airtrail. - Set
UPLOAD_LOCATIONto an absolute path the service user can write to, such as/var/lib/airtrail/uploads. - The
DB_PASSWORD,DB_DATABASE_NAMEandDB_USERNAMEvariables only configure the Docker database container and can be removed.
See Environment variables for everything else.
Add the airport map layer (optional)
The detailed airport layer on the map (runways, taxiways and terminals) comes from a 200 MB data file that is not in the repository. Without it, AirTrail works normally but shows no airport detail on the map. If Docker is available on any machine, copy the file out of its image and place it in static/ before building:
id=$(docker create johly/airtrail-airport-overlay:latest noop)
docker cp "$id":/airport-overlay.pmtiles static/airport-overlay.pmtiles
docker rm "$id"Build and migrate
bun run build
bun run db:migrate-deployStart the server
node does not read .env by itself, so pass it explicitly:
node --env-file=.env buildAirTrail listens on port 3000. Open the URL from ORIGIN and follow the post-installation steps.
Run it as a service
To start AirTrail on boot and restart it if it stops, use a systemd unit. Adjust the user and paths:
[Unit]
Description=AirTrail
After=network.target postgresql.service
[Service]
User=airtrail
WorkingDirectory=/opt/airtrail
ExecStart=/usr/bin/node --env-file=/opt/airtrail/.env build
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now airtrailBehind a reverse proxy
Follow the reverse proxy guide. With ORIGIN set you do not need PROTOCOL_HEADER or HOST_HEADER; set ADDRESS_HEADER=X-Forwarded-For so rate limits see the real client address.
Updating
Last updated on
