Refactor Docker Compose files and update documentation

- Commented out build configurations in docker-compose files for AIO, dev, and standard setups to simplify deployment.
- Updated the documentation homepage with a new layout, including a hero section, features overview, and installation options.
- Introduced new Vue components for enhanced user experience on the documentation site, including HomeHero, HomeFeatures, and HomeInstall.
- Improved SEO metadata for better visibility and searchability of the documentation.
This commit is contained in:
Sean Morley
2026-06-06 21:42:05 -04:00
parent c4bccd214b
commit 4cd6ab4fd2
34 changed files with 3168 additions and 620 deletions

View File

@@ -1,9 +1,9 @@
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
target: aio
# build:
# context: .
# dockerfile: docker/Dockerfile
# target: aio
image: ghcr.io/seanmorley15/adventurelog-aio:latest
container_name: adventurelog-aio
restart: unless-stopped

View File

@@ -1,7 +1,7 @@
services:
web:
build: ./frontend/
image: ghcr.io/seanmorley15/adventurelog-frontend:latest
# image: ghcr.io/seanmorley15/adventurelog-frontend:latest
container_name: adventurelog-frontend
restart: unless-stopped
user: root
@@ -51,7 +51,7 @@ services:
server:
build: ./backend/
image: ghcr.io/seanmorley15/adventurelog-backend:latest
# image: ghcr.io/seanmorley15/adventurelog-backend:latest
container_name: adventurelog-backend
restart: unless-stopped
env_file: .env

View File

@@ -1,9 +1,9 @@
services:
web:
build:
context: .
dockerfile: docker/Dockerfile
target: frontend
# build:
# context: .
# dockerfile: docker/Dockerfile
# target: frontend
image: ghcr.io/seanmorley15/adventurelog-frontend:latest
container_name: adventurelog-frontend
restart: unless-stopped
@@ -45,11 +45,11 @@ services:
start_period: 10s
server:
build:
context: .
dockerfile: docker/Dockerfile
target: backend
image: ghcr.io/seanmorley15/adventurelog-backend:latest
# build:
# context: .
# dockerfile: docker/Dockerfile
# target: backend
# image: ghcr.io/seanmorley15/adventurelog-backend:latest
container_name: adventurelog-backend
restart: unless-stopped
env_file: .env

View File

@@ -1,10 +1,10 @@
import { defineConfig } from "vitepress";
import { buildPageHead, pageSeo } from "./seo";
// https://vitepress.dev/reference/site-config
export default defineConfig({
head: [
["link", { rel: "icon", href: "/adventurelog.png" }],
[
"script",
{
@@ -13,7 +13,6 @@ export default defineConfig({
"data-website-id": "a7552764-5a1d-4fe7-80c2-5331e1a53cb6",
},
],
[
"link",
{
@@ -24,79 +23,164 @@ export default defineConfig({
],
ignoreDeadLinks: "localhostLinks",
title: "AdventureLog",
description: "The ultimate travel companion.",
description:
"Self-hosted, open-source travel companion for tracking locations, planning trips, and sharing adventures.",
lang: "en-US",
sitemap: {
hostname: "https://adventurelog.app",
},
transformPageData(pageData) {
if (pageData.relativePath === "index.md") {
const jsonLd = {
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: "AdventureLog",
url: "https://adventurelog.app",
applicationCategory: "TravelApplication",
operatingSystem: "Web, Docker, Linux",
description:
"AdventureLog is a self-hosted platform for tracking and planning travel experiences. Built for modern explorers, it offers trip planning, journaling, tracking and location mapping in one privacy-respecting package.",
creator: {
"@type": "Person",
name: "Sean Morley",
url: "https://seanmorley.com",
},
offers: {
"@type": "Offer",
price: "0.00",
priceCurrency: "USD",
description: "Open-source version available for self-hosting.",
},
softwareVersion: "v0.12.1",
license:
"https://github.com/seanmorley15/adventurelog/blob/main/LICENSE",
screenshot:
"https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/adventures.png",
downloadUrl: "https://github.com/seanmorley15/adventurelog",
sameAs: ["https://github.com/seanmorley15/adventurelog"],
keywords: [
"self-hosted travel log",
"open source trip planner",
"travel journaling app",
"docker travel diary",
"map-based travel tracker",
"privacy-focused travel app",
"adventure log software",
"travel experience tracker",
"self-hosted travel app",
"open source travel software",
"trip planning tool",
"travel itinerary manager",
"location-based travel app",
"travel experience sharing",
"travel log application",
],
};
rewrites: {
"docs/Guides/nginx_migration.md": "docs/guides/v0-7-1_migration.md",
},
return {
frontmatter: {
...pageData.frontmatter,
head: [
["script", { type: "application/ld+json" }, JSON.stringify(jsonLd)],
transformPageData(pageData) {
const seo =
pageSeo[pageData.relativePath] ??
({
description:
"AdventureLog documentation for self-hosted travel tracking, trip planning, and Docker deployment.",
} as const);
const pageTitle = seo.title ?? pageData.title;
const head = buildPageHead(pageData.relativePath, pageTitle, seo);
if (pageData.relativePath === "index.md") {
const siteUrl = "https://adventurelog.app";
const screenshot =
"https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/adventures.png";
const structuredData = [
{
"@context": "https://schema.org",
"@type": "WebSite",
name: "AdventureLog",
url: siteUrl,
description: seo.description,
inLanguage: "en-US",
publisher: {
"@type": "Organization",
name: "AdventureLog",
url: siteUrl,
logo: `${siteUrl}/adventurelog.png`,
sameAs: [
"https://github.com/seanmorley15/AdventureLog",
"https://discord.gg/wRbQ9Egr8C",
"https://x.com/AdventureLogApp",
"https://mastodon.social/@adventurelog",
],
},
},
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: "AdventureLog",
url: siteUrl,
applicationCategory: "TravelApplication",
operatingSystem: "Web, Docker, Linux, macOS",
description: seo.description,
featureList: [
"Location and visit tracking",
"Interactive world map",
"Trip itineraries and collections",
"World travel country and region tracker",
"Strava, Immich, and Wanderer integrations",
"Self-hosted Docker deployment",
],
creator: {
"@type": "Person",
name: "Sean Morley",
url: "https://seanmorley.com",
},
offers: {
"@type": "Offer",
price: "0",
priceCurrency: "USD",
description: "Free open-source self-hosted travel companion.",
},
softwareVersion: "v0.12.1",
license:
"https://github.com/seanmorley15/adventurelog/blob/main/LICENSE",
screenshot,
downloadUrl: "https://github.com/seanmorley15/adventurelog",
installUrl: `${siteUrl}/docs/install/quick_start.html`,
sameAs: ["https://github.com/seanmorley15/adventurelog"],
keywords: (seo.keywords ?? []).join(", "),
},
{
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: [
{
"@type": "Question",
name: "What is AdventureLog?",
acceptedAnswer: {
"@type": "Answer",
text: "AdventureLog is an open-source, self-hosted travel companion for tracking locations, planning trips with itineraries, and visualizing travels on an interactive world map.",
},
},
{
"@type": "Question",
name: "How do I install AdventureLog?",
acceptedAnswer: {
"@type": "Answer",
text: "Run curl -sSL https://get.adventurelog.app | bash to install with the official one-line Docker installer. It defaults to the All-in-One setup on port 8015.",
},
},
{
"@type": "Question",
name: "Is AdventureLog free?",
acceptedAnswer: {
"@type": "Answer",
text: "Yes. AdventureLog is GPL-3.0 open source and free to self-host. There are no subscriptions required for the self-hosted version.",
},
},
{
"@type": "Question",
name: "Can I self-host AdventureLog on a homelab or NAS?",
acceptedAnswer: {
"@type": "Answer",
text: "Yes. AdventureLog runs in Docker on homelabs, VPS, Proxmox, Synology NAS, Unraid, Kubernetes, and other Docker-capable platforms.",
},
},
],
},
};
];
for (const graph of structuredData) {
head.push([
"script",
{ type: "application/ld+json" },
JSON.stringify(graph),
]);
}
}
return {};
const description =
pageData.frontmatter.description ?? seo.description ?? pageData.description;
return {
title: seo.title ?? pageData.title,
description,
frontmatter: {
...pageData.frontmatter,
description,
head: [...(pageData.frontmatter.head ?? []), ...head],
},
};
},
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: "Home", link: "/" },
{ text: "Docs", link: "/docs/intro/adventurelog_overview" },
{ text: "Install", link: "/docs/install/getting_started" },
{ text: "Configure", link: "/docs/configuration/environment_variables" },
{ text: "Usage", link: "/docs/usage/usage" },
{
text: "GitHub",
link: "https://github.com/seanmorley15/AdventureLog",
},
],
search: {
provider: "local",
@@ -107,7 +191,7 @@ export default defineConfig({
},
footer: {
message: "AdventureLog",
message: "AdventureLog — self-hosted travel companion",
copyright: "Copyright © 2023-2026 Sean Morley",
},
@@ -115,37 +199,42 @@ export default defineConfig({
sidebar: [
{
text: "About AdventureLog",
text: "Introduction",
items: [
{
text: "AdventureLog Overview",
text: "About AdventureLog",
link: "/docs/intro/adventurelog_overview",
},
],
},
{
text: "Installation",
collapsed: false,
items: [
{ text: "Getting Started", link: "/docs/install/getting_started" },
{ text: "Quick Start Script ⏲️", link: "/docs/install/quick_start" },
{ text: "Docker 🐋", link: "/docs/install/docker" },
{ text: "Proxmox LXC 🐧", link: "/docs/install/proxmox_lxc" },
{ text: "Synology NAS ☁️", link: "/docs/install/synology_nas" },
{ text: "Quick Start Installer", link: "/docs/install/quick_start" },
{ text: "All-in-One Docker (AIO)", link: "/docs/install/aio" },
{ text: "Standard Docker", link: "/docs/install/docker" },
{
text: "Kubernetes and Kustomize 🌐",
link: "/docs/install/kustomize",
},
{ text: "Unraid 🧡", link: "/docs/install/unraid" },
{
text: "Dev Container + WSL 🧰",
text: "Development Setup",
link: "/docs/install/dev_container_wsl",
},
{
text: "With A Reverse Proxy",
collapsed: false,
text: "Platform Guides",
collapsed: true,
items: [
{ text: "Proxmox LXC", link: "/docs/install/proxmox_lxc" },
{ text: "Synology NAS", link: "/docs/install/synology_nas" },
{ text: "Unraid", link: "/docs/install/unraid" },
{
text: "Kubernetes (Kustomize)",
link: "/docs/install/kustomize",
},
],
},
{
text: "Reverse Proxy",
collapsed: true,
items: [
{
text: "Nginx Proxy Manager",
@@ -161,10 +250,7 @@ export default defineConfig({
text: "Usage",
collapsed: false,
items: [
{
text: "How to use AdventureLog",
link: "/docs/usage/usage",
},
{ text: "How to Use AdventureLog", link: "/docs/usage/usage" },
],
},
{
@@ -172,29 +258,22 @@ export default defineConfig({
collapsed: false,
items: [
{
text: "Immich Integration",
link: "/docs/configuration/immich_integration",
text: "Environment Variables",
link: "/docs/configuration/environment_variables",
},
{
text: "Google Maps Integration",
link: "/docs/configuration/google_maps_integration",
text: "Operations & Maintenance",
link: "/docs/configuration/operations",
},
{ text: "Updating", link: "/docs/configuration/updating" },
{
text: "Strava Integration",
link: "/docs/configuration/strava_integration",
},
{
text: "Wanderer Integration",
link: "/docs/configuration/wanderer_integration",
},
{
text: "Social Auth and OIDC",
link: "/docs/configuration/social_auth",
},
{
text: "Authentication Providers",
collapsed: false,
text: "Authentication",
collapsed: true,
items: [
{
text: "Social Auth & OIDC",
link: "/docs/configuration/social_auth",
},
{
text: "Authentik",
link: "/docs/configuration/social_auth/authentik",
@@ -203,39 +282,60 @@ export default defineConfig({
text: "GitHub",
link: "/docs/configuration/social_auth/github",
},
{
text: "Authelia",
link: "https://www.authelia.com/integration/openid-connect/adventure-log/",
},
{
text: "Pocket ID",
link: "/docs/configuration/social_auth/pocket_id",
},
{
text: "Open ID Connect",
text: "OpenID Connect",
link: "/docs/configuration/social_auth/oidc",
},
{
text: "Authelia",
link: "https://www.authelia.com/integration/openid-connect/adventure-log/",
},
{
text: "Disable Registration",
link: "/docs/configuration/disable_registration",
},
{ text: "API Keys", link: "/docs/configuration/api_keys" },
],
},
{
text: "Integrations",
collapsed: true,
items: [
{
text: "Immich",
link: "/docs/configuration/immich_integration",
},
{
text: "Google Maps",
link: "/docs/configuration/google_maps_integration",
},
{
text: "Strava",
link: "/docs/configuration/strava_integration",
},
{
text: "Wanderer",
link: "/docs/configuration/wanderer_integration",
},
],
},
{
text: "Update App",
link: "/docs/configuration/updating",
text: "Storage & Email",
collapsed: true,
items: [
{ text: "S3 Media Storage", link: "/docs/configuration/s3_storage" },
{ text: "SMTP Email", link: "/docs/configuration/email" },
],
},
{
text: "Disable Registration",
link: "/docs/configuration/disable_registration",
},
{ text: "SMTP Email", link: "/docs/configuration/email" },
{ text: "Umami Analytics", link: "/docs/configuration/analytics" },
{ text: "S3 Storage", link: "/docs/configuration/s3_storage" },
{
text: "API Keys",
link: "/docs/configuration/api_keys",
},
{
text: "Advanced Configuration",
text: "Advanced Settings",
link: "/docs/configuration/advanced_configuration",
},
{ text: "Umami Analytics", link: "/docs/configuration/analytics" },
],
},
{
@@ -243,15 +343,15 @@ export default defineConfig({
collapsed: true,
items: [
{
text: "No Images Displaying",
text: "Images Not Displaying",
link: "/docs/troubleshooting/no_images",
},
{
text: "Login and Registration Unresponsive",
text: "Login Unresponsive",
link: "/docs/troubleshooting/login_unresponsive",
},
{
text: "Failed to Start Nginx",
text: "Nginx Failed to Start",
link: "/docs/troubleshooting/nginx_failed",
},
],
@@ -260,16 +360,10 @@ export default defineConfig({
text: "Guides",
collapsed: true,
items: [
{ text: "Admin Panel", link: "/docs/guides/admin_panel" },
{ text: "Invite a User", link: "/docs/guides/invite_user" },
{
text: "Admin Panel",
link: "/docs/guides/admin_panel",
},
{
text: "Invite a User",
link: "/docs/guides/invite_user",
},
{
text: "v0.7.1 Migration Guide",
text: "v0.7.1 Migration",
link: "/docs/guides/v0-7-1_migration",
},
],
@@ -282,38 +376,14 @@ export default defineConfig({
text: "Development Timeline",
link: "/docs/changelogs/development_timeline",
},
{
text: "v0.12.1",
link: "/docs/changelogs/v0-12-1",
},
{
text: "v0.12.0",
link: "/docs/changelogs/v0-12-0",
},
{
text: "v0.11.0",
link: "/docs/changelogs/v0-11-0",
},
{
text: "v0.10.0",
link: "/docs/changelogs/v0-10-0",
},
{
text: "v0.9.0",
link: "/docs/changelogs/v0-9-0",
},
{
text: "v0.8.0",
link: "/docs/changelogs/v0-8-0",
},
{
text: "v0.7.1",
link: "/docs/changelogs/v0-7-1",
},
{
text: "v0.7.0",
link: "/docs/changelogs/v0-7-0",
},
{ text: "v0.12.1", link: "/docs/changelogs/v0-12-1" },
{ text: "v0.12.0", link: "/docs/changelogs/v0-12-0" },
{ text: "v0.11.0", link: "/docs/changelogs/v0-11-0" },
{ text: "v0.10.0", link: "/docs/changelogs/v0-10-0" },
{ text: "v0.9.0", link: "/docs/changelogs/v0-9-0" },
{ text: "v0.8.0", link: "/docs/changelogs/v0-8-0" },
{ text: "v0.7.1", link: "/docs/changelogs/v0-7-1" },
{ text: "v0.7.0", link: "/docs/changelogs/v0-7-0" },
],
},
],

View File

@@ -0,0 +1,306 @@
export type PageSeo = {
title?: string;
description: string;
keywords?: string[];
};
const DEFAULT_OG_IMAGE =
"https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/adventures.png";
const SITE_ORIGIN = "https://adventurelog.app";
/** Per-page SEO metadata keyed by VitePress relativePath. URLs are preserved for search rankings. */
export const pageSeo: Record<string, PageSeo> = {
"index.md": {
title: "AdventureLog — Travel Log, Trip Planner & World Map",
description:
"Log locations with photos and notes, plan multi-day itineraries with flights and lodging, and track countries on an interactive world map. AdventureLog is the open-source travel companion for remembering every trip.",
keywords: [
"travel log app",
"trip planner",
"world travel tracker",
"travel itinerary app",
"location travel journal",
"interactive travel map",
"open source travel app",
"AdventureLog",
],
},
"docs/intro/adventurelog_overview.md": {
description:
"Learn what AdventureLog is, its core features for location tracking and trip planning, and why it is a modern open-source alternative to closed travel apps.",
keywords: ["AdventureLog features", "open source travel app", "trip planning"],
},
"docs/install/getting_started.md": {
description:
"Choose the right AdventureLog installation path: quick-start installer, All-in-One Docker, standard Docker, Kubernetes, or platform-specific guides.",
keywords: ["AdventureLog install", "self-hosted travel app setup"],
},
"docs/install/quick_start.md": {
description:
"Install AdventureLog in seconds with the official curl installer. Defaults to All-in-One Docker with interactive configuration and a built-in management menu.",
keywords: ["AdventureLog quick start", "one line docker install"],
},
"docs/install/aio.md": {
description:
"Run AdventureLog in a single Docker container on one port. Minimal .env.aio configuration with automatic URL and secret derivation for homelabs and VPS installs.",
keywords: ["AdventureLog AIO", "all in one docker", "single container travel app"],
},
"docs/install/docker.md": {
description:
"Standard multi-container Docker setup for AdventureLog with separate frontend, backend, and PostGIS services. Full environment variable reference for production deployments.",
keywords: ["AdventureLog docker compose", "self-hosted docker travel log"],
},
"docs/install/dev_container_wsl.md": {
description:
"Develop AdventureLog on Windows with WSL 2 and VS Code Dev Containers using docker-compose.dev.yml and hot reload for frontend and backend.",
keywords: ["AdventureLog development", "dev container", "WSL docker"],
},
"docs/install/proxmox_lxc.md": {
description:
"Install AdventureLog on Proxmox using an LXC container with Docker for a lightweight homelab deployment.",
keywords: ["AdventureLog Proxmox", "LXC homelab install"],
},
"docs/install/synology_nas.md": {
description:
"Self-host AdventureLog on a Synology NAS using Docker or Container Manager with step-by-step setup guidance.",
keywords: ["AdventureLog Synology", "NAS docker install"],
},
"docs/install/kustomize.md": {
description:
"Deploy AdventureLog on Kubernetes with Kustomize manifests in k8s/base/, including PostGIS and ingress configuration.",
keywords: ["AdventureLog kubernetes", "kustomize deployment"],
},
"docs/install/unraid.md": {
description:
"Install AdventureLog on Unraid with Docker templates for frontend, backend, and PostGIS database containers.",
keywords: ["AdventureLog Unraid", "homelab docker template"],
},
"docs/install/nginx_proxy_manager.md": {
description:
"Put AdventureLog behind Nginx Proxy Manager with HTTPS, path routing, and trusted origin configuration for Django and SvelteKit.",
keywords: ["AdventureLog nginx proxy manager", "reverse proxy HTTPS"],
},
"docs/install/traefik.md": {
description:
"Deploy AdventureLog with Traefik using the official docker-compose-traefik.yaml for automatic HTTPS and path-based routing.",
keywords: ["AdventureLog Traefik", "docker reverse proxy"],
},
"docs/install/caddy.md": {
description:
"Run AdventureLog behind Caddy for automatic HTTPS and simple reverse proxy configuration on a single domain.",
keywords: ["AdventureLog Caddy", "automatic HTTPS proxy"],
},
"docs/usage/usage.md": {
description:
"User guide for AdventureLog: locations, visits, collections, itineraries, world travel, integrations, and collaborative trip planning.",
keywords: ["how to use AdventureLog", "travel log tutorial"],
},
"docs/configuration/environment_variables.md": {
description:
"Complete AdventureLog environment variable reference for standard Docker, AIO, and optional integrations including URLs, security, and storage.",
keywords: ["AdventureLog environment variables", "docker env configuration"],
},
"docs/configuration/operations.md": {
description:
"Operate AdventureLog in production: deploy.sh updates, backup and restore scripts, validate-env checks, management menu, and first-boot behavior.",
keywords: ["AdventureLog backup", "deploy update", "docker operations"],
},
"docs/configuration/updating.md": {
description:
"Update AdventureLog Docker images safely with deploy.sh, the installer management menu, manual compose commands, and region data refresh.",
keywords: ["AdventureLog update", "docker pull upgrade"],
},
"docs/configuration/immich_integration.md": {
description:
"Connect AdventureLog to Immich for photo imports and linking images to travel locations from your self-hosted media library.",
keywords: ["AdventureLog Immich integration", "photo travel log"],
},
"docs/configuration/google_maps_integration.md": {
description:
"Enable Google Maps in AdventureLog for enhanced map tiles and place search using a Google Maps API key.",
keywords: ["AdventureLog Google Maps", "maps API key"],
},
"docs/configuration/strava_integration.md": {
description:
"Import Strava activities into AdventureLog locations with GPX tracks, distance, and elevation data.",
keywords: ["AdventureLog Strava", "activity import"],
},
"docs/configuration/wanderer_integration.md": {
description:
"Link Wanderer trails to AdventureLog locations for hiking routes with distance and elevation context.",
keywords: ["AdventureLog Wanderer", "trail integration"],
},
"docs/configuration/social_auth.md": {
description:
"Configure social and OIDC login for AdventureLog with GitHub, Authentik, Pocket ID, Authelia, and generic OpenID Connect providers.",
keywords: ["AdventureLog OIDC", "social login self-hosted"],
},
"docs/configuration/social_auth/authentik.md": {
description:
"Set up Authentik as an OpenID Connect provider for AdventureLog single sign-on and account linking.",
keywords: ["AdventureLog Authentik", "OIDC SSO"],
},
"docs/configuration/social_auth/github.md": {
description:
"Enable GitHub OAuth login for AdventureLog using django-allauth social application configuration.",
keywords: ["AdventureLog GitHub login", "OAuth"],
},
"docs/configuration/social_auth/pocket_id.md": {
description:
"Configure Pocket ID as an OIDC identity provider for AdventureLog authentication.",
keywords: ["AdventureLog Pocket ID", "OIDC login"],
},
"docs/configuration/social_auth/oidc.md": {
description:
"Connect any OpenID Connect provider to AdventureLog for enterprise or self-hosted identity management.",
keywords: ["AdventureLog OpenID Connect", "generic OIDC"],
},
"docs/configuration/disable_registration.md": {
description:
"Disable public user registration on a self-hosted AdventureLog instance while keeping invites and social signup options.",
keywords: ["AdventureLog disable registration", "private instance"],
},
"docs/configuration/email.md": {
description:
"Configure SMTP email in AdventureLog for account verification, password reset, and invitation messages.",
keywords: ["AdventureLog SMTP", "email configuration"],
},
"docs/configuration/analytics.md": {
description:
"Optionally add Umami analytics to AdventureLog for privacy-friendly usage tracking on your self-hosted instance.",
keywords: ["AdventureLog Umami analytics"],
},
"docs/configuration/s3_storage.md": {
description:
"Store AdventureLog media on S3-compatible object storage including AWS S3, Cloudflare R2, MinIO, and DigitalOcean Spaces.",
keywords: ["AdventureLog S3 storage", "R2 media", "object storage"],
},
"docs/configuration/api_keys.md": {
description:
"Create and use AdventureLog REST API keys for scripts and integrations with the locations, collections, and stats endpoints.",
keywords: ["AdventureLog API keys", "REST API authentication"],
},
"docs/configuration/advanced_configuration.md": {
description:
"Advanced AdventureLog settings: rate limits, Gunicorn workers, email verification, social-only login, and first-boot world data options.",
keywords: ["AdventureLog advanced config", "rate limits", "gunicorn"],
},
"docs/troubleshooting/no_images.md": {
description:
"Fix AdventureLog images not displaying: URL configuration, media paths, S3 settings, and reverse proxy routing for /media.",
keywords: ["AdventureLog images not showing", "media troubleshooting"],
},
"docs/troubleshooting/login_unresponsive.md": {
description:
"Resolve AdventureLog login and registration failures caused by CSRF, ORIGIN, SITE_URL, or reverse proxy misconfiguration.",
keywords: ["AdventureLog login broken", "CSRF troubleshooting"],
},
"docs/troubleshooting/nginx_failed.md": {
description:
"Diagnose 'Starting nginx: nginx failed' errors in the AdventureLog backend container during Docker startup.",
keywords: ["AdventureLog nginx failed", "backend container error"],
},
"docs/guides/admin_panel.md": {
description:
"Use the Django admin panel at /admin to manage AdventureLog users, locations, and database objects as a staff administrator.",
keywords: ["AdventureLog admin panel", "Django admin"],
},
"docs/guides/invite_user.md": {
description:
"Invite users to a private AdventureLog instance using django-invitations from the admin panel or in-app invite flow.",
keywords: ["AdventureLog invite user", "private instance"],
},
"docs/guides/v0-7-1_migration.md": {
description:
"Migrate AdventureLog to v0.7.1 with the updated in-container nginx and gunicorn Docker Compose layout.",
keywords: ["AdventureLog v0.7.1 migration", "nginx migration"],
},
"docs/changelogs/development_timeline.md": {
description:
"The origin story and development timeline of AdventureLog from first commit to a full-featured self-hosted travel platform.",
keywords: ["AdventureLog history", "development timeline"],
},
"docs/changelogs/v0-12-1.md": {
description: "AdventureLog v0.12.1 release notes, bug fixes, and improvements.",
keywords: ["AdventureLog v0.12.1 changelog"],
},
"docs/changelogs/v0-12-0.md": {
description:
"AdventureLog v0.12.0 release: trip planning improvements, itineraries, and budget features.",
keywords: ["AdventureLog v0.12.0 changelog"],
},
"docs/changelogs/v0-11-0.md": {
description:
"AdventureLog v0.11.0 release: Strava and Wanderer integrations, redesigned UI, and new features.",
keywords: ["AdventureLog v0.11.0 changelog"],
},
"docs/changelogs/v0-10-0.md": {
description:
"AdventureLog v0.10.0 release: trip maps, Google Maps integration, and quick deploy script.",
keywords: ["AdventureLog v0.10.0 changelog"],
},
"docs/changelogs/v0-9-0.md": {
description:
"AdventureLog v0.9.0 release: smart recommendations, attachments, and map improvements.",
keywords: ["AdventureLog v0.9.0 changelog"],
},
"docs/changelogs/v0-8-0.md": {
description:
"AdventureLog v0.8.0 release: Immich integration, calendar view, and UI customization.",
keywords: ["AdventureLog v0.8.0 changelog"],
},
"docs/changelogs/v0-7-1.md": {
description:
"AdventureLog v0.7.1 release: in-container nginx migration, gunicorn, and adventure sorting improvements.",
keywords: ["AdventureLog v0.7.1 changelog"],
},
"docs/changelogs/v0-7-0.md": {
description: "AdventureLog v0.7.0 release notes and feature summary.",
keywords: ["AdventureLog v0.7.0 changelog"],
},
};
export function pagePathToUrl(relativePath: string): string {
if (relativePath === "index.md") {
return `${SITE_ORIGIN}/`;
}
const slug = relativePath.replace(/\.md$/, "").replace(/\/index$/, "");
return `${SITE_ORIGIN}/${slug}.html`;
}
export function buildPageHead(
relativePath: string,
pageTitle: string,
seo: PageSeo,
): Array<[string, Record<string, string>] | [string, Record<string, string>, string]> {
const description = seo.description;
const canonicalUrl = pagePathToUrl(relativePath);
const ogTitle = seo.title ?? pageTitle;
const head: Array<
[string, Record<string, string>] | [string, Record<string, string>, string]
> = [
["meta", { name: "description", content: description }],
["meta", { property: "og:title", content: ogTitle }],
["meta", { property: "og:description", content: description }],
["meta", { property: "og:url", content: canonicalUrl }],
["meta", { property: "og:type", content: "article" }],
["meta", { property: "og:image", content: DEFAULT_OG_IMAGE }],
["meta", { property: "og:site_name", content: "AdventureLog" }],
["meta", { name: "twitter:card", content: "summary_large_image" }],
["meta", { name: "twitter:title", content: ogTitle }],
["meta", { name: "twitter:description", content: description }],
["meta", { name: "twitter:image", content: DEFAULT_OG_IMAGE }],
["link", { rel: "canonical", href: canonicalUrl }],
];
if (seo.keywords?.length) {
head.push(["meta", { name: "keywords", content: seo.keywords.join(", ") }]);
}
return head;
}
export { DEFAULT_OG_IMAGE, SITE_ORIGIN };

View File

@@ -0,0 +1,50 @@
<script setup lang="ts">
const features = [
{
icon: "📍",
title: "Log locations & visits",
summary: "More than a pin on a map — a real record of each place.",
details:
"Add dates, notes, photos, trails, and categories. Mark spots as visited or planned, attach Strava activities, and browse everything on an interactive world map.",
},
{
icon: "✈️",
title: "Plan trips & itineraries",
summary: "Collections that grow into full travel plans.",
details:
"Organize multi-day trips with flights, lodging, transport, daily notes, and packing checklists. Share collections and plan together with the people you travel with.",
},
{
icon: "🌍",
title: "Track your world travel",
summary: "See how far you've gone — and what's still on the list.",
details:
"Mark countries, regions, and cities as visited. View travel stats on your dashboard and explore your progress with maps built for bucket lists and lifetime goals.",
},
];
</script>
<template>
<section class="al-features" aria-labelledby="features-heading">
<div class="al-features__inner">
<header class="al-features__head">
<p class="al-eyebrow">What you can do</p>
<h2 id="features-heading">Log, plan, and explore in one travel app</h2>
<p class="al-features__lead">
From weekend getaways to years of backpacking, AdventureLog keeps your
past trips memorable and your next ones organized.
</p>
</header>
<div class="al-features__grid">
<article v-for="(f, i) in features" :key="f.title" class="al-features__card">
<span class="al-features__step" aria-hidden="true">{{ i + 1 }}</span>
<div class="al-features__icon" aria-hidden="true">{{ f.icon }}</div>
<h3>{{ f.title }}</h3>
<p class="al-features__summary">{{ f.summary }}</p>
<p class="al-features__details">{{ f.details }}</p>
</article>
</div>
</div>
</section>
</template>

View File

@@ -0,0 +1,30 @@
<template>
<section class="al-final" aria-labelledby="final-heading">
<div class="al-final__glow" aria-hidden="true" />
<div class="al-final__inner">
<h2 id="final-heading">Your next adventure deserves more than a camera roll</h2>
<p>
Start logging locations, planning itineraries, and mapping the places
that matter then look back on every trip with the detail it deserves.
</p>
<div class="al-final__actions">
<a class="al-btn al-btn--brand al-btn--lg" href="https://demo.adventurelog.app" target="_blank" rel="noopener noreferrer">
Try live demo
</a>
<a class="al-btn al-btn--ghost al-btn--lg" href="/docs/install/quick_start">
Install AdventureLog
</a>
<a class="al-btn al-btn--ghost al-btn--lg" href="/docs/usage/usage">
Read the guide
</a>
</div>
<p class="al-final__support">
<a href="https://discord.gg/wRbQ9Egr8C" target="_blank" rel="noopener noreferrer">Discord</a>
·
<a href="https://github.com/seanmorley15/AdventureLog" target="_blank" rel="noopener noreferrer">GitHub</a>
·
<a href="https://github.com/seanmorley15/AdventureLog/issues" target="_blank" rel="noopener noreferrer">Report an issue</a>
</p>
</div>
</section>
</template>

View File

@@ -0,0 +1,127 @@
<script setup lang="ts">
import { ref } from "vue";
const SHOT =
"https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots";
const command = "curl -sSL https://get.adventurelog.app | bash";
const copied = ref(false);
async function copy() {
try {
await navigator.clipboard.writeText(command);
copied.value = true;
setTimeout(() => (copied.value = false), 2000);
} catch {
/* clipboard unavailable */
}
}
</script>
<template>
<section class="al-hero" aria-labelledby="hero-heading">
<div class="al-hero__backdrop" aria-hidden="true">
<div class="al-hero__grid" />
<div class="al-hero__orb al-hero__orb--green" />
<div class="al-hero__orb al-hero__orb--blue" />
</div>
<div class="al-hero__inner">
<div class="al-hero__copy">
<p class="al-hero__pill">
<span class="al-hero__pill-dot" aria-hidden="true" />
Locations · Itineraries · World map
</p>
<h1 id="hero-heading" class="al-hero__title">
Everything travel,
<span class="al-hero__title-accent">united in one place.</span>
</h1>
<p class="al-hero__lead">
Remember where you've been, plan what's ahead, and see your whole
travel story on one map.
</p>
<div class="al-hero__actions">
<a class="al-hero__btn al-hero__btn--primary" href="/docs/install/getting_started">
Get started
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path
d="M3 8h10M9 4l4 4-4 4"
stroke="currentColor"
stroke-width="1.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</a>
<a
class="al-hero__btn al-hero__btn--secondary"
href="https://demo.adventurelog.app"
target="_blank"
rel="noopener noreferrer"
>
Live demo
</a>
</div>
<div class="al-hero__install">
<code class="al-hero__cmd">
<span class="al-hero__prompt" aria-hidden="true">$</span>
{{ command }}
</code>
<button
type="button"
class="al-hero__copy-btn"
:aria-label="copied ? 'Copied' : 'Copy install command'"
@click="copy"
>
{{ copied ? "Copied" : "Copy" }}
</button>
</div>
<ul class="al-hero__stats" aria-label="Core features">
<li><strong>Locations</strong> visits, photos &amp; trails</li>
<li><strong>Itineraries</strong> flights, lodging &amp; notes</li>
<li><strong>World travel</strong> countries &amp; regions</li>
</ul>
</div>
<div class="al-hero__visual">
<div class="al-hero__glow" aria-hidden="true" />
<div class="al-hero__frame">
<div class="al-hero__chrome" aria-hidden="true">
<span /><span /><span />
<div class="al-hero__url">adventurelog.app</div>
</div>
<img
class="al-hero__shot"
:src="`${SHOT}/adventures.png`"
alt="AdventureLog location list with map, visit filters, and trip categories"
width="1200"
height="675"
loading="eager"
fetchpriority="high"
decoding="async"
/>
</div>
<div class="al-hero__float al-hero__float--map" aria-hidden="true">
<span class="al-hero__float-icon">🗺</span>
<div>
<strong>World map</strong>
<small>Pin &amp; filter locations</small>
</div>
</div>
<div class="al-hero__float al-hero__float--docker" aria-hidden="true">
<span class="al-hero__float-icon"></span>
<div>
<strong>Trip planning</strong>
<small>Itineraries &amp; checklists</small>
</div>
</div>
</div>
</div>
</section>
</template>

View File

@@ -0,0 +1,178 @@
<script setup lang="ts">
import { ref } from "vue";
const command = "curl -sSL https://get.adventurelog.app | bash";
const copied = ref(false);
type InstallPath = {
icon: string;
title: string;
desc: string;
href: string;
external?: boolean;
};
type InstallPathGroup = {
label: string;
paths: InstallPath[];
};
const pathGroups: InstallPathGroup[] = [
{
label: "Docker",
paths: [
{
icon: "⚡",
title: "Quick Start Installer",
desc: "Guided one-line install — AIO by default.",
href: "/docs/install/quick_start",
},
{
icon: "📦",
title: "All-in-One Docker",
desc: "Single container, one port, minimal config.",
href: "/docs/install/aio",
},
{
icon: "🐋",
title: "Standard Docker",
desc: "Frontend, backend, and PostGIS — full control.",
href: "/docs/install/docker",
},
],
},
{
label: "Homelab & NAS",
paths: [
{
icon: "🐧",
title: "Proxmox LXC",
desc: "Lightweight LXC container with Docker.",
href: "/docs/install/proxmox_lxc",
},
{
icon: "☁️",
title: "Synology NAS",
desc: "Install via Container Manager on Synology.",
href: "/docs/install/synology_nas",
},
{
icon: "🧡",
title: "Unraid",
desc: "Docker templates for Unraid homelabs.",
href: "/docs/install/unraid",
},
{
icon: "🏠",
title: "Umbrel",
desc: "Community app for Umbrel home servers.",
href: "https://apps.umbrel.com/app/adventurelog",
external: true,
},
{
icon: "💾",
title: "TrueNAS",
desc: "Community app catalog for TrueNAS SCALE.",
href: "https://apps.truenas.com/catalog/adventurelog/",
external: true,
},
],
},
{
label: "Kubernetes",
paths: [
{
icon: "🌐",
title: "Kubernetes + Kustomize",
desc: "Deploy with manifests in `k8s/base/`.",
href: "/docs/install/kustomize",
},
],
},
];
async function copy() {
try {
await navigator.clipboard.writeText(command);
copied.value = true;
setTimeout(() => (copied.value = false), 2000);
} catch {
/* clipboard unavailable */
}
}
</script>
<template>
<section class="al-install" aria-labelledby="install-heading">
<div class="al-install__inner">
<div class="al-install__copy">
<p class="al-eyebrow">Installation</p>
<h2 id="install-heading">Choose how you run AdventureLog</h2>
<p class="al-install__desc">
Docker guides for most setups, plus platform-specific instructions
for Proxmox, Synology, Unraid, Umbrel, TrueNAS, and Kubernetes.
</p>
<ul class="al-install__badges" aria-label="Install methods">
<li>Docker Compose</li>
<li>Homelab &amp; NAS</li>
<li>Kubernetes</li>
<li>Reverse proxy</li>
</ul>
<div class="al-install__links">
<a class="al-btn al-btn--brand" href="/docs/install/getting_started">
All install options
</a>
<a class="al-btn al-btn--ghost" href="/docs/install/quick_start">
Quick Start
</a>
</div>
</div>
<div class="al-install__panel">
<p class="al-install__panel-label">Install paths</p>
<div
v-for="group in pathGroups"
:key="group.label"
class="al-install__group"
>
<p class="al-install__group-label">{{ group.label }}</p>
<ul class="al-install__paths">
<li v-for="path in group.paths" :key="path.href">
<a
class="al-install__path"
:href="path.href"
:target="path.external ? '_blank' : undefined"
:rel="path.external ? 'noopener noreferrer' : undefined"
>
<span class="al-install__path-icon" aria-hidden="true">{{ path.icon }}</span>
<span class="al-install__path-text">
<strong>{{ path.title }}</strong>
<small>{{ path.desc }}</small>
</span>
<span class="al-install__path-arrow" aria-hidden="true"></span>
</a>
</li>
</ul>
</div>
<div class="al-install__quick" role="group" aria-label="Quick Start command">
<div class="al-install__quick-head">
<span>Fastest path</span>
<button
type="button"
class="al-install__quick-copy"
:aria-label="copied ? 'Copied' : 'Copy install command'"
@click="copy"
>
{{ copied ? "Copied" : "Copy" }}
</button>
</div>
<code class="al-install__quick-cmd">
<span class="al-prompt" aria-hidden="true">$</span> {{ command }}
</code>
</div>
</div>
</div>
</section>
</template>

View File

@@ -0,0 +1,54 @@
<script setup lang="ts">
const pillars = [
{
icon: "📋",
title: "Rich location logs",
text: "Photos, attachments, ratings, tags, and visit history — everything you need to remember why a place mattered.",
},
{
icon: "🗺️",
title: "Interactive maps",
text: "Drop pins from the world map, filter visited vs planned, and see your trips take shape visually.",
},
{
icon: "📅",
title: "Full itineraries",
text: "Flights, lodging, transport, notes, and checklists organized by day for trips that are easy to follow.",
},
{
icon: "🌐",
title: "World travel book",
text: "Track countries, regions, and cities you've explored — with maps and stats that show your progress.",
},
{
icon: "📊",
title: "Travel dashboard",
text: "Countries visited, regions explored, and milestones at a glance — celebrate how much of the world you've seen.",
},
{
icon: "📸",
title: "Integrations",
text: "Pull in photos from Immich, activities from Strava, trails from Wanderer, and places from Google Maps.",
},
];
</script>
<template>
<section class="al-pillars" aria-labelledby="pillars-heading">
<div class="al-section-head al-section-head--center">
<p class="al-eyebrow">Go deeper</p>
<h2 id="pillars-heading">Features built for real travelers</h2>
<p class="al-section-lead al-pillars__lead">
Whether you're planning a road trip or logging years of adventures,
AdventureLog has the tools to capture the full picture.
</p>
</div>
<div class="al-pillars__grid">
<article v-for="p in pillars" :key="p.title" class="al-pillar">
<span class="al-pillar__icon" aria-hidden="true">{{ p.icon }}</span>
<h3>{{ p.title }}</h3>
<p>{{ p.text }}</p>
</article>
</div>
</section>
</template>

View File

@@ -0,0 +1,98 @@
<script setup lang="ts">
import { ref } from "vue";
const SHOT =
"https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots";
const tabs = [
{
id: "locations",
label: "Locations",
title: "Every place, fully logged",
desc: "Filter by visited or planned, sort by date or category, and keep rich notes, photos, and ratings for every stop on your journey.",
src: `${SHOT}/adventures.png`,
alt: "AdventureLog location list with filters and categories",
},
{
id: "map",
label: "World Map",
title: "See your story on the map",
desc: "Drop pins from the interactive MapLibre world map. Toggle visited vs planned and watch your travel history come alive.",
src: `${SHOT}/map.png`,
alt: "AdventureLog interactive world map with location pins",
},
{
id: "itinerary",
label: "Trip Planning",
title: "Plan trips that actually happen",
desc: "Build multi-day itineraries with flights, lodging, checklists, notes, and collaborative collections your whole group can edit.",
src: `${SHOT}/itinerary.png`,
alt: "AdventureLog trip itinerary planner with daily activities",
},
{
id: "dashboard",
label: "Dashboard",
title: "Stats that celebrate travel",
desc: "Track countries, regions, and cities visited. Your personal travel dashboard turns milestones into motivation.",
src: `${SHOT}/dashboard.png`,
alt: "AdventureLog travel statistics dashboard",
},
{
id: "world",
label: "World Travel",
title: "Countries & regions explorer",
desc: "Mark countries and regions as visited with interactive maps. Perfect for bucket lists and lifetime travel goals.",
src: `${SHOT}/countries.png`,
alt: "AdventureLog countries and regions visited tracker",
},
] as const;
const active = ref<(typeof tabs)[number]["id"]>("locations");
const current = () => tabs.find((t) => t.id === active.value) ?? tabs[0];
</script>
<template>
<section class="al-showcase" aria-labelledby="showcase-heading">
<div class="al-section-head">
<p class="al-eyebrow">See it in action</p>
<h2 id="showcase-heading">Built for travelers who want more than a pin on a map</h2>
<p class="al-section-lead">
Track locations, plan itineraries, explore the world, and share trips
all in one self-hosted app you control.
</p>
</div>
<div class="al-showcase__tabs" role="tablist" aria-label="Feature screenshots">
<button
v-for="tab in tabs"
:key="tab.id"
type="button"
role="tab"
class="al-showcase__tab"
:class="{ 'is-active': active === tab.id }"
:aria-selected="active === tab.id"
@click="active = tab.id"
>
{{ tab.label }}
</button>
</div>
<div class="al-showcase__panel" role="tabpanel">
<div class="al-showcase__text">
<h3>{{ current().title }}</h3>
<p>{{ current().desc }}</p>
</div>
<figure class="al-showcase__frame">
<img
:key="current().src"
:src="current().src"
:alt="current().alt"
width="1280"
height="720"
loading="lazy"
decoding="async"
/>
</figure>
</div>
</section>
</template>

View File

@@ -0,0 +1,56 @@
<script setup lang="ts">
const quotes = [
{
quote:
"It's an open-source, self-hosted travel planner that's completely free to use… Safe to say, it's become a mainstay in Docker for me.",
author: "Sumukh Rao",
role: "Senior Author, XDA",
rank: null,
href: "https://www.xda-developers.com/i-self-hosted-this-app-to-plan-itinerary-when-traveling/",
},
{
quote:
"AdventureLog is aptly named… one of the best apps for the job and can be fully self-hosted at home.",
author: "Rich Edmonds",
role: "Lead PC Hardware Editor, XDA",
rank: "#1 self-hosted travel app",
href: "https://www.xda-developers.com/these-self-hosted-apps-are-perfect-for-those-on-the-go/",
},
{
quote:
"AdventureLog represents a new era of travel tracking: open, private, comprehensive, and truly yours.",
author: "Open Source Daily",
role: "Publication",
rank: null,
href: "https://opensourcedaily.blog/adventurelog-private-open-source-travel-tracking-trip-planning/",
},
{
quote:
"AdventureLog behaves more like a super-charged travel journal than yet another travel app.",
author: "Dhruv Bhutani",
role: "Android Authority",
rank: null,
href: "https://www.androidauthority.com/self-hosted-travel-app-3572353/",
},
];
</script>
<template>
<section class="al-proof" aria-labelledby="proof-heading">
<div class="al-section-head al-section-head--center">
<p class="al-eyebrow">Trusted by the self-hosting community</p>
<h2 id="proof-heading">Featured in XDA, Android Authority &amp; more</h2>
</div>
<div class="al-proof__grid">
<blockquote v-for="q in quotes" :key="q.href" class="al-quote">
<p>"{{ q.quote }}"</p>
<footer>
<cite>{{ q.author }}</cite>
<span>{{ q.role }}</span>
<span v-if="q.rank" class="al-quote__rank">{{ q.rank }}</span>
</footer>
<a :href="q.href" target="_blank" rel="noopener noreferrer">Read article </a>
</blockquote>
</div>
</section>
</template>

View File

@@ -0,0 +1,33 @@
<script setup lang="ts">
const stacks = [
{
title: "Frontend",
items: ["SvelteKit", "TailwindCSS", "DaisyUI", "MapLibre GL"],
},
{
title: "Backend",
items: ["Django", "Django REST", "PostGIS", "django-allauth"],
},
{
title: "Deploy",
items: ["Docker Compose", "Kubernetes", "GHCR images", "One-line installer"],
},
];
</script>
<template>
<section class="al-tech" aria-labelledby="tech-heading">
<div class="al-section-head al-section-head--center">
<p class="al-eyebrow">Modern stack</p>
<h2 id="tech-heading">Built with tools you already trust</h2>
</div>
<div class="al-tech__grid">
<div v-for="stack in stacks" :key="stack.title" class="al-tech__card">
<h3>{{ stack.title }}</h3>
<ul>
<li v-for="item in stack.items" :key="item">{{ item }}</li>
</ul>
</div>
</div>
</section>
</template>

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,29 @@
// https://vitepress.dev/guide/custom-theme
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import './style.css'
import { h } from "vue";
import type { Theme } from "vitepress";
import DefaultTheme from "vitepress/theme";
import HomeHero from "./components/HomeHero.vue";
import HomeFeatures from "./components/HomeFeatures.vue";
import "./style.css";
import "./home.css";
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
"home-hero-before": () => h(HomeHero),
"home-features-before": () => h(HomeFeatures),
});
},
enhanceApp({ app, router, siteData }) {
// ...
}
} satisfies Theme
enhanceApp({ app }) {
const components = import.meta.glob("./components/Home*.vue", {
eager: true,
}) as Record<string, { default: object }>;
for (const path in components) {
const name = path.split("/").pop()!.replace(".vue", "");
if (name !== "HomeHero" && name !== "HomeFeatures") {
app.component(name, components[path].default);
}
}
},
} satisfies Theme;

View File

@@ -92,18 +92,19 @@
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
#1c913f 30%,
#1f73f1
--vp-home-hero-name-background: linear-gradient(
135deg,
#159947 0%,
#1c913f 35%,
#1f73f1 100%
);
--vp-home-hero-image-background-image: linear-gradient(
-45deg,
#1c913f 50%,
#1f73f1 50%
135deg,
rgba(28, 145, 63, 0.5) 0%,
rgba(31, 115, 241, 0.4) 100%
);
--vp-home-hero-image-filter: blur(44px);
--vp-home-hero-image-filter: blur(56px);
}
@media (min-width: 640px) {

View File

@@ -10,7 +10,7 @@ Hi everyone! I am super excited to announce the release of AdventureLog v0.7.1.
> [!IMPORTANT]
> _While the app will still function normally without these changes_, they are recommended for the best support and stability
> The **migration guide** can be found here: https://docs.adventurelog.app/docs/Guides/nginx_migration
> The **migration guide** can be found here: [v0.7.1 Migration Guide](../guides/v0-7-1_migration.md)
- Migrated nginx inside of server container for easier deployment, removed external nginx requirement
- App now uses gunicorn for better performance at scale

View File

@@ -1,9 +1,64 @@
# Advanced Configuration
In addition to the primary configuration variables listed above, there are several optional environment variables that can be set to further customize your AdventureLog instance. These variables are not required for a basic setup but can enhance functionality and security.
Optional environment variables for security hardening, performance tuning, and authentication behavior. For the complete reference, see [Environment Variables](environment_variables.md).
| Name | Required | Description | Default Value | Variable Location |
| ---------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | ----------------- |
| `ACCOUNT_EMAIL_VERIFICATION` | No | Enable email verification for new accounts. Options are `none`, `optional`, or `mandatory` | `none` | Backend |
| `FORCE_SOCIALACCOUNT_LOGIN` | No | When set to `True`, only social login is allowed (no password login). The login page will show only social providers or redirect directly to the first provider if only one is configured. | `False` | Backend |
| `SOCIALACCOUNT_ALLOW_SIGNUP` | No | When set to `True`, signup will be allowed via social providers even if registration is disabled. | `False` | Backend |
## Authentication behavior
| Variable | Default | Description |
| -------- | ------- | ----------- |
| `ACCOUNT_EMAIL_VERIFICATION` | `none` | `none`, `optional`, or `mandatory` email verification for new accounts |
| `FORCE_SOCIALACCOUNT_LOGIN` | `False` | When `True`, disables password login — social/OIDC providers only |
| `SOCIALACCOUNT_ALLOW_SIGNUP` | `False` | Allow new accounts via social providers even when `DISABLE_REGISTRATION=True` |
Related: [Social Auth](social_auth.md), [Disable Registration](disable_registration.md), [SMTP Email](email.md).
## Rate limiting
Enable in production to protect against abuse:
```env
ENABLE_RATE_LIMITS=True
```
Per-endpoint overrides (all optional):
| Variable | Default | Endpoint |
| -------- | ------- | -------- |
| `RATE_LIMIT_USER` | `10000/hour` | Authenticated API requests |
| `RATE_LIMIT_IMAGE_PROXY` | `60/minute` | Image proxy |
| `RATE_LIMIT_IMAGE_IMPORT` | `12/minute` | Image import |
| `RATE_LIMIT_EXTERNAL_GEOCODE` | `120/minute` | External geocoding |
| `RATE_LIMIT_EXTERNAL_RECOMMENDATIONS` | `30/minute` | Recommendations |
| `RATE_LIMIT_EXTERNAL_WIKIPEDIA` | `60/minute` | Wikipedia lookups |
| `RATE_LIMIT_EXTERNAL_SUN_TIMES` | `30/minute` | Sun times API |
## Performance
| Variable | Default | Description |
| -------- | ------- | ----------- |
| `GUNICORN_WORKERS` | `2` | Gunicorn worker count. Use `1` on small VPS instances; `(2 × CPU cores) + 1` on larger servers. |
| `SKIP_WORLD_DATA` | unset | Set to `1` to skip the first-boot `download-countries` import. Saves RAM on low-memory hosts; world travel data can be imported later. |
The installer offers `SKIP_WORLD_DATA=1` automatically when it detects limited RAM.
## Multi-factor authentication
MFA (TOTP) is configured per-user in the app, not via environment variables:
1. Log in and open **Settings → Security**
2. Enable **Multi-Factor Authentication**
3. Scan the QR code with an authenticator app
## Mobile QR login
AdventureLog supports QR-based mobile login from **Settings → Security**. No server-side configuration is required.
## Cloud billing (hosted only)
These variables apply only to the hosted AdventureLog cloud service, not self-hosted installs:
| Variable | Description |
| -------- | ----------- |
| `CLOUD_MODE` | Enable cloud billing features |
| `CLOUD_TRIAL_DAYS` | Trial period length |
| `STRIPE_*` | Stripe payment integration keys |

View File

@@ -29,7 +29,7 @@ Authorization: Api-Key al_your_key_here
### Example with `curl`
```bash
curl https://your-adventurelog-instance.com/api/adventures/ \
curl https://your-adventurelog-instance.com/api/locations/ \
-H "X-API-Key: al_your_key_here"
```

View File

@@ -0,0 +1,159 @@
# Environment Variables
AdventureLog configuration is driven by environment variables. The file you edit depends on your install type:
| Install type | Env file | Compose file |
| ------------ | -------- | ------------ |
| All-in-One (AIO) | `.env.aio` | `docker-compose.aio.yml` |
| Standard Docker | `.env` | `docker-compose.yml` |
| Traefik | `.env` | `docker-compose-traefik.yaml` |
| Development | `.env` | `docker-compose.dev.yml` |
Validate before deploying:
```bash
bash scripts/validate-env.sh
# or for AIO:
bash scripts/validate-env.sh .env.aio
```
::: tip AIO minimal setup
AIO only requires `POSTGRES_PASSWORD` in `.env.aio`. URLs, `SECRET_KEY`, and admin defaults are derived at container startup. See [All-in-One Docker](../install/aio.md).
:::
## URL and networking
These variables control how the browser, SvelteKit SSR, and Django talk to each other.
| Variable | Required | Used by | Description | Default |
| -------- | -------- | ------- | ----------- | ------- |
| `SITE_URL` | No | Both | Single public URL when frontend and backend share one domain. Derives `ORIGIN`, `FRONTEND_URL`, `PUBLIC_URL`, and `CSRF_TRUSTED_ORIGINS` when those are unset. | — |
| `PUBLIC_SERVER_URL` | Yes | Frontend SSR | Internal backend URL for server-side requests. **Keep `http://server:8000` in standard Docker.** AIO uses `http://127.0.0.1:8000`. | `http://server:8000` |
| `ORIGIN` | Sometimes | Frontend | Public frontend origin (needed without HTTPS). | `http://localhost:8015` |
| `FRONTEND_URL` | Yes | Backend | Public frontend URL for emails and redirects. | `http://localhost:8015` |
| `PUBLIC_URL` | Yes | Backend | Public backend URL for media and OAuth callbacks. | `http://localhost:8016` |
| `CSRF_TRUSTED_ORIGINS` | Yes | Backend | Comma-separated browser origins allowed to submit forms. | `http://localhost:8015,http://localhost:8016` |
| `FRONTEND_PORT` | Yes | Compose | Host port for the frontend container. | `8015` |
| `BACKEND_PORT` | Yes | Compose | Host port for the backend container. | `8016` |
| `HOST_PORT` | No | AIO compose | Host port mapped to the AIO container. | `8015` |
| `BODY_SIZE_LIMIT` | Yes | Frontend | Maximum upload size in bytes. | `Infinity` |
See [Standard Docker](../install/docker.md#url-mental-model) for a visual explanation of the URL model.
## Database (PostgreSQL / PostGIS)
| Variable | Required | Description | Default |
| -------- | -------- | ----------- | ------- |
| `PGHOST` | Yes | Database hostname inside Docker network. | `db` |
| `POSTGRES_DB` / `PGDATABASE` | Yes | Database name. | `database` |
| `POSTGRES_USER` / `PGUSER` | Yes | Database user. | `adventure` |
| `POSTGRES_PASSWORD` / `PGPASSWORD` | Yes | Database password. Change in production. | `changeme123` |
## Django core
| Variable | Required | Description | Default |
| -------- | -------- | ----------- | ------- |
| `SECRET_KEY` | Yes | Django secret key. Auto-generated on AIO if unset. | `changeme123` |
| `DEBUG` | No | Enable debug mode. Use `False` in production. | `False` |
| `DJANGO_ADMIN_USERNAME` | Yes | First-boot superuser username. | `admin` |
| `DJANGO_ADMIN_PASSWORD` | Yes | First-boot superuser password. | `admin` |
| `DJANGO_ADMIN_EMAIL` | Yes | First-boot superuser email. | `admin@example.com` |
| `GUNICORN_WORKERS` | No | Gunicorn worker processes. Use `1` on small hosts; `(2 × CPU) + 1` on larger servers. | `2` |
| `SKIP_WORLD_DATA` | No | Set to `1` to skip the first-boot `download-countries` import (saves RAM; world travel data loads later). | unset |
## Registration and authentication
| Variable | Required | Description | Default |
| -------- | -------- | ----------- | ------- |
| `DISABLE_REGISTRATION` | No | Block new account signups. | `False` |
| `DISABLE_REGISTRATION_MESSAGE` | No | Message shown when registration is disabled. | Custom message |
| `SOCIALACCOUNT_ALLOW_SIGNUP` | No | Allow new accounts via social providers when registration is disabled. | `False` |
| `FORCE_SOCIALACCOUNT_LOGIN` | No | Disable password login; social/OIDC only. | `False` |
| `ACCOUNT_EMAIL_VERIFICATION` | No | `none`, `optional`, or `mandatory`. | `none` |
Related guides: [Social Auth](social_auth.md), [Disable Registration](disable_registration.md), [API Keys](api_keys.md).
## Rate limiting
| Variable | Required | Description | Default |
| -------- | -------- | ----------- | ------- |
| `ENABLE_RATE_LIMITS` | No | Enable API rate limiting. Recommended in production. | `False` |
| `RATE_LIMIT_USER` | No | Default authenticated user throttle. | `10000/hour` |
| `RATE_LIMIT_IMAGE_PROXY` | No | Image proxy endpoint limit. | `60/minute` |
| `RATE_LIMIT_IMAGE_IMPORT` | No | Image import limit. | `12/minute` |
| `RATE_LIMIT_EXTERNAL_GEOCODE` | No | External geocoding limit. | `120/minute` |
| `RATE_LIMIT_EXTERNAL_RECOMMENDATIONS` | No | Recommendations API limit. | `30/minute` |
| `RATE_LIMIT_EXTERNAL_WIKIPEDIA` | No | Wikipedia lookup limit. | `60/minute` |
| `RATE_LIMIT_EXTERNAL_SUN_TIMES` | No | Sun times API limit. | `30/minute` |
See [Advanced Configuration](advanced_configuration.md) for usage notes.
## Email (SMTP)
| Variable | Required | Description |
| -------- | -------- | ----------- |
| `EMAIL_BACKEND` | No | `console` (logs only) or `email` (SMTP). |
| `EMAIL_HOST` | If SMTP | SMTP server hostname. |
| `EMAIL_PORT` | No | SMTP port. Default `587`. |
| `EMAIL_USE_TLS` | No | Enable TLS. Default `true`. |
| `EMAIL_USE_SSL` | No | Enable SSL. Default `false`. |
| `EMAIL_HOST_USER` | If SMTP | SMTP username. |
| `EMAIL_HOST_PASSWORD` | If SMTP | SMTP password. |
| `DEFAULT_FROM_EMAIL` | If SMTP | Sender address. |
See [SMTP Email](email.md).
## Media storage
| Variable | Required | Description | Default |
| -------- | -------- | ----------- | ------- |
| `MEDIA_STORAGE` | No | `local` or `s3`. | `local` |
| `MEDIA_STORAGE_LIMIT_MB` | No | Per-user storage cap in MB (`0` = unlimited). | `0` |
| `MEDIA_STORAGE_LIMIT_BYTES` | No | Overrides MB limit when set. | `0` |
| `AWS_ACCESS_KEY_ID` | If S3 | S3 access key. | — |
| `AWS_SECRET_ACCESS_KEY` | If S3 | S3 secret key. | — |
| `AWS_STORAGE_BUCKET_NAME` | If S3 | Bucket name. | — |
| `AWS_S3_ENDPOINT_URL` | If non-AWS | Provider endpoint (R2, MinIO, Spaces). | — |
| `AWS_S3_REGION_NAME` | No | Region (`auto` for Cloudflare R2). | — |
| `AWS_S3_CUSTOM_DOMAIN` | No | CDN or custom domain for media URLs. | — |
See [S3 Media Storage](s3_storage.md).
## Integrations
| Variable | Required | Description |
| -------- | -------- | ----------- |
| `GOOGLE_MAPS_API_KEY` | If enabled | Google Maps tiles and place search. |
| `STRAVA_CLIENT_ID` | If enabled | Strava OAuth client ID. |
| `STRAVA_CLIENT_SECRET` | If enabled | Strava OAuth client secret. |
| `PUBLIC_UMAMI_SRC` | If enabled | Umami analytics script URL. |
| `PUBLIC_UMAMI_WEBSITE_ID` | If enabled | Umami website ID. |
## Traefik compose
Used with `docker-compose-traefik.yaml`:
| Variable | Required | Description |
| -------- | -------- | ----------- |
| `ACME_EMAIL` | Yes | Let's Encrypt registration email. |
| `TRAEFIK_DOMAIN` | Yes | Public domain for the Traefik router. |
## Operations
These are not application settings but affect management scripts:
| Variable | Description | Default |
| -------- | ----------- | ------- |
| `COMPOSE_FILE` | Override compose file (`deploy.sh`, backup, restore). | Auto-detected |
| `ADVENTURELOG_COMPOSE` | Set to `aio` to prefer AIO when both env files exist. | unset |
| `BACKUP_DIR` | Backup output directory for `scripts/backup.sh`. | `backups` |
| `ADVENTURELOG_REF` | Git ref for installer downloads. | `main` |
See [Operations & Maintenance](operations.md).
## Source of truth
- Standard env template: [`.env.example`](https://github.com/seanmorley15/AdventureLog/blob/main/.env.example)
- AIO env template: [`.env.aio.example`](https://github.com/seanmorley15/AdventureLog/blob/main/.env.aio.example)
- Django settings: [`backend/server/main/settings.py`](https://github.com/seanmorley15/AdventureLog/blob/main/backend/server/main/settings.py)
- AIO derivation: [`aio/env-setup.sh`](https://github.com/seanmorley15/AdventureLog/blob/main/aio/env-setup.sh)

View File

@@ -0,0 +1,140 @@
# Operations & Maintenance
Day-to-day tasks for a self-hosted AdventureLog instance: updates, backups, validation, and the installer management menu.
## Management menu
Re-run the installer to open the interactive management menu:
```bash
curl -sSL https://get.adventurelog.app | bash
```
Or from your install directory:
```bash
bash install_adventurelog.sh --manage
```
Available actions:
| Action | What it does |
| ------ | ------------ |
| **Status** | Shows container health and `/health` endpoint |
| **Update** | Pulls latest images and redeploys (optional backup first) |
| **Reconfigure** | Re-runs the configuration wizard |
| **Backup** | Runs `scripts/backup.sh` |
| **Restore** | Runs `scripts/restore.sh` from a backup folder |
| **Logs** | Follows container logs |
| **Restart** | Restarts the compose stack |
| **Uninstall** | Stops containers, removes volumes |
## Compose file detection
`deploy.sh`, `scripts/backup.sh`, and `scripts/restore.sh` auto-detect your setup:
| Condition | Compose file | Env file |
| --------- | ------------ | -------- |
| Only `.env.aio` exists | `docker-compose.aio.yml` | `.env.aio` |
| `ADVENTURELOG_COMPOSE=aio` with both env files | `docker-compose.aio.yml` | `.env.aio` |
| Otherwise | `docker-compose.yml` | `.env` |
Override manually:
```bash
COMPOSE_FILE=docker-compose.aio.yml bash deploy.sh --backup
```
Always pass `--env-file` when running `docker compose` directly:
```bash
docker compose --env-file .env.aio -f docker-compose.aio.yml ps
```
## Updating
See [Updating](updating.md) for full details. Quick reference:
```bash
# Recommended — validates env, backs up, pulls, and waits for health
bash deploy.sh --backup
# AIO with explicit compose file
COMPOSE_FILE=docker-compose.aio.yml bash deploy.sh --backup
```
## Backup
`scripts/backup.sh` creates a timestamped folder under `backups/` containing:
- Your env file (`.env` or `.env.aio`)
- PostgreSQL dump (`database.sql`)
- Media volume archive (`media.tar.gz`)
```bash
bash scripts/backup.sh
# Custom output directory:
BACKUP_DIR=/mnt/backups bash scripts/backup.sh
```
::: warning Legacy script
The root `backup.sh` only archives the media volume and does **not** include the database. Use `scripts/backup.sh` instead.
:::
## Restore
```bash
bash scripts/restore.sh backups/20260101-120000
```
This stops the stack, restores env + database + media, and brings containers back up.
## Environment validation
Run before every deploy or after editing env files:
```bash
bash scripts/validate-env.sh
bash scripts/validate-env.sh .env.aio
```
The validator catches common mistakes such as `PUBLIC_SERVER_URL` pointing at the host backend port instead of the internal Docker service name.
## First boot behavior
On first start, the backend container:
1. Runs database migrations
2. Creates the Django superuser from `DJANGO_ADMIN_*` variables
3. Imports world geography data (`download-countries`) unless `SKIP_WORLD_DATA=1`
The geography import needs **~2 GB RAM** on first boot. Steady-state use is typically **~1 GB**. The installer offers `SKIP_WORLD_DATA=1` on low-memory hosts.
## Scheduled tasks
Inside the backend container, a cron job runs nightly (UTC midnight):
```bash
python manage.py sync_visited_regions
```
This keeps world-travel region visit status in sync with location data.
## In-app backup vs shell scripts
AdventureLog also has backup/restore features in **Settings** that operate through the REST API. These are separate from `scripts/backup.sh` and are useful for app-level exports. For full disaster recovery (database + media + env), use the shell scripts.
## Security checklist
- [ ] Change default `POSTGRES_PASSWORD`, `SECRET_KEY`, and admin credentials
- [ ] Set `ENABLE_RATE_LIMITS=True` in production
- [ ] Configure `CSRF_TRUSTED_ORIGINS` / `SITE_URL` for your public domain
- [ ] Use HTTPS via a reverse proxy
- [ ] Review [API Keys](api_keys.md) and revoke unused keys
- [ ] Enable MFA in **Settings → Security** for admin accounts
## Related docs
- [Environment Variables](environment_variables.md)
- [Updating](updating.md)
- [Troubleshooting](../troubleshooting/login_unresponsive.md)

View File

@@ -1,6 +1,6 @@
## S3-compatible media storage
# S3 Media Storage
This document explains how to enable optional S3-compatible object storage for AdventureLog's user-uploaded media (images, files). Use S3 when you want scalable, durable media hosting separate from the application container.
Store AdventureLog user uploads (images, attachments) on S3-compatible object storage instead of the local filesystem. Supported providers include AWS S3, Cloudflare R2, DigitalOcean Spaces, and MinIO.
### Recommendation

View File

@@ -4,12 +4,17 @@ AdventureLog support authentication via 3rd party services and self-hosted ident
The steps for each service varies so please refer to the specific service's documentation for more information.
## Supported Services
## Supported providers
- [Authentik](social_auth/authentik.md) (self-hosted)
- [GitHub](social_auth/github.md)
- [Open ID Connect](social_auth/oidc.md)
- [Authelia](https://www.authelia.com/integration/openid-connect/adventure-log/)
| Provider | Type | Guide |
| -------- | ---- | ----- |
| Authentik | Self-hosted OIDC | [Setup guide](social_auth/authentik.md) |
| GitHub | OAuth | [Setup guide](social_auth/github.md) |
| Pocket ID | Self-hosted OIDC | [Setup guide](social_auth/pocket_id.md) |
| OpenID Connect | Generic OIDC | [Setup guide](social_auth/oidc.md) |
| Authelia | Self-hosted OIDC | [External guide](https://www.authelia.com/integration/openid-connect/adventure-log/) |
Providers are configured in the Django admin panel under **Social applications**. See the [Admin Panel](../guides/admin_panel.md) for access requirements.
## Linking Existing Accounts

View File

@@ -1,54 +1,68 @@
# Updating
# Updating AdventureLog
Updating AdventureLog when using Docker is straightforward. **Back up your instance before updating.**
Keep your self-hosted instance current with the latest images and database migrations. **Always back up before updating.**
### Option 1: Re-run the installer (management menu)
## Option 1: Installer management menu
```bash
curl -sSL https://get.adventurelog.app | bash
```
Choose **Update to latest images** (optionally with backup).
Choose **Update to latest images** (with optional backup).
### Option 2: deploy.sh (cron-safe)
## Option 2: deploy.sh (recommended)
Make sure you are in the same directory as your compose file.
From your install directory (where `deploy.sh` and your compose file live):
```bash
bash deploy.sh --backup
bash deploy.sh --logs # optional: follow container logs after deploy
bash deploy.sh --logs # optional: follow logs after deploy
```
For AIO installs, pass the compose file explicitly or rely on auto-detection when only `.env.aio` exists:
`deploy.sh` validates your env file, creates a backup, pulls images, and runs `docker compose up -d --wait`.
For AIO installs:
```bash
COMPOSE_FILE=docker-compose.aio.yml bash deploy.sh --backup
```
### Option 3: Manual
See [Operations & Maintenance](operations.md) for compose auto-detection details.
## Option 3: Manual compose
```bash
bash scripts/backup.sh
docker compose pull
docker compose up -d --wait
# Standard
docker compose --env-file .env -f docker-compose.yml pull
docker compose --env-file .env -f docker-compose.yml up -d --wait
# AIO
docker compose --env-file .env.aio -f docker-compose.aio.yml pull
docker compose --env-file .env.aio -f docker-compose.aio.yml up -d --wait
```
To restore from a backup directory:
## Restore from backup
```bash
bash scripts/restore.sh backups/YYYYMMDD-HHMMSS
```
## Updating the Region Data
## Updating region data
Region and Country data in AdventureLog is provided by an open source project: [dr5hn/countries-states-cities-database](https://github.com/dr5hn/countries-states-cities-database). If you would like to update the region data in your AdventureLog instance, you can do so by running the following command. This will make sure your database is up to date with the latest region data for your version of AdventureLog. For security reasons, the region data is not automatically updated to the latest and is release version is controlled in the `settings.py` file.
```bash
docker exec -it <container> bash
```
Once you are in the container run the following command to resync the region data.
Country and region reference data comes from [dr5hn/countries-states-cities-database](https://github.com/dr5hn/countries-states-cities-database). To refresh it manually:
```bash
docker exec -it <backend-container> bash
python manage.py download-countries --force
```
Region data version is pinned per AdventureLog release in `settings.py` and is not auto-updated on every deploy.
## What happens during an update
1. New container images are pulled
2. Containers restart with your existing env and volumes
3. Database migrations run automatically on backend startup
4. The `/health` endpoint confirms the stack is ready

View File

@@ -1,11 +1,42 @@
# AdventureLog Admin Panel
# Admin Panel
The AdventureLog Admin Panel, powered by Django, is a web-based interface that allows administrators to manage objects in the AdventureLog database. The Admin Panel is accessible at the `/admin` endpoint of the AdventureLog server. Example: `https://al-server.yourdomain.com/admin`.
The AdventureLog admin panel is powered by Django and is available at `/admin` on your backend URL. In AIO installs, that is the same domain as the frontend (for example `https://adventurelog.example.com/admin`).
Features of the Admin Panel include:
## Access requirements
- **User Management**: Administrators can view and manage user accounts, including creating new users, updating user information, and deleting users.
- **Adventure Management**: Administrators can view and manage adventures, including creating new adventures, updating adventure information, and deleting adventures.
- **Security**: The Admin Panel enforces access control to ensure that only authorized administrators can access and manage the database. This means that only users with the `is_staff` flag set to `True` can access the Admin Panel.
Only users with the **staff** flag (`is_staff=True`) can access the admin panel. The first-boot superuser created from `DJANGO_ADMIN_*` environment variables has staff access by default.
Note: the `CSRF_TRUSTED_ORIGINS` setting in your `docker-compose.yml` file must include the domain of the server. For example, if your server is hosted at `https://al-server.yourdomain.com`, you should add `al-server.yourdomain.com` to the `CSRF_TRUSTED_ORIGINS` setting.
## What you can manage
| Section | Description |
| ------- | ----------- |
| **Users** | Create, edit, and deactivate user accounts |
| **Locations** | View and manage location records in the database |
| **Social applications** | Configure OAuth/OIDC providers (GitHub, OIDC, etc.) |
| **Invitations** | Send invite links for private instances |
| **World data** | Countries, regions, and cities reference data |
## CSRF configuration
If the admin panel loads but form submissions fail, verify `CSRF_TRUSTED_ORIGINS` in your `.env` or `.env.aio` includes your public domain:
```env
CSRF_TRUSTED_ORIGINS=https://adventurelog.example.com
```
When using a single domain, set `SITE_URL` instead and the origins are derived automatically. See [Environment Variables](../configuration/environment_variables.md#url-and-networking).
## Social auth setup
OAuth and OIDC providers are configured in the admin panel under **Social applications** and **Social accounts**. Step-by-step guides:
- [Social Auth overview](../configuration/social_auth.md)
- [GitHub](../configuration/social_auth/github.md)
- [Authentik](../configuration/social_auth/authentik.md)
- [Pocket ID](../configuration/social_auth/pocket_id.md)
- [OpenID Connect](../configuration/social_auth/oidc.md)
## Related guides
- [Invite a User](invite_user.md)
- [Disable Registration](../configuration/disable_registration.md)

View File

@@ -105,6 +105,9 @@ docker compose --env-file .env.aio -f docker-compose.aio.yml build
See [`docker/README.md`](https://github.com/seanmorley15/AdventureLog/blob/main/docker/README.md) for all build targets.
## Optional settings
## Operations
Advanced options (S3 media, OAuth, email, etc.) can still be passed as environment variables on the `app` service in `docker-compose.aio.yml`. See the full [Docker configuration](docker.md) reference for available variables.
- [Operations & Maintenance](../configuration/operations.md) — backups, updates, management menu
- [Environment Variables](../configuration/environment_variables.md) — full reference including optional S3, OAuth, and email settings
Advanced options can be added to `.env.aio` or the `environment` block in `docker-compose.aio.yml`.

View File

@@ -1,10 +1,10 @@
# Docker 🐋
# Standard Docker
Docker is the preferred way to run AdventureLog on your local machine. It is a lightweight containerization technology that allows you to run applications in isolated environments called containers.
Run AdventureLog as three containers: SvelteKit frontend, Django backend, and PostGIS database. This layout gives full control over environment variables and is the best fit for reverse proxies and custom integrations.
> **Looking for the simplest setup?** See the [All-in-One (AIO)](aio.md) guide — one container, one port, two environment variables.
> **Note**: This guide mainly focuses on installation with a Linux-based host machine, but the steps are similar for other operating systems.
> **Looking for the simplest setup?** See [All-in-One Docker (AIO)](aio.md) — one container, one port, two required env vars.
>
> **Full env reference:** [Environment Variables](../configuration/environment_variables.md)
## Prerequisites
@@ -52,7 +52,7 @@ bash scripts/validate-env.sh
## Configuration
The `.env` file contains all the configuration settings for your AdventureLog instance. Heres a breakdown of each section:
The `.env` file contains all configuration for your instance. Below are the most important variables — see [Environment Variables](../configuration/environment_variables.md) for the complete reference.
### 🌐 Frontend (web)
@@ -95,12 +95,21 @@ The `.env` file contains all the configuration settings for your AdventureLog in
- [Immich Integration](../configuration/immich_integration.md)
- [Umami Analytics](../configuration/analytics.md)
## Running the Containers
## Running the containers
Once you've configured `.env`, you can start AdventureLog with:
Validate and start:
```bash
docker compose up -d
bash scripts/validate-env.sh
docker compose --env-file .env -f docker-compose.yml up -d --wait
```
Enjoy using AdventureLog! 🎉
Open **http://localhost:8015** (or your configured `ORIGIN` / `SITE_URL`).
Default admin login: `admin` / `admin` — change this after first login.
## Next steps
- [Operations & Maintenance](../configuration/operations.md) — backups, updates, management menu
- [Reverse proxy guides](getting_started.md#reverse-proxy) — HTTPS on a custom domain
- [Configuration](../configuration/environment_variables.md) — integrations and advanced settings

View File

@@ -1,38 +1,74 @@
# 🚀 Install Options for AdventureLog
# Install AdventureLog
AdventureLog can be installed in a variety of ways, depending on your platform or preference.
AdventureLog runs on Docker in most setups. Pick the guide that matches your environment — from a one-line installer to platform-specific homelab and NAS instructions.
## Which setup should I use?
## Quick start
| Your situation | Recommended path |
| -------------- | ---------------- |
| New homelab / quick install | [Quick start installer](quick_start.md) — AIO by default, interactive setup |
| Full env control, split containers, or custom integrations | [Standard Docker](docker.md) — full `.env.example` (also available in installer advanced mode) |
| Split domains or path-based reverse proxy (Traefik, NPM, Caddy) | Standard Docker + [reverse proxy docs](#advanced--alternative-setups) |
| Kubernetes cluster | [Kubernetes + Kustomize](kustomize.md) — see `k8s/base/` |
## 📦 Docker Quick Start
::: tip Quick Start Script
**The fastest way to get started:**
[Install AdventureLog with a single command →](quick_start.md)
Perfect for Docker beginners.
::: tip Fastest install
```bash
curl -sSL https://get.adventurelog.app | bash
```
:::
## 🐳 Popular Installation Methods
The [Quick Start Installer](quick_start.md) walks you through setup (AIO by default), writes your env files, and starts AdventureLog. Re-run the same command for updates, backups, and configuration changes.
- [All-in-One Docker (AIO)](aio.md) — Single container, one port, minimal config
- [Docker](docker.md) — Standard multi-container setup
- [Proxmox LXC](proxmox_lxc.md) — Lightweight virtual environment
- [Synology NAS](synology_nas.md) — Self-host on your home NAS
- [Kubernetes + Kustomize](kustomize.md) — Advanced, scalable deployment
- [Unraid](unraid.md) — Easy integration for homelabbers
- [Umbrel](https://apps.umbrel.com/app/adventurelog) — Home server app store
- [TrueNAS](https://apps.truenas.com/catalog/adventurelog/) — TrueNAS app catalog
## Choose your setup
## ⚙️ Advanced & Alternative Setups
### Docker
- [Nginx Proxy Manager](nginx_proxy_manager.md) - Easy reverse proxy config
- [Traefik](traefik.md) — Dynamic reverse proxy with automation
- [Caddy](caddy.md) — Automatic HTTPS with a clean config
- [Dev Container + WSL](dev_container_wsl.md) - Windows dev environment with WSL 2 + Dev Containers
| I want to… | Guide |
| ---------- | ----- |
| Guided install on a VPS or homelab | [Quick Start Installer](quick_start.md) |
| One container, one port, minimal config | [All-in-One Docker (AIO)](aio.md) |
| Separate frontend, backend, and database | [Standard Docker](docker.md) |
| HTTPS on a custom domain | [Reverse proxy guides](#reverse-proxy) |
### Homelab & NAS platforms
| Platform | Guide |
| -------- | ----- |
| Proxmox LXC | [Proxmox LXC](proxmox_lxc.md) |
| Synology NAS | [Synology NAS](synology_nas.md) |
| Unraid | [Unraid](unraid.md) |
| Umbrel | [Umbrel](https://apps.umbrel.com/app/adventurelog) — community app |
| TrueNAS SCALE | [TrueNAS](https://apps.truenas.com/catalog/adventurelog/) — community app |
These guides use the same AdventureLog Docker images, adapted for each platform.
### Kubernetes
| Platform | Guide |
| -------- | ----- |
| Kubernetes cluster | [Kubernetes + Kustomize](kustomize.md) |
### Development
| Use case | Guide |
| -------- | ----- |
| Local development on Windows / WSL | [Dev Container + WSL](dev_container_wsl.md) |
### Reverse proxy {#reverse-proxy}
Use these when AdventureLog sits behind HTTPS on a custom domain:
| Proxy | Guide |
| ----- | ----- |
| Nginx Proxy Manager | [Nginx Proxy Manager](nginx_proxy_manager.md) |
| Traefik | [Traefik](traefik.md) — includes `docker-compose-traefik.yaml` |
| Caddy | [Caddy](caddy.md) |
Set `SITE_URL` to your public HTTPS URL so Django CSRF and SvelteKit origins stay correct. See [Environment Variables](../configuration/environment_variables.md#url-and-networking).
## After installation
1. Log in with your admin credentials (default `admin` / `admin` — change immediately)
2. Review [How to Use AdventureLog](../usage/usage.md)
3. Configure optional features in [Configuration](../configuration/environment_variables.md)
4. Set up [backups](../configuration/operations.md#backup) before going to production
## Requirements
- Docker Engine + Docker Compose v2 (for Docker-based installs)
- **2 GB RAM** on first boot (world geography import); ~1 GB afterward
- Linux server, VPS, homelab, or macOS with Docker Desktop
- Optional: domain name and reverse proxy for HTTPS

View File

@@ -1,47 +1,48 @@
# 🚀 Quick Start Install
# Quick Start Installer
Install **AdventureLog** in seconds using our automated installer. The script defaults to the **All-in-One (AIO)** setup — one URL, one port, minimal configuration.
Install AdventureLog in seconds with the official curl installer. It defaults to the **All-in-One (AIO)** layout — one URL, one port, minimal configuration — and includes a management menu for updates and backups.
## 🧪 One-Liner Install
## One-line install
```bash
curl -sSL https://get.adventurelog.app | bash
```
This will:
## What the installer does
- Check dependencies (Docker, Docker Compose, RAM, architecture)
- Detect ARM hosts and configure a compatible PostGIS image automatically
- Set up the `./adventurelog` project directory
- Download `docker-compose.aio.yml`, `.env.aio`, and management scripts
- Walk you through core and optional configuration (S3, email, integrations, etc.)
- Start AdventureLog and wait for the health check
1. Checks dependencies (Docker, Compose v2, RAM, CPU architecture)
2. Detects ARM hosts and configures a compatible PostGIS image automatically
3. Creates the `./adventurelog` project directory (configurable via `INSTALL_DIR`)
4. Downloads `docker-compose.aio.yml` or `docker-compose.yml`, env files, and management scripts
5. Walks you through site URL, admin credentials, and optional features (S3, email, integrations)
6. Starts containers and waits for the `/health` endpoint
7. Saves credentials to `credentials.txt` when generated
## Requirements
## Requirements
- Docker + Docker Compose v2
- **2 GB RAM** recommended on first boot (world geography import); ~1 GB afterward
- Linux server, VPS, or macOS with Docker Desktop
- Optional: domain name for HTTPS (set `SITE_URL` to your public URL)
| Requirement | Details |
| ----------- | ------- |
| Docker + Compose v2 | Required |
| RAM | 2 GB recommended on first boot; ~1 GB afterward |
| OS | Linux server, VPS, or macOS with Docker Desktop |
| Domain | Optional — set `SITE_URL` for HTTPS behind a reverse proxy |
::: tip ARM / Apple Silicon
The installer automatically uses `imresamu/postgis:16-3.5-alpine` on ARM hosts. AdventureLog AIO images are multi-arch.
The installer automatically uses `imresamu/postgis:16-3.5-alpine` on ARM hosts. AdventureLog images are multi-arch.
:::
## 🔍 What It Does
## Setup modes
The script automatically:
During installation you can choose:
1. Verifies Docker is installed and running
2. Offers **All-in-One** (recommended) or **Standard** (separate frontend/backend) setup
3. Downloads compose files, `.env.aio` or `.env`, `deploy.sh`, and backup scripts
4. Prompts for site URL, admin credentials, and optional features
5. Waits for `/health` (first boot may take several minutes)
6. Saves optional credentials to `credentials.txt`
| Mode | Compose file | Env file | When to use |
| ---- | ------------ | -------- | ----------- |
| **All-in-One** (default) | `docker-compose.aio.yml` | `.env.aio` | Simplest — one port, auto-derived URLs |
| **Standard** | `docker-compose.yml` | `.env` | Full env control, separate frontend/backend ports |
## 🔄 Management (Re-run the installer)
## Management menu
Re-run the same command to open the **management menu** when an install already exists:
Re-run the installer when an install already exists:
```bash
curl -sSL https://get.adventurelog.app | bash
@@ -49,22 +50,29 @@ curl -sSL https://get.adventurelog.app | bash
bash install_adventurelog.sh --manage
```
Management options include:
Options include status, update, reconfigure, backup, restore, logs, restart, and uninstall. See [Operations & Maintenance](../configuration/operations.md).
- Check status and health
- Update to latest images (`deploy.sh --backup`)
- Edit configuration
- Backup and restore
- View logs, restart, or uninstall
## Dry run
## 🧼 Uninstall
Preview what the installer would do without making changes:
```bash
ADVENTURELOG_SKIP_GUM=1 bash install_adventurelog.sh --dry-run --force-install
```
## Uninstall
From the management menu, choose **Uninstall**, or manually:
```bash
cd adventurelog
docker compose -f docker-compose.aio.yml down -v
docker compose --env-file .env.aio -f docker-compose.aio.yml down -v
rm -rf adventurelog
```
Need more control? See [All-in-One Docker](aio.md), [Standard Docker](docker.md), or other [install options](getting_started.md).
## Next steps
- [All-in-One Docker](aio.md) — how the AIO container works
- [Standard Docker](docker.md) — multi-container configuration
- [Environment Variables](../configuration/environment_variables.md) — full reference
- [Other install options](getting_started.md)

View File

@@ -1,7 +1,51 @@
# Installation with Traefik
# Traefik Reverse Proxy
Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. It is designed to be simple to use and configure, and it integrates well with Docker.
Deploy AdventureLog behind [Traefik](https://traefik.io/) with automatic HTTPS and path-based routing using the official compose file.
AdventureLog has a built-in Traefik configuration that makes it easy to deploy and manage your AdventureLog instance.
## Official compose file
The most recent version of the Traefik `docker-compose.yml` file can be found in the [AdventureLog GitHub repository](https://github.com/seanmorley15/AdventureLog/blob/main/docker-compose-traefik.yaml).
Download [`docker-compose-traefik.yaml`](https://github.com/seanmorley15/AdventureLog/blob/main/docker-compose-traefik.yaml) from the repository. It includes:
- Traefik v2.11 with Let's Encrypt
- Prebuilt `adventurelog-frontend` and `adventurelog-backend` images (no local build required)
- Path-based routing: frontend pages on `/`, backend on `/media`, `/admin`, `/accounts`, `/static`
## Required environment variables
Add these to your `.env` alongside the standard AdventureLog variables:
| Variable | Description | Example |
| -------- | ----------- | ------- |
| `ACME_EMAIL` | Let's Encrypt registration email | `you@example.com` |
| `TRAEFIK_DOMAIN` | Public domain for the router | `adventurelog.example.com` |
| `SITE_URL` | Public HTTPS URL (derives CSRF and frontend origins) | `https://adventurelog.example.com` |
See [Environment Variables](../configuration/environment_variables.md) for the full list.
## Getting started
```bash
wget https://raw.githubusercontent.com/seanmorley15/AdventureLog/main/docker-compose-traefik.yaml
wget https://raw.githubusercontent.com/seanmorley15/AdventureLog/main/.env.example
cp .env.example .env
# Edit .env: set SITE_URL, ACME_EMAIL, TRAEFIK_DOMAIN, POSTGRES_PASSWORD, SECRET_KEY
bash scripts/validate-env.sh
docker compose -f docker-compose-traefik.yaml up -d
```
## Routing overview
Traefik routes traffic to two containers on a single domain:
| Path prefix | Service |
| ----------- | ------- |
| `/`, `/api`, `/auth`, app pages | Frontend (SvelteKit) |
| `/media`, `/admin`, `/accounts`, `/static` | Backend (Django/Gunicorn) |
This matches the internal routing model used by the [All-in-One](aio.md) container, but with separate frontend and backend services.
## Related guides
- [Standard Docker](docker.md) — base configuration without Traefik
- [Environment Variables](../configuration/environment_variables.md) — URL and CSRF settings
- [Nginx Proxy Manager](nginx_proxy_manager.md) — alternative reverse proxy

View File

@@ -1,8 +1,8 @@
# About AdventureLog
Starting from a simple idea of tracking travel locations, AdventureLog has grown into a full-fledged travel companion. With AdventureLog, you can log your adventures, keep track of where you've been on the world map, plan your next trip collaboratively, and share your experiences with friends and family. **AdventureLog is the ultimate travel companion for the modern-day explorer**.
AdventureLog is a self-hosted, open-source travel companion for tracking where you have been, planning where you are going, and sharing trips with the people you travel with.
## Features
## Core features
- **Track Your Adventures** 🌍: Log your adventures and keep track of where you've been on the world map.
- Locations can store a variety of information, including the location, date, and description.
@@ -32,4 +32,4 @@ Hi, I'm [Sean Morley](https://seanmorley.com), the creator of AdventureLog. I'm
I hope you enjoy using AdventureLog as much as I enjoy creating it! If you have any questions, feedback, or suggestions, feel free to reach out to me via the email address listed on my website. I'm always happy to hear from users and help in any way I can. Thank you for using AdventureLog, and happy travels! 🌍
If you want to check out the origins of AdventureLog and the timeline, process, and story of its development, check out the [Development Timeline](/docs/changelogs/development_timeline.md).
If you want to check out the origins of AdventureLog and the timeline, process, and story of its development, check out the [Development Timeline](../changelogs/development_timeline.md).

View File

@@ -1,8 +1,25 @@
# How to use AdventureLog
# How to Use AdventureLog
Welcome to AdventureLog! This guide will help you get started with AdventureLog and provide you with an overview of the features available to you.
Welcome to AdventureLog! This guide covers core concepts and features. For server configuration, see [Environment Variables](../configuration/environment_variables.md).
## Key Terms
## App sections
| Page | Route | Purpose |
| ---- | ----- | ------- |
| Dashboard | `/dashboard` | Travel statistics and overview |
| Locations | `/locations` | Browse, filter, and manage locations |
| Map | `/map` | Interactive world map with location pins |
| Collections | `/collections` | Trips, folders, and itineraries |
| Calendar | `/calendar` | View collections and visits by date |
| World Travel | `/worldtravel` | Countries, regions, and cities visited |
| Search | `/search` | Full-text search across your data |
| Settings | `/settings` | Profile, integrations, security, API keys |
| Invites | `/invites` | Accept invitations to private instances |
| Admin | `/admin` | Django admin panel (staff only) |
Configure integrations (Immich, Strava, Wanderer, Google Maps) and security (MFA, API keys) from **Settings**.
## Key terms
#### Locations

View File

@@ -1,306 +1,18 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
hero:
name: "AdventureLog"
text: "The ultimate travel companion."
tagline: Discover new places, track your adventures, and share your experiences with friends and family.
actions:
- theme: brand
text: Get Started
link: /docs/install/getting_started
- theme: alt
text: About
link: /docs/intro/adventurelog_overview
- theme: alt
text: Demo
link: https://demo.adventurelog.app
image:
src: ./adventurelog.svg
alt: AdventureLog Map Logo
features:
- title: "Track Your Adventures"
details: "Log your adventures and keep track of where you've been on the world map."
icon: 📍
- title: "Plan Your Next Trip"
details: "Take the guesswork out of planning your next adventure with an easy-to-use itinerary planner."
icon: 📅
- title: "Share Your Experiences"
details: "Share your adventures with friends and family and collaborate on trips together."
icon: 📸
title: AdventureLog — Self-Hosted Travel Log & Trip Planner
description: Log locations with photos and notes, plan multi-day itineraries, and track countries on an interactive world map. AdventureLog is the open-source travel companion for remembering every trip.
---
## ⚡️ Quick Start
<HomeInstall />
Get AdventureLog running in under 60 seconds:
<HomeShowcase />
```bash [One-Line Install]
curl -sSL https://get.adventurelog.app | bash
```
<HomePillars />
You can also explore our [full installation guide](/docs/install/getting_started) for plenty of options, including Docker, Proxmox, Synology NAS, and more.
<HomeSocialProof />
## 📸 See It In Action
<HomeTech />
::: details 🗂️ **Location Overview & Management**
Manage your full list of locations with ease. View upcoming and past trips, filter and sort by status, date, or category to find exactly what you want quickly.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/adventures.png" alt="Location Overview" style="max-width:100%; margin-top:10px;" />
:::
::: details 📋 **Detailed Adventure Logs**
Capture rich details for every location: name, dates, precise locations, vivid descriptions, personal ratings, photos, and customizable categories. Your memories deserve to be more than just map pins — keep them alive with full, organized logs.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/details.png" alt="Detailed Adventure Logs" style="max-width:100%; margin-top:10px;" />
:::
::: details 🗺️ **Interactive World Map**
Track every destination youve visited or plan to visit with our beautifully detailed, interactive world map. Easily filter locations by visit status — visited or planned — and add new locations by simply clicking on the map. Watch your travel story unfold visually as your journey grows.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/map.png" alt="Interactive World Map" style="max-width:100%; margin-top:10px;" />
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/map-satellite.png" alt="Interactive World Map" style="max-width:100%; margin-top:10px;" />
:::
::: details ✈️ **Comprehensive Trip Planning**
Organize your multi-day trips with detailed itineraries, including flight information, daily activities, collaborative notes, packing checklists, and handy resource links. Stay on top of your plans and ensure every adventure runs smoothly.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/itinerary.png" alt="Comprehensive Trip Planning" style="max-width:100%; margin-top:10px;" />
:::
::: details 📊 **Travel Statistics Dashboard**
Unlock insights into your travel habits and milestones through elegant, easy-to-understand analytics. Track total countries visited, regions explored, cities logged, and more. Visualize your world travels with ease and celebrate your achievements.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/dashboard.png" alt="Travel Statistics Dashboard" style="max-width:100%; margin-top:10px;" />
:::
::: details ✏️ **Edit & Customize Locations**
Make quick updates or deep customizations to any location using a clean and intuitive editing interface. Add photos, update notes, adjust dates, and more—keeping your records accurate and personal.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/edit.png" alt="Edit Location Modal" style="max-width:100%; margin-top:10px;" />
:::
::: details 🌍 **Countries & Regions Explorer**
Explore and manage the countries youve visited or plan to visit with an organized list, filtering by visit status. Dive deeper into each countrys regions, complete with interactive maps to help you visually select and track your regional travels.
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/countries.png" alt="Countries List" style="max-width:100%; margin-top:10px;" />
<img src="https://raw.githubusercontent.com/seanmorley15/AdventureLog/refs/heads/main/brand/screenshots/regions.png" alt="Regions Explorer" style="max-width:100%; margin-top:10px;" />
:::
## 💬 What People Are Saying
::: details ✈️ **XDA Travel Week Reviews**
> “I stumbled upon AdventureLog. It's an open-source, self-hosted travel planner that's completely free to use and has a bunch of cool features that make it a treat to plan, organize, and log your journey across the world. Safe to say, it's become a mainstay in Docker for me.”
>
> — _Sumukh Rao, Senior Author at XDA_
[Article Link](https://www.xda-developers.com/i-self-hosted-this-app-to-plan-itinerary-when-traveling/)
:::
::: details 🧳 **Rich Edmonds, XDA**
**Overall Ranking: #1**
> “The most important part of travelling in this socially connected world is to log everything and showcase all of your adventures. AdventureLog is aptly named, as it allows you to do just that. It just so happens to be one of the best apps for the job and can be fully self-hosted at home.”
>
> — _Rich Edmonds, Lead PC Hardware Editor at XDA_
[Article Link](https://www.xda-developers.com/these-self-hosted-apps-are-perfect-for-those-on-the-go/)
:::
::: details 📆 **Open Source Daily**
> “Your travel memories are your personal treasures—dont let them be held hostage by closed platforms, hidden fees, or privacy risks. AdventureLog represents a new era of travel tracking: open, private, comprehensive, and truly yours. Whether youre a casual traveler, digital nomad, family vacation planner, or anyone who values their adventures, AdventureLog offers a compelling alternative that puts you back in control.”
>
> — _Open Source Daily_
[Article Link](https://opensourcedaily.blog/adventurelog-private-open-source-travel-tracking-trip-planning/)
:::
::: details 📱 **Android Authority**
> "AdventureLog behaves more like a super-charged travel journal than yet another travel app.”
>
> — _Dhruv Bhutani, Android Authority_
[Article Link](https://www.androidauthority.com/self-hosted-travel-app-3572353/)
:::
## 🏗️ Built With Excellence
<div class="tech-stack">
<div class="tech-card">
### **Frontend Excellence**
- 🎨 **SvelteKit** - Lightning-fast, modern web framework
- 💨 **TailwindCSS** - Utility-first styling for beautiful designs
- 🎭 **DaisyUI** - Beautiful, accessible component library
- 🗺️ **MapLibre** - Interactive, customizable mapping
</div>
<div class="tech-card">
### **Backend Power**
- 🐍 **Django** - Robust, scalable web framework
- 🗺️ **PostGIS** - Advanced geospatial database capabilities
- 🔌 **Django REST** - Modern API architecture
- 🔐 **AllAuth** - Comprehensive authentication system
</div>
</div>
## 🌟 Join the Adventure
<div class="community-stats">
<div class="community-card">
### 🎯 **Active Development**
Regular updates, new features, and community-driven improvements keep AdventureLog at the forefront of travel technology.
</div>
<div class="community-card">
### 💬 **Thriving Community**
Join thousands of travelers sharing tips, contributing code, and building the future of travel documentation together.
</div>
<div class="community-card">
### 🚀 **Open Source Freedom**
GPL 3.0 licensed, fully transparent, and built for the community. By travelers, for travelers.
</div>
</div>
## 💖 Support the Project
AdventureLog is lovingly maintained by passionate developers and supported by amazing users like you:
- ⭐ [Star us on GitHub](https://github.com/seanmorley15/AdventureLog)
- 💬 [Join our Discord community](https://discord.gg/wRbQ9Egr8C)
- 💖 [Sponsor The Project](https://seanmorley.com/sponsor) to help us keep improving AdventureLog
- 🐛 [Report bugs & request features](https://github.com/seanmorley15/AdventureLog/issues)
---
<div class="footer-cta">
### Ready to Transform Your Travel Experience?
Stop letting amazing adventures fade from memory. Start documenting, planning, and sharing your travel story today.
[**🚀 Get Started Now**](/docs/install/getting_started) • [**📱 Try the Demo**](https://demo.adventurelog.app) • [**📚 Read the Docs**](/docs/intro/adventurelog_overview)
</div>
<style>
.why-section {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.why-card {
padding: 1.5rem;
border-radius: 12px;
border: 1px solid var(--vp-c-border);
background: var(--vp-c-bg-soft);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.why-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.why-card h3 {
margin-bottom: 0.75rem;
color: var(--vp-c-text-1);
}
.tech-stack {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.tech-card {
padding: 1.5rem;
border-radius: 12px;
border: 1px solid var(--vp-c-border);
background: var(--vp-c-bg-soft);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.tech-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.tech-card h3 {
margin-bottom: 1rem;
color: var(--vp-c-text-1);
}
.community-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.community-card {
padding: 1.5rem;
border-radius: 12px;
border: 1px solid var(--vp-c-border);
background: var(--vp-c-bg-soft);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.community-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.community-card h3 {
margin-bottom: 0.75rem;
color: var(--vp-c-text-1);
}
.footer-cta {
text-align: center;
padding: 3rem 2rem;
margin: 3rem 0;
border-radius: 12px;
background: linear-gradient(135deg, var(--vp-c-brand-soft) 0%, var(--vp-c-brand-softer) 100%);
border: 1px solid var(--vp-c-brand-soft);
}
.footer-cta h3 {
margin-bottom: 1rem;
color: var(--vp-c-brand-dark);
}
.footer-cta p {
margin-bottom: 2rem;
font-size: 1.1rem;
opacity: 0.8;
}
details img {
border-radius: 12px;
}
</style>
<HomeFinalCta />

View File

@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://adventurelog.app/sitemap.xml