Traccar GPS Tracking 6.16.0 on AWS User Guide
Overview
This guide covers launching and using the Traccar GPS Tracking 6.16.0 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened EHRbase & GIS, Health and Research Platforms AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Traccar is the reference open source GPS tracking and fleet telematics server. It receives position reports from vehicle trackers, asset tags and phones, stores them with a full history, and presents live maps, trip replay, geofences, scheduled and on demand reports, event notifications, and driver and maintenance records through a web application and a complete REST API. It understands more than two hundred tracker protocols.
The cloudimg image adds:
- HTTPS from the first boot. nginx serves Traccar on port 443 with a certificate generated on your instance's first boot (never baked into the image). Port 80 redirects to HTTPS.
- No default login and no open enrolment. A fresh Traccar makes the first account anyone creates an administrator. On this image the web door stays shut until first boot has created your administrator with a random password, closed self-registration and proved it closed.
- Its own database, created on your instance. PostgreSQL 16 is installed but no database ships in the image. First boot creates this instance's cluster, listening on its local socket only, and Traccar signs in to it by operating system identity (peer authentication), so there is no database password anywhere.
- No device port open by default. Traccar listens for trackers only on the protocols you enable with one command (Step 8), so the only open ports are 22, 80 and 443 until you choose otherwise.
- Traccar on loopback only, as an unprivileged user. The application listens on
127.0.0.1:8082, runs as thetraccarsystem user in a systemd sandbox, and is reached only through nginx. - Fixed host and real client addresses. Requests for a host name the instance does not serve are dropped, links Traccar generates use your configured host name, cross site requests and WebSocket connections from other web origins are refused, and Traccar records the real client address rather than forged forwarding headers.
- Metadata service blocked. Traccar, nginx and PostgreSQL cannot reach the instance metadata service, so a forwarding URL, webhook or map source can never reach it, and the AMI requires IMDSv2.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on (they cover OpenJDK 21, PostgreSQL and nginx).

What is on the image: Traccar 6.16.0 (/opt/traccar), OpenJDK 21, PostgreSQL 16 (cluster created at first boot), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH) from your management network and TCP 443 (the web interface) and TCP 80 (redirects to HTTPS) from the networks your users work from. Open a device protocol port only after you enable that protocol (Step 8), and only to the addresses your trackers report from. Never open port 8082.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Traccar GPS Tracking 6.16.0 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above. m5.large handles a small to medium fleet; choose a larger instance, and a larger root volume, for hundreds of devices reporting at short intervals.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=traccar}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| Traccar GPS Tracking 6.16.0 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
First boot takes about a minute: it creates the database, generates the certificate and the administrator password, and only then lets nginx start. Then every unit is active:
systemctl is-active postgresql@16-main traccar nginx traccar-firstboot
active
active
active
active
Traccar runs on Ubuntu's own OpenJDK package, so unattended-upgrades keeps the JVM patched with the rest of the system:
java -version 2>&1 | head -2
openjdk version "21.0.12.1" 2026-08-18
OpenJDK Runtime Environment (build 21.0.12.1+1-1-24.04.4-Ubuntu)
Step 4: Check what the network can reach
sudo /usr/local/sbin/traccar-port-check.sh
off-box TCP exactly [22 80 443]; Traccar web on loopback 8082; PostgreSQL socket-only
TRACCAR_PORTS_OK
That is the complete network surface of a new instance: SSH, the HTTPS front door and the HTTP redirect. Traccar's own web server listens on loopback and PostgreSQL has no TCP listener at all. No device protocol is listening yet:
sudo traccar-protocols list
no device protocol is enabled (the default)
Step 5: Read your login
First boot writes this instance's URL, the administrator login and its password to a root only file:
sudo cat /root/traccar-credentials.txt
# Traccar GPS Tracking 6.16.0 on Ubuntu 24.04 (cloudimg)
# Generated on this instance's first boot. These credentials are unique to THIS instance.
TRACCAR_URL=https://<public-dns-name>/
TRACCAR_ADMIN_USER=admin
TRACCAR_ADMIN_PASSWORD=<TRACCAR_ADMIN_PASSWORD>
...
None of these values exists in the image: the password, the certificate and the database are all created on your instance's first boot.
Step 6: Sign in
Open the TRACCAR_URL from Step 5 in a browser. The certificate is self signed and unique to your instance, so the browser warns on the first visit; Step 10 shows how to use your own DNS name and certificate. Sign in as admin with the password from Step 5. A new instance has no devices, so the map is empty until you add one.

The same checks from the command line. Self-registration is closed:
curl -sk https://127.0.0.1/api/server \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps({k: d[k] for k in ("registration","readonly","deviceReadonly")}, indent=2))'
{
"registration": false,
"readonly": false,
"deviceReadonly": false
}
And a real sign in through the front door. The password is read from your credentials file and passed to curl on its standard input, so it never appears on a command line:
sudo sed -n 's/^TRACCAR_ADMIN_PASSWORD=//p' /root/traccar-credentials.txt | tr -d '\n' \
| curl -sk -c /tmp/traccar.jar -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "email=admin" --data-urlencode "password@-" https://127.0.0.1/api/session \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps({k: d[k] for k in ("name","login","email","administrator")}, indent=2))'
{
"name": "Administrator",
"login": "admin",
"email": "admin@localhost",
"administrator": true
}
Step 7: Add your first tracker
Every tracker identifies itself by a unique identifier, usually its IMEI (printed on the device or returned by an SMS status command). Register the identifier first: Traccar refuses positions from identifiers it does not know, so an unregistered device cannot inject data into your fleet.
In the web interface choose Settings, Devices, then +, give the device a name and enter its identifier. Or use the API with the session from Step 6:
curl -sk -b /tmp/traccar.jar -X POST -H 'Content-Type: application/json' \
--data '{"name":"My first tracker","uniqueId":"123456789012345"}' https://127.0.0.1/api/devices \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps({k: d[k] for k in ("id","name","uniqueId","status")}, indent=2))'
{
"id": 1,
"name": "My first tracker",
"uniqueId": "123456789012345",
"status": "offline"
}

Step 8: Enable the protocol your trackers speak
Traccar supports more than two hundred device protocols, each on its own port. This image enables none by default, because every protocol listener is unauthenticated by design (the device identifier is the only credential). Enable exactly the ones your hardware uses. Traccar's device list gives the protocol name and the conventional port for every supported tracker; common ones are osmand on 5055 (the official Traccar Client app for Android and iOS), teltonika on 5027 and gt06 on 5023.
sudo traccar-protocols enable osmand 5055
traccar-protocols: osmand enabled on port 5055.
Now open 5055 (TCP, and UDP if your trackers use it) in the instance's security group to your trackers' addresses.
The command checks the name against the protocols this Traccar build implements, writes the configuration and restarts Traccar (which signs out any open web and API sessions). Send a test position for the device from Step 7 from the instance itself (this is the request the Traccar Client app makes):
curl -s -o /dev/null -w '%{http_code}\n' "http://127.0.0.1:5055/?id=123456789012345&lat=51.5074&lon=-0.1278&speed=12×tamp=$(date -u +%s)"
200
The network check now includes the new port, and nothing else:
sudo /usr/local/sbin/traccar-port-check.sh
off-box TCP exactly [22 80 443 5055]; Traccar web on loopback 8082; PostgreSQL socket-only
TRACCAR_PORTS_OK
Then open the port in the instance's security group, ideally only to the address ranges your trackers or your mobile operator's APN report from:
aws ec2 authorize-security-group-ingress --group-id <your-security-group> \
--ip-permissions 'IpProtocol=tcp,FromPort=5055,ToPort=5055,IpRanges=[{CidrIp=<tracker-cidr>}]'
In the Traccar Client app set the server URL to http://<public-dns-name>:5055 and the device identifier to the value you registered; positions start arriving within a minute and the device turns Online on the map. Select a device to see its status card: fix time, position, speed and total distance.

To turn a protocol off again, run sudo traccar-protocols disable <name> and remove its security group rule.
Step 9: Reports and the API
Choose Reports in the navigation. Positions lists every stored fix; Trips and Stops group them into journeys and dwell time; Summary and Chart aggregate distance, engine hours and speed. Pick a device and a period, then select Show.

The same data through the API. Enabling a protocol in Step 8 restarted Traccar, which signs every session out, so sign in again first:
sudo sed -n 's/^TRACCAR_ADMIN_PASSWORD=//p' /root/traccar-credentials.txt | tr -d '\n' \
| curl -sk -o /dev/null -w '%{http_code}\n' -c /tmp/traccar.jar -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "email=admin" --data-urlencode "password@-" https://127.0.0.1/api/session
200
curl -sk -b /tmp/traccar.jar "https://127.0.0.1/api/positions" \
| python3 -c 'import json,sys; print(json.dumps([{k: p[k] for k in ("deviceId","latitude","longitude","speed")} for p in json.load(sys.stdin)][:1], indent=2))'
[
{
"deviceId": 1,
"latitude": 51.5074,
"longitude": -0.1278,
"speed": 12.0
}
]
The full API reference is at traccar.org/api-reference. When you have finished, remove the cookie jar with rm -f /tmp/traccar.jar.
Step 10: Your own DNS name and certificate
Point a DNS name at the instance (an Elastic IP keeps the address stable), then tell the instance its name. This regenerates the self signed certificate for the name, pins nginx and the cross origin guard to it, and sets the address Traccar uses in notification and report links:
sudo traccar-set-hostname <your-domain>
To use a certificate from a public authority, issue it for the same name (for example with certbot and a DNS challenge) and install it where nginx expects it, then reload nginx:
sudo install -o root -g root -m 0600 /etc/letsencrypt/live/<your-domain>/privkey.pem /etc/ssl/traccar/traccar.key
sudo install -o root -g root -m 0644 /etc/letsencrypt/live/<your-domain>/fullchain.pem /etc/ssl/traccar/traccar.crt
sudo nginx -t && sudo systemctl reload nginx
Running traccar-set-hostname again replaces the certificate with a self signed one, so repeat the two install commands after it, and in your certificate renewal hook.
Step 11: Add more users
Self-registration is disabled: nobody who finds your instance can enrol themselves. Add users from Settings, Users, +, or through the API as the administrator:
curl -sk -b /tmp/traccar.jar -X POST -H 'Content-Type: application/json' \
--data '{"name":"Dispatcher","email":"dispatch@example.com","password":"<new-password>"}' \
https://127.0.0.1/api/users
Grant each user access to specific devices from Settings, Users, then Show next to the user. Leave Admin off for everyday accounts. If you deliberately want open enrolment, turn it on in Settings, Server, Registration; do not do this on an instance reachable from the internet unless you intend anyone to be able to create an account.
Step 12: Security checks
The image carries the checks it was built with. The administrator password works through the front door, while admin/admin, blank and common passwords are refused by Traccar, self-registration is closed and the session cookie is Secure, HttpOnly and SameSite:
sudo /usr/local/sbin/traccar-verify-login.sh
per-instance credential authenticates as administrator (200); admin/admin and weak passwords refused (401), blank refused (400)
self-registration closed (anonymous POST /api/users -> 400); cookie Secure+HttpOnly+SameSite
TRACCAR_LOGIN_OK
A caller cannot forge the address Traccar records for a sign in (the check compares a request through nginx with one sent straight to Traccar):
sudo /usr/local/sbin/traccar-xff-check.sh
through nginx Traccar recorded [127.0.0.1], not the forged [203.0.113.77]; the direct control recorded [203.0.113.77]
TRACCAR_XFF_OK
Traccar, nginx and PostgreSQL are denied the instance metadata service at the kernel level:
systemctl show -p IPAddressDeny traccar nginx postgresql@16-main
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
Step 13: Back up your data
Everything Traccar stores (devices, users, positions, geofences, reports) is in the traccar PostgreSQL database; uploaded media is in /opt/traccar/media. Dump the database as the postgres operating system user (peer authentication, no password):
sudo -u postgres pg_dump -Fc traccar > <backup-dir>/traccar-$(date +%F).dump
sudo tar czf <backup-dir>/traccar-media-$(date +%F).tar.gz /opt/traccar/media /etc/traccar-cloudimg
To restore onto a new instance, stop traccar.service, restore with sudo -u postgres pg_restore --clean --if-exists -d traccar <dump>, put the media back and start the service. Keep the dumps off the instance, for example in Amazon S3, or snapshot the EBS volume.
Step 14: Versions, build provenance and licence
cat /usr/share/doc/traccar-cloudimg/BUILD-PROVENANCE.txt
Traccar 6.16.0 - https://github.com/traccar/traccar/releases/tag/v6.16.0
Archive: traccar-other-6.16.0.zip sha256 87be9347090248747cf31ff00a554d59c28e50d1d41d1f68f7f16957976bde55
Licence: Apache-2.0 (LICENSE.txt at v6.16.0, byte-identical to v6.15.3)
Removed from lib/: h2, mysql-connector-j, mssql-jdbc, mariadb-java-client (unused JDBC drivers)
Runtime: openjdk-21-jre-headless (Ubuntu noble main); datastore PostgreSQL 16 (Ubuntu noble main),
cluster created on each instance's first boot (socket only, peer authentication, no password).
Server components
| Component | Version | Notes |
|---|---|---|
| Traccar | 6.16.0 | /opt/traccar, traccar.service, user traccar, 127.0.0.1:8082 |
| OpenJDK | 21 | Ubuntu openjdk-21-jre-headless |
| PostgreSQL | 16 | cluster 16/main, UNIX socket only, peer authentication |
| nginx | 1.24 | ports 80 (redirect) and 443 (TLS 1.2 and 1.3) |
Filesystem layout
| Path | Purpose |
|---|---|
/opt/traccar/conf/traccar.xml |
Traccar configuration (generated; use the helpers below to change it) |
/etc/traccar-cloudimg/protocols |
Enabled device protocols (traccar-protocols) |
/root/traccar-credentials.txt |
This instance's URL and administrator login (root only) |
/etc/ssl/traccar/ |
This instance's certificate and key |
/var/lib/postgresql/16/main |
The database (created at first boot) |
/opt/traccar/media, /opt/traccar/logs |
Uploaded media and Traccar's log |
Managing the services
sudo systemctl restart traccar # after changing anything in Traccar's settings files
sudo journalctl -u traccar -n 100 --no-pager
sudo tail -n 50 /opt/traccar/logs/tracker-server.log
sudo traccar-protocols list | enable <name> <port> | disable <name>
sudo traccar-set-hostname <dns-name>
Security recommendations
- Keep port 8082 closed; nginx on 443 is the only web door. Restrict port 22 to your management network.
- Open a device protocol port only to the addresses your trackers report from, and register device identifiers deliberately: anyone who can reach an enabled protocol port can send positions for a registered identifier.
- Event forwarding, webhooks and notification channels send data to the URLs you configure; the metadata service stays blocked for Traccar whatever URL is set.
- Unattended upgrades apply Ubuntu security updates for OpenJDK, PostgreSQL and nginx; reboot when
/var/run/reboot-requiredappears. To upgrade Traccar itself, back up first (Step 13), replace/opt/traccarwith a newer release while keepingconf/traccar.xml, and restart the service; Traccar migrates its own schema on start.
Troubleshooting
The web interface does not load. systemctl is-active traccar nginx should print active twice. Both wait for first boot: journalctl -u traccar-firstboot --no-pager shows what it did. If traccar is not active, read journalctl -u traccar -n 100 --no-pager.
A tracker does not appear. Check the protocol is enabled (sudo traccar-protocols list) and its port is open in the security group. In /opt/traccar/logs/tracker-server.log, Unknown device means the identifier is not registered (Step 7); no line at all means the tracker is not reaching the port.
The browser shows a certificate warning. The certificate is self signed and unique to your instance. Accept it for testing, or install your own name and certificate (Step 10).
The live map does not update when opened through another address. Traccar is served only under the names it knows (your configured name, the instance's own IP addresses). Use TRACCAR_URL from the credentials file, or set your own name with traccar-set-hostname.
Support and licensing
Traccar is open source software distributed under the Apache License 2.0; the image runs the unmodified upstream 6.16.0 release with the unused database drivers removed. cloudimg provides 24/7 technical support for this image by email and live chat: support@cloudimg.co.uk, with a 24 hour response SLA.
Traccar is a trademark of its respective owner. All product names are trademarks of their respective owners. cloudimg is not affiliated with or endorsed by Traccar Ltd or the OpenStreetMap Foundation.