Yamtrack Media Tracker on AWS User Guide
Overview
This guide covers the deployment and configuration of Yamtrack on AWS using cloudimg AWS Marketplace AMIs. Yamtrack is an open source app for keeping one personal library of everything you watch, play and read. Track movies, TV shows, anime, manga, video games and books together, record where you are up to with per item progress and episode tracking, rate what you have finished, and see it all organised by status such as in progress, planning and completed. Rich metadata and artwork are fetched automatically for the things you add, and a Celery background worker keeps that information in sync. You can also add fully custom entries for niche items no catalogue covers.
The cloudimg image ships the free and open source, AGPL-3.0 licensed Yamtrack, run the officially supported way as the upstream all in one container (its supervisord runs nginx in front of gunicorn, a Celery worker and Celery beat) pinned to a fixed release and captured into the AMI, backed by PostgreSQL and Redis, so your instance starts in seconds. Because Yamtrack's upstream application secret is a well known fixed value and open registration is on by default, nothing here ships with a known credential and the instance is not left world open: a unique application secret and database password are generated for each instance on first boot, before the app is reachable, a per instance admin account with a random password is seeded once the app is healthy, and open self sign up is disabled. Backed by 24/7 cloudimg support.
Yamtrack is a trademark of its respective owner. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the Yamtrack project. It ships the free and open source AGPL-3.0 licensed self hosted software, unmodified.
What is included:
- Yamtrack 0.25.3 (the AGPL-3.0 licensed all in one container: nginx plus gunicorn Django, a Celery worker and Celery beat under supervisord), pinned to a fixed release tag
- PostgreSQL 16 (
postgres:16-alpine) as the application database and Redis 8 (redis:8-alpine) as the Celery broker and cache, both bound to the internal Docker network only - The app published on port
80; PostgreSQL and Redis have no published host ports and are never bound to the public interface - A dedicated gp3 data volume mounted at
/var/lib/docker(the Docker data root) so the container images and database live on their own independently resizable disk yamtrack.serviceandyamtrack-firstboot.serviceas systemd units, enabled and active on boot- A unique application secret, a unique database password and a per instance admin account with a random password generated per instance on first boot, never baked into the image
- No default login, no shipped secret, open self sign up disabled and an empty database on first boot
- A fully patched Ubuntu 24.04 LTS base with unattended security upgrades
- 24/7 cloudimg support with a guaranteed 24 hour response SLA
Connecting to your instance
Connect over SSH on port 22 as the default login user for the operating system variant you launched:
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh ubuntu@<vm-ip>
Prerequisites
- An AWS account subscribed to the Yamtrack listing on AWS Marketplace
- An EC2 key pair in the target region and a VPC subnet
- A security group allowing
22/tcpfrom your management network and80/tcpfor the web app from the networks that use it
Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is a sensible starting point for a personal library. For many concurrent users or large imports use a larger instance.
Step 1: Launch from the AWS Marketplace console
Sign in to the AWS Management Console, open AWS Marketplace, find the Yamtrack listing by cloudimg and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch. Pick your region, instance type (m5.large), VPC subnet, key pair and a security group that allows SSH (22) and HTTP (80), then Launch.
Step 2: Launch from the AWS CLI
AMI_ID="ami-xxxxxxxxxxxxxxxxx" # the Yamtrack AMI id for your region (from the listing)
aws ec2 run-instances \
--image-id "$AMI_ID" \
--instance-type m5.large \
--key-name my-keypair \
--security-group-ids sg-xxxxxxxx \
--subnet-id subnet-xxxxxxxx \
--associate-public-ip-address \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeType":"gp3","VolumeSize":16}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=yamtrack-01}]'
Step 3: Connect to your instance
ssh ubuntu@<vm-ip>
Step 4: Confirm the services are running
Yamtrack runs as one all in one container under yamtrack.service, alongside a PostgreSQL container and a Redis container. The app's bundled nginx is published on host port 80; PostgreSQL and Redis have no published host ports and are reachable only on the internal Docker network. Confirm the services are active and see the containers:
sudo systemctl is-active docker yamtrack-firstboot yamtrack
sudo docker compose -f /var/lib/yamtrack/docker-compose.yml ps
You will see the services report active and the three containers running, with the app container reporting healthy and only 0.0.0.0:80->8000/tcp published. Inside the app container, supervisord runs nginx in front of gunicorn (the Django app), a Celery worker and Celery beat, which handles background metadata sync.
Step 5: Read the per instance credentials
A unique application secret and database password were generated for this instance on the first boot, before the app was reachable, and a per instance admin account with a random password was seeded once the app was healthy and written to a root only file. Read it:
sudo cat /root/yamtrack-credentials.txt
The file (mode 0600 root:root) holds the admin username, email and DJANGO_ADMIN_PASSWORD (the account you sign in to the web app with) and the app url. None of these ship in the image; every value is unique to this instance, so no two instances share a credential and there is no default login to change.
Step 6: Verify the security model
The health endpoint is reachable without authentication, but every application page requires a signed in session, and open self sign up is disabled. Confirm that the health endpoint answers, that the home page redirects an anonymous visitor to the login page, that an unauthenticated attempt to add an item is rejected, and that the per instance admin credential authenticates a real session and reads back the library:
B=http://localhost
curl -s -o /dev/null -w 'health (no auth): %{http_code}\n' $B/health/
curl -s -o /dev/null -w 'home / (no auth): %{http_code}\n' $B/
curl -s -o /dev/null -w 'POST /create (no auth): %{http_code}\n' -X POST $B/create
PASS=$(sudo grep '^DJANGO_ADMIN_PASSWORD=' /root/yamtrack-credentials.txt | cut -d= -f2-)
J=$(mktemp)
curl -s -c $J -b $J -o /dev/null $B/accounts/login/
TOK=$(awk '$6=="csrftoken"{print $7}' $J | tail -1)
curl -s -c $J -b $J -o /dev/null -w 'login (admin creds): %{http_code}\n' \
-H "Referer: $B/accounts/login/" -H "Origin: $B" \
--data-urlencode "login=admin" --data-urlencode "password=$PASS" \
--data-urlencode "csrfmiddlewaretoken=$TOK" $B/accounts/login/
curl -s -c $J -b $J -o /dev/null -w 'GET /admin/movie (session): %{http_code}\n' $B/admin/movie
rm -f $J
The health endpoint returns 200, the home page returns 302 (an anonymous visitor is redirected to the login page), the unauthenticated add is rejected with a non success code, the login with the per instance admin returns 302 (success), and the authenticated library page then returns 200. This is the security model: Django's login required middleware gates every page, there is no open registration, and only the per instance admin can read or write the library.
Step 7: Open the web app and sign in
Browse to http://<vm-ip>/ to reach the Yamtrack web app. Sign in with the username admin and the DJANGO_ADMIN_PASSWORD from Step 5.

Step 8: Add something to your library
Yamtrack fetches rich metadata and artwork for the titles you add. Use the search box at the top to look up a movie, show, game or book, open its detail page, and add it to your library with a status such as Completed, In progress or Planning, a score and your progress. For a niche item no catalogue covers, use Create Custom in the sidebar to add a fully custom entry, which needs no external metadata provider. The screenshot shows a title detail page with its poster, description and the Add to tracker control.

Step 9: Browse your tracked library
Each media type has its own page in the sidebar — Movies, TV Shows, Anime, Manga, Games, Books and more. Open one to see everything you are tracking of that type as cards showing the title, your score and a status indicator, and filter or sort by rating, status or title. This is the heart of Yamtrack: one private, organised library of everything you watch, play and read.

Step 10: See your statistics
The Statistics page summarises your media consumption habits: completed items, average rating, your most active day and current streak, plus an activity history heatmap. It is the at a glance view of everything you have tracked.

Step 11: Enable sign up or add more users
Open self sign up is disabled on this image (REGISTRATION=False), so the instance is not world open and new accounts are not created by anyone who reaches the URL. To let people register their own accounts, edit the environment file, set REGISTRATION=True, and restart the app:
sudo sed -i 's/^REGISTRATION=.*/REGISTRATION=True/' /var/lib/yamtrack/.env
sudo systemctl restart yamtrack.service
Alternatively, keep registration closed and add users yourself from the Django admin at http://<vm-ip>/admin/ (the admin backend is enabled on this image; sign in as admin).
Step 12: Confirm the pinned release
The stack is pinned to a fixed Yamtrack release and fixed PostgreSQL and Redis images, so your instance never silently upgrades. Confirm the image tags:
sudo docker compose -f /var/lib/yamtrack/docker-compose.yml images
Step 13: Add metadata provider API keys (optional)
Yamtrack works out of the box with shared default metadata keys. For heavy use, or to add games and books reliably, add your own provider keys to /var/lib/yamtrack/.env and restart the app. Common ones are TMDB_API (movies and TV), MAL_API (anime and manga), and IGDB_ID + IGDB_SECRET (games):
sudo tee -a /var/lib/yamtrack/.env >/dev/null <<'EOF'
TMDB_API=<your-token>
MAL_API=<your-token>
EOF
sudo systemctl restart yamtrack.service
Custom entries created with Create Custom never need a provider key, so you can always track anything even with no keys set.
Step 14: Server components
| Component | Version / Detail |
|---|---|
| Application | Yamtrack 0.25.3 all in one container (nginx + gunicorn Django + Celery worker + Celery beat under supervisord), pinned |
| Front door | the container's nginx on :8000, published on host :80 |
| Application database | PostgreSQL 16 (postgres:16-alpine), internal Docker network only |
| Cache / task broker | Redis 8 (redis:8-alpine), maxmemory capped at 256mb, internal Docker network only |
| Orchestration | Docker Compose under yamtrack.service, data root on a dedicated gp3 volume at /var/lib/docker |
| Application secret | per instance, generated first boot into /var/lib/yamtrack/.env |
| Admin account | per instance random password, seeded first boot into /root/yamtrack-credentials.txt |
| Registration | open self sign up disabled (REGISTRATION=False) |
| Operating system | Ubuntu 24.04 LTS (patched at build) |
| License | AGPL-3.0 (Yamtrack) |
Step 15: Managing the service
sudo systemctl status yamtrack --no-pager | head -12
sudo docker compose -f /var/lib/yamtrack/docker-compose.yml logs --tail 40 yamtrack
Restart the app with sudo systemctl restart yamtrack.service, follow the logs live with sudo docker compose -f /var/lib/yamtrack/docker-compose.yml logs -f yamtrack, and view configuration in /var/lib/yamtrack/.env. After changing the environment file, restart the service to apply it.
Step 16: Use your own domain and HTTPS (production)
The image serves the web app over plain HTTP on port 80, which is convenient behind a load balancer or private network. For production you should terminate TLS in front of the instance so credentials travel encrypted:
- Front the instance with an Application Load Balancer with an ACM certificate, or a CloudFront distribution, and forward to the app on port
80. - If you serve the app from a custom domain, add that origin to
CSRFin/var/lib/yamtrack/.env(for exampleCSRF=https://<your-domain>) so login and forms work from that address, then restart the app. The app reads its reachable address at first boot, so use a stable Elastic IP or set the address before first boot.
Step 17: Security recommendations
- Restrict the security group. Allow TCP 80 (and 22 for admin) only from the networks that use the app.
- Terminate TLS in front of the app (Step 16) so the admin password and session cookies are encrypted in transit.
- Rotate the seeded admin password. Sign in and change it, or set a new password from the Django admin.
- Keep registration closed. Open self sign up is disabled by default; leave it that way and add members yourself unless you specifically want open registration.
- Keep the datastores private. PostgreSQL and Redis are bound to the internal Docker network only; keep it that way and never publish their ports.
- Keep the OS patched. Unattended security upgrades remain enabled on the running instance.
Step 18: Support and Licensing
Yamtrack is distributed under the GNU Affero General Public License v3.0 (AGPL-3.0). This cloudimg image bundles the unmodified official open source release; cloudimg provides the packaging, the PostgreSQL and Redis backing services, the per instance secret, database password and admin generation, the paired deploy guide, and 24/7 support with a guaranteed 24 hour response SLA. Yamtrack is an independent open source project and this image is not affiliated with or endorsed by it.
Deploy on AWS
Launch Yamtrack from AWS Marketplace and follow this guide to a working personal media tracker for movies, TV, anime, manga, games and books in minutes.