---
title: "Deploy AdventureLog | (Just Updated) Self-Hosted Travel Tracker & Trip Planner, Ready to Use"
description: "AdventureLog self-hosted travel tracker and trip planner, REST API"
category: "Other"
url: https://railway.com/deploy/adventurelog-or-just-updated-self-hosted
---

# Deploy AdventureLog | (Just Updated) Self-Hosted Travel Tracker & Trip Planner, Ready to Use

AdventureLog self-hosted travel tracker and trip planner, REST API

**[Deploy AdventureLog | (Just Updated) Self-Hosted Travel Tracker & Trip Planner, Ready to Use on Railway](https://railway.com/template/adventurelog-or-just-updated-self-hosted)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/adventurelog-or-just-updated-self-hosted/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Other

## Template content

### app

- **Image:** ghcr.io/seanmorley15/adventurelog:v0.13.1@sha256:67ff66e4a2b46b3ca4806a3ecb47cb71c42443ea2d88c18e1ea3dba3ae0d2cf5
- **Start command:** `/bin/sh -c 'sed -i "s#proxy_pass http://frontend;#proxy_pass http://frontend; proxy_cookie_domain .railway.app $RAILWAY_PUBLIC_DOMAIN;#" /etc/nginx/nginx.conf && exec /aio/entrypoint.sh supervisord -c /aio/supervisord.conf'`
- **Public domain:** Yes

### db

- **Image:** postgis/postgis:16-3.5@sha256:94146ac37bc61e2322f88016056c5920729cb8c64c8542ed590af8fc2abdac07

## Documentation

# Deploy and Host AdventureLog on Railway

**Built for an LLM agent to deploy and use.** The deploy form has no fields to fill: the database credentials, the Django secret key and the admin password are all generated, and the admin account is created on first boot, so nobody opens a setup page first. AdventureLog is a self-hosted travel tracker and trip planner: log visited places on a world map, plan itineraries into collections, attach photos and notes, and share trips.

## About Hosting AdventureLog

This template runs two services from the stock upstream images, pinned by digest: **app** (the AdventureLog all-in-one image: nginx, the SvelteKit web app, the Django REST API and a cache, the only public service) and **db** (PostGIS on a volume at `/var/lib/postgresql`). Uploaded photos and attachments live on a second volume at `/code/media`. On first boot the app runs the migrations, creates the `admin` user from `DJANGO_ADMIN_PASSWORD` and loads the country and region data; that takes a few minutes, so the service has no healthcheck and the public URL answers once the load has finished.

**Browser login works on the generated `up.railway.app` domain.** Upstream sets the session cookie for `.railway.app`, which browsers reject on a Railway subdomain, so a stock deploy bounces you back to the login page. The `app` start command rewrites that cookie domain to your deploy's own host and then hands over to the upstream entrypoint unchanged.

**What persists.** Users, trips, places and API keys live on the `db` volume, photos on the `app` volume. The secret key and the admin password are stable variables, so redeploys keep sessions and stored data valid. Change the admin password in the app after the first login if you want your own.

### Agent contract

- Public URL: `https://RAILWAY_PUBLIC_DOMAIN` (the generated domain of the `app` service)
- Private URL: `http://app.railway.internal:80`
- Credentials: user `admin` (an image default, not a template variable) and the password in the `DJANGO_ADMIN_PASSWORD` variable of the `app` service
- Auth: `POST /auth/app/v1/auth/login` returns a `session_token`; send it as the `sessionid` cookie to `POST /auth/api-keys`, which returns an API key; send that key as an `X-API-Key` header on `/api/` calls. A write without a valid key answers `401`; browser-style `DELETE` calls also need an `Origin` header equal to the public URL
- Health: `GET /health` returns 200

```bash
# needs: SITE_URL (public https URL of the app service), DJANGO_ADMIN_PASSWORD (from the app service); also curl, sed
curl -s -o /dev/null -w "health: %{http_code}\n" "$SITE_URL/health"
T=$(curl -s -X POST "$SITE_URL/auth/app/v1/auth/login" -H 'content-type: application/json' -d "{\"username\":\"admin\",\"password\":\"$DJANGO_ADMIN_PASSWORD\"}" | sed -n 's/.*"session_token": *"\([^"]*\)".*/\1/p')
echo "log in: session token of ${#T} characters"
KEY=$(curl -sL -X POST "$SITE_URL/auth/api-keys" -H "Cookie: sessionid=$T" -H "Origin: $SITE_URL" -H 'content-type: application/json' -d '{"name":"agent"}')
K=$(echo "$KEY" | sed -n 's/.*"key":"\([^"]*\)".*/\1/p'); KID=$(echo "$KEY" | sed -n 's/^{"id":"\([^"]*\)".*/\1/p')
echo "api key: ${K%${K#al_??????}}..."
curl -sL -o /dev/null -w "write without key: %{http_code}\n" -X POST "$SITE_URL/api/collections" -H 'content-type: application/json' -d '{"name":"agent trip"}'
curl -sL -o /dev/null -w "write wrong key: %{http_code}\n" -X POST "$SITE_URL/api/collections" -H 'X-API-Key: al_wrong' -H 'content-type: application/json' -d '{"name":"agent trip"}'
CID=$(curl -sL -X POST "$SITE_URL/api/collections" -H "X-API-Key: $K" -H 'content-type: application/json' -d '{"name":"agent trip"}' | sed -n 's/^{"id":"\([^"]*\)".*/\1/p')
echo "collection created: $CID"
curl -sL -H "X-API-Key: $K" "$SITE_URL/api/collections/$CID" | sed -n 's/.*"name":"\([^"]*\)".*/collection name: \1/p'; echo
curl -sL -o /dev/null -w "collection delete: %{http_code}\n" -X DELETE -H "X-API-Key: $K" -H "Origin: $SITE_URL" "$SITE_URL/api/collections/$CID"
curl -sL -o /dev/null -w "api key delete: %{http_code}\n" -X DELETE -H "Cookie: sessionid=$T" -H "Origin: $SITE_URL" "$SITE_URL/auth/api-keys/$KID"
```

A fresh deploy prints `health: 200`, `log in: session token of 32 characters`, an `al_` API key prefix, `write without key: 401`, `write wrong key: 401`, a created collection id, `collection name: agent trip`, `collection delete: 204` and `api key delete: 204`.

## Why Deploy AdventureLog on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying AdventureLog on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - no deployer fields, a contract block and one script that logs in, mints an API key, creates and deletes a collection and shows the refusal without a key.
- **Browser login that works** - the session-cookie domain defect of the stock image on `up.railway.app` is fixed in the start command.
- **Data survives redeploys** - the database and the uploaded media each sit on a volume, and the secrets are stable.
- **Pinned** - both images are pinned by digest.
- **Your travels stay yours** - places, photos and itineraries stay on your own service, with no third-party travel account.
- **The database stays private** - it has no public domain.

## Common Use Cases

- **Self-hosted travel log** - keep every country, region and place you have visited on one map.
- **Trip planning** - build itineraries, lodging and notes into shareable collections.
- **Family or group trips** - share a collection with the people travelling with you.
- **Agent-driven trip logging** - an agent creates collections and locations through the REST API with an API key.

## Dependencies for AdventureLog Hosting

- Nothing outside the template: the app and the database are the two services. A custom domain is optional.

### Deployment Dependencies

- [AdventureLog repository](https://github.com/seanmorley15/AdventureLog)
- [AdventureLog documentation](https://adventurelog.app)
- [App image](https://github.com/seanmorley15/AdventureLog/pkgs/container/adventurelog)
- [PostGIS image](https://hub.docker.com/r/postgis/postgis)


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/adventurelog-or-just-updated-self-hosted
