Applications Azure

AdventureLog on Ubuntu 24.04 on Azure User Guide

| Product: AdventureLog on Ubuntu 24.04 LTS on Azure

Overview

AdventureLog is a self-hosted travel companion. It lets you log the countries and regions you have visited, plan future trips, pin your adventures on an interactive world map and keep your travel photos in one private place. The cloudimg image installs the official AdventureLog self-host Docker Compose stack, pinned to v0.12.1: a SvelteKit frontend (the web UI), a Django/GeoDjango + Gunicorn backend (the REST API, media and Django admin) and a PostgreSQL 16 database with the PostGIS extension for the geospatial features. Every secret - the PostgreSQL password, the Django SECRET_KEY and the admin password - is generated uniquely on the first boot of every VM, and a fresh admin account is seeded on a clean database. Backed by 24/7 cloudimg support.

What is included:

  • The official AdventureLog v0.12.1 self-host stack running under Docker (the web frontend, the server backend and a PostgreSQL 16 + PostGIS db), pinned so it never silently upgrades
  • The SvelteKit frontend published on port 80 and the backend (REST API, media and Django admin) on port 8016
  • A per-VM admin account generated on first boot - a unique password recorded in a root-only file - so every VM is secured independently
  • The customer-facing URLs (ORIGIN, PUBLIC_URL, CSRF_TRUSTED_ORIGINS) resolved to your VM's reachable address at first boot, so sign-in and CSRF work out of the box
  • The whole stack managed as one adventurelog.service systemd unit, plus docker.service, both enabled
  • PostgreSQL bound to the internal Docker network only - just 22/tcp (SSH), 80/tcp (UI) and 8016/tcp (backend/media/API) are exposed
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size for the three-container stack. NSG inbound: allow 22/tcp from your management network, and 80/tcp and 8016/tcp from the clients that will use AdventureLog. The app serves plain HTTP; for production, put it behind your own domain and TLS.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for AdventureLog by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22), then add 80 and 8016 after deployment. Review + create -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name adventurelog \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name adventurelog --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name adventurelog --port 8016 --priority 1020

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the stack is running

AdventureLog runs as a Docker Compose stack managed by a single systemd unit. On first boot the stack rotates every secret, re-points its URLs at your VM's address, recreates itself on a fresh database and seeds the admin account; the multi-container stack can take a minute or two to become fully healthy after the VM is created.

systemctl is-active adventurelog.service

It reports active. You can list the running containers with:

sudo docker compose -f /var/lib/adventurelog/docker-compose.yml ps

AdventureLog Compose stack running under Docker - frontend, backend and PostgreSQL with PostGIS

The whole stack is managed as one systemd unit - use sudo systemctl status adventurelog and sudo systemctl restart adventurelog to control every container together.

Step 5 - Retrieve your per-VM admin credentials

The admin password is generated uniquely on the first boot of your VM and written to a root-only file. Confirm the file exists (it is 0600, root-only):

sudo ls -l /root/adventurelog-credentials.txt

Then read it to get your credentials:

sudo cat /root/adventurelog-credentials.txt

The file contains adventurelog.url (the address to browse to), adventurelog.admin.username (admin), adventurelog.admin.email and DJANGO_ADMIN_PASSWORD (for the web UI). Store them somewhere safe.

AdventureLog first-boot secret rotation - the credentials file exists as a root-only 0600 file and the first-boot service is active

Step 6 - Confirm the endpoints are healthy

The SvelteKit frontend answers on port 80 and the Django backend answers on port 8016:

curl -s -o /dev/null -w 'frontend -> HTTP %{http_code}\n' http://localhost/

It returns HTTP 200. The backend REST API is reachable on port 8016:

curl -s -o /dev/null -w 'backend  -> HTTP %{http_code}\n' http://localhost:8016/api/

It also returns HTTP 200. You can confirm which ports are published (PostgreSQL is deliberately not among them - it stays on the internal Docker network):

sudo ss -tlnp | grep -E ':80 |:8016 ' | awk '{print $1, $4}'

AdventureLog endpoints healthy - frontend on port 80 and backend on port 8016 both returning HTTP 200

Step 7 - Confirm the pinned release

The images are pinned to AdventureLog v0.12.1 so the appliance never silently upgrades:

sudo docker compose -f /var/lib/adventurelog/docker-compose.yml images

AdventureLog pinned to v0.12.1 - frontend, backend and the PostGIS database images

Step 8 - Sign in to the web UI

Browse to http://<vm-public-ip>/ and sign in with the username admin and the password from Step 5.

AdventureLog sign-in page

After signing in, the dashboard welcomes you and summarises your travels - the number of adventures logged, countries and regions visited, and your most recent entries.

AdventureLog dashboard showing travel statistics and recent adventures

Step 9 - Log adventures and explore the map

Under Locations you see every adventure you have logged, with its category, rating and whether you have visited it or are still planning to.

AdventureLog locations list showing logged adventures with ratings

The Map plots each adventure on an interactive world map and tracks your completion across the places you want to see.

AdventureLog interactive map with visited and planned adventures pinned across the world

Logging your first adventure

AdventureLog groups your travels into collections and pins individual adventures on the map. In the web UI: select Add New Location, give it a name, a place (city and country) and coordinates so it appears on the map, set a rating and mark it visited or planned, and optionally add it to a collection (for example a specific trip). Under World Travel you can mark the countries and regions you have visited to build up your world map. Everything you create is stored in PostgreSQL with PostGIS on your own VM.

If you prefer the REST API, the backend is served on port 8016 and uses session authentication - sign in at /accounts/login/ to obtain a session, then create objects under /api/collections/ and /api/locations/:

# Illustrative - substitute your admin password for <DJANGO_ADMIN_PASSWORD>
BASE=http://<vm-public-ip>:8016
# 1. Get a CSRF cookie, 2. sign in, 3. create a collection with the session cookie
curl -c cj -b cj "$BASE/accounts/login/" -o /dev/null
# ... POST login=admin, password=<DJANGO_ADMIN_PASSWORD>, csrfmiddlewaretoken to /accounts/login/
# ... POST {"name":"European Summer 2026"} to /api/collections/ with the X-CSRFToken header

See the AdventureLog documentation for the full API and feature reference.

Maintenance

  • Admin credentials: the per-VM admin account is in /root/adventurelog-credentials.txt; change the password from your profile settings in the web UI after first sign-in.
  • Custom domain: the URLs are pinned to the VM's address at first boot. If you reach the VM via a DNS name or a different IP, update ORIGIN, FRONTEND_URL, PUBLIC_URL and CSRF_TRUSTED_ORIGINS in /var/lib/adventurelog/.env, then run sudo systemctl restart adventurelog.
  • Data: the PostgreSQL database and your uploaded media live in the postgres_data and adventurelog_media Docker volumes - snapshot the OS disk, or use pg_dump against the db container, for backups.
  • Stack: manage the whole stack with sudo systemctl <status|restart|stop> adventurelog, or per-container with sudo docker compose -f /var/lib/adventurelog/docker-compose.yml <ps|logs|restart>.
  • TLS: AdventureLog serves plain HTTP; front it with your own domain and TLS before production use.
  • Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.