move documentation/ to docs/
18
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/coverage
|
||||
/src/client/shared.ts
|
||||
/src/node/shared.ts
|
||||
*.log
|
||||
*.tgz
|
||||
.DS_Store
|
||||
.idea
|
||||
.temp
|
||||
.vite_opt_cache
|
||||
.vscode
|
||||
dist
|
||||
cache
|
||||
temp
|
||||
examples-temp
|
||||
node_modules
|
||||
pnpm-global
|
||||
TODOs.md
|
||||
*.timestamp-*.mjs
|
||||
325
docs/.vitepress/config.mts
Normal file
@@ -0,0 +1,325 @@
|
||||
import { defineConfig } from "vitepress";
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
head: [
|
||||
["link", { rel: "icon", href: "/adventurelog.png" }],
|
||||
|
||||
[
|
||||
"script",
|
||||
{
|
||||
defer: "",
|
||||
src: "https://cloud.umami.is/script.js",
|
||||
"data-website-id": "a7552764-5a1d-4fe7-80c2-5331e1a53cb6",
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
"link",
|
||||
{
|
||||
rel: "me",
|
||||
href: "https://mastodon.social/@adventurelog",
|
||||
},
|
||||
],
|
||||
],
|
||||
ignoreDeadLinks: "localhostLinks",
|
||||
title: "AdventureLog",
|
||||
description: "The ultimate travel companion.",
|
||||
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.0",
|
||||
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",
|
||||
],
|
||||
};
|
||||
|
||||
return {
|
||||
frontmatter: {
|
||||
...pageData.frontmatter,
|
||||
head: [
|
||||
["script", { type: "application/ld+json" }, JSON.stringify(jsonLd)],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
|
||||
themeConfig: {
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
nav: [
|
||||
{ text: "Home", link: "/" },
|
||||
{ text: "Docs", link: "/docs/intro/adventurelog_overview" },
|
||||
],
|
||||
search: {
|
||||
provider: "local",
|
||||
},
|
||||
editLink: {
|
||||
pattern:
|
||||
"https://github.com/seanmorley15/AdventureLog/edit/main/documentation/:path",
|
||||
},
|
||||
|
||||
footer: {
|
||||
message: "AdventureLog",
|
||||
copyright: "Copyright © 2023-2026 Sean Morley",
|
||||
},
|
||||
|
||||
logo: "/adventurelog.png",
|
||||
|
||||
sidebar: [
|
||||
{
|
||||
text: "About AdventureLog",
|
||||
items: [
|
||||
{
|
||||
text: "AdventureLog Overview",
|
||||
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: "Kubernetes and Kustomize 🌐",
|
||||
link: "/docs/install/kustomize",
|
||||
},
|
||||
{ text: "Unraid 🧡", link: "/docs/install/unraid" },
|
||||
{
|
||||
text: "Dev Container + WSL 🧰",
|
||||
link: "/docs/install/dev_container_wsl",
|
||||
},
|
||||
|
||||
{
|
||||
text: "With A Reverse Proxy",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: "Nginx Proxy Manager",
|
||||
link: "/docs/install/nginx_proxy_manager",
|
||||
},
|
||||
{ text: "Traefik", link: "/docs/install/traefik" },
|
||||
{ text: "Caddy", link: "/docs/install/caddy" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Usage",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: "How to use AdventureLog",
|
||||
link: "/docs/usage/usage",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Configuration",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: "Immich Integration",
|
||||
link: "/docs/configuration/immich_integration",
|
||||
},
|
||||
{
|
||||
text: "Google Maps Integration",
|
||||
link: "/docs/configuration/google_maps_integration",
|
||||
},
|
||||
{
|
||||
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,
|
||||
items: [
|
||||
{
|
||||
text: "Authentik",
|
||||
link: "/docs/configuration/social_auth/authentik",
|
||||
},
|
||||
{
|
||||
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",
|
||||
link: "/docs/configuration/social_auth/oidc",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Update App",
|
||||
link: "/docs/configuration/updating",
|
||||
},
|
||||
{
|
||||
text: "Disable Registration",
|
||||
link: "/docs/configuration/disable_registration",
|
||||
},
|
||||
{ text: "SMTP Email", link: "/docs/configuration/email" },
|
||||
{ text: "Umami Analytics", link: "/docs/configuration/analytics" },
|
||||
{
|
||||
text: "Advanced Configuration",
|
||||
link: "/docs/configuration/advanced_configuration",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Troubleshooting",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "No Images Displaying",
|
||||
link: "/docs/troubleshooting/no_images",
|
||||
},
|
||||
{
|
||||
text: "Login and Registration Unresponsive",
|
||||
link: "/docs/troubleshooting/login_unresponsive",
|
||||
},
|
||||
{
|
||||
text: "Failed to Start Nginx",
|
||||
link: "/docs/troubleshooting/nginx_failed",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Guides",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Travel Agent (MCP)",
|
||||
link: "/docs/guides/travel_agent",
|
||||
},
|
||||
{
|
||||
text: "Admin Panel",
|
||||
link: "/docs/guides/admin_panel",
|
||||
},
|
||||
{
|
||||
text: "Invite a User",
|
||||
link: "/docs/guides/invite_user",
|
||||
},
|
||||
{
|
||||
text: "v0.7.1 Migration Guide",
|
||||
link: "/docs/guides/v0-7-1_migration",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Changelogs",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Development Timeline",
|
||||
link: "/docs/changelogs/development_timeline",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
socialLinks: [
|
||||
{ icon: "github", link: "https://github.com/seanmorley15/AdventureLog" },
|
||||
{ icon: "discord", link: "https://discord.gg/wRbQ9Egr8C" },
|
||||
{ icon: "buymeacoffee", link: "https://buymeacoffee.com/seanmorley15" },
|
||||
{ icon: "x", link: "https://x.com/AdventureLogApp" },
|
||||
{ icon: "mastodon", link: "https://mastodon.social/@adventurelog" },
|
||||
{ icon: "instagram", link: "https://www.instagram.com/adventurelogapp" },
|
||||
],
|
||||
},
|
||||
});
|
||||
17
docs/.vitepress/theme/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// https://vitepress.dev/guide/custom-theme
|
||||
import { h } from 'vue'
|
||||
import type { Theme } from 'vitepress'
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import './style.css'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
Layout: () => {
|
||||
return h(DefaultTheme.Layout, null, {
|
||||
// https://vitepress.dev/guide/extending-default-theme#layout-slots
|
||||
})
|
||||
},
|
||||
enhanceApp({ app, router, siteData }) {
|
||||
// ...
|
||||
}
|
||||
} satisfies Theme
|
||||
138
docs/.vitepress/theme/style.css
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Customize default theme styling by overriding CSS variables:
|
||||
* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
|
||||
*/
|
||||
|
||||
/**
|
||||
* Colors
|
||||
*
|
||||
* Each colors have exact same color scale system with 3 levels of solid
|
||||
* colors with different brightness, and 1 soft color.
|
||||
*
|
||||
* - `XXX-1`: The most solid color used mainly for colored text. It must
|
||||
* satisfy the contrast ratio against when used on top of `XXX-soft`.
|
||||
*
|
||||
* - `XXX-2`: The color used mainly for hover state of the button.
|
||||
*
|
||||
* - `XXX-3`: The color for solid background, such as bg color of the button.
|
||||
* It must satisfy the contrast ratio with pure white (#ffffff) text on
|
||||
* top of it.
|
||||
*
|
||||
* - `XXX-soft`: The color used for subtle background such as custom container
|
||||
* or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
|
||||
* on top of it.
|
||||
*
|
||||
* The soft color must be semi transparent alpha channel. This is crucial
|
||||
* because it allows adding multiple "soft" colors on top of each other
|
||||
* to create a accent, such as when having inline code block inside
|
||||
* custom containers.
|
||||
*
|
||||
* - `default`: The color used purely for subtle indication without any
|
||||
* special meanings attached to it such as bg color for menu hover state.
|
||||
*
|
||||
* - `brand`: Used for primary brand colors, such as link text, button with
|
||||
* brand theme, etc.
|
||||
*
|
||||
* - `tip`: Used to indicate useful information. The default theme uses the
|
||||
* brand color for this by default.
|
||||
*
|
||||
* - `warning`: Used to indicate warning to the users. Used in custom
|
||||
* container, badges, etc.
|
||||
*
|
||||
* - `danger`: Used to show error, or dangerous message to the users. Used
|
||||
* in custom container, badges, etc.
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-c-default-1: var(--vp-c-gray-1);
|
||||
--vp-c-default-2: var(--vp-c-gray-2);
|
||||
--vp-c-default-3: var(--vp-c-gray-3);
|
||||
--vp-c-default-soft: var(--vp-c-gray-soft);
|
||||
|
||||
--vp-c-brand-1: var(--vp-c-green-1);
|
||||
--vp-c-brand-2: var(--vp-c-green-2);
|
||||
--vp-c-brand-3: var(--vp-c-green-3);
|
||||
--vp-c-brand-soft: var(--vp-c-green-soft);
|
||||
|
||||
--vp-c-tip-1: var(--vp-c-brand-1);
|
||||
--vp-c-tip-2: var(--vp-c-brand-2);
|
||||
--vp-c-tip-3: var(--vp-c-brand-3);
|
||||
--vp-c-tip-soft: var(--vp-c-brand-soft);
|
||||
|
||||
--vp-c-warning-1: var(--vp-c-yellow-1);
|
||||
--vp-c-warning-2: var(--vp-c-yellow-2);
|
||||
--vp-c-warning-3: var(--vp-c-yellow-3);
|
||||
--vp-c-warning-soft: var(--vp-c-yellow-soft);
|
||||
|
||||
--vp-c-danger-1: var(--vp-c-red-1);
|
||||
--vp-c-danger-2: var(--vp-c-red-2);
|
||||
--vp-c-danger-3: var(--vp-c-red-3);
|
||||
--vp-c-danger-soft: var(--vp-c-red-soft);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Button
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-button-brand-border: transparent;
|
||||
--vp-button-brand-text: var(--vp-c-white);
|
||||
--vp-button-brand-bg: var(--vp-c-brand-3);
|
||||
--vp-button-brand-hover-border: transparent;
|
||||
--vp-button-brand-hover-text: var(--vp-c-white);
|
||||
--vp-button-brand-hover-bg: var(--vp-c-brand-2);
|
||||
--vp-button-brand-active-border: transparent;
|
||||
--vp-button-brand-active-text: var(--vp-c-white);
|
||||
--vp-button-brand-active-bg: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Home
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-home-hero-name-color: transparent;
|
||||
--vp-home-hero-name-background: -webkit-linear-gradient(
|
||||
120deg,
|
||||
#1c913f 30%,
|
||||
#1f73f1
|
||||
);
|
||||
|
||||
--vp-home-hero-image-background-image: linear-gradient(
|
||||
-45deg,
|
||||
#1c913f 50%,
|
||||
#1f73f1 50%
|
||||
);
|
||||
--vp-home-hero-image-filter: blur(44px);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
:root {
|
||||
--vp-home-hero-image-filter: blur(56px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
:root {
|
||||
--vp-home-hero-image-filter: blur(68px);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Custom Block
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-custom-block-tip-border: transparent;
|
||||
--vp-custom-block-tip-text: var(--vp-c-text-1);
|
||||
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
|
||||
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Algolia
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
.DocSearch {
|
||||
--docsearch-primary-color: var(--vp-c-brand-1) !important;
|
||||
}
|
||||
41
docs/architecture.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Voyage Architecture
|
||||
|
||||
> **Status**: Stub — to be expanded as architecture evolves.
|
||||
|
||||
## Overview
|
||||
|
||||
Voyage is a self-hosted travel companion built with SvelteKit (frontend) and Django REST Framework (backend), deployed via Docker.
|
||||
|
||||
## Key Architectural Patterns
|
||||
|
||||
### API Proxy
|
||||
The frontend never calls Django directly. All API calls go through `src/routes/api/[...path]/+server.ts`, which proxies to the Django server, injecting CSRF tokens and managing session cookies.
|
||||
|
||||
### Services (Docker Compose)
|
||||
- `web` → SvelteKit frontend (`:8015`)
|
||||
- `server` → Django via Gunicorn + Nginx (`:8016`)
|
||||
- `db` → PostgreSQL + PostGIS (`:5432`)
|
||||
- `cache` → Memcached (internal)
|
||||
|
||||
### Authentication
|
||||
Session-based via `django-allauth`. CSRF tokens from `/auth/csrf/`, passed as `X-CSRFToken` header.
|
||||
|
||||
## Backend Apps
|
||||
- `adventures` — core domain (locations, collections, itineraries, notes, transportation, MCP)
|
||||
- `users` — user management
|
||||
- `worldtravel` — countries, regions, cities, visited tracking
|
||||
- `integrations` — external service integrations
|
||||
- `achievements` — gamification
|
||||
- `chat` — LLM chat/agent
|
||||
|
||||
## Frontend Structure
|
||||
- `src/routes/` — SvelteKit file-based routing
|
||||
- `src/lib/types.ts` — TypeScript interfaces
|
||||
- `src/lib/components/` — Svelte components by domain
|
||||
- `src/locales/` — i18n JSON files
|
||||
|
||||
## TODO
|
||||
- [ ] Data flow diagrams
|
||||
- [ ] Database schema overview
|
||||
- [ ] Deployment architecture
|
||||
- [ ] MCP endpoint architecture
|
||||
209
docs/docs/changelogs/development_timeline.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# Voyage: Development Timeline & Origin Story
|
||||
|
||||
By: Sean Morley, Founder & Lead Developer
|
||||
|
||||
This is the timeline of **how Voyage came to be, how it kept surviving my terrible early design choices, and how it slowly learned to be useful**. I wrote this as a detailed, phase-by-phase story so contributors, users, and future-me can see what decisions were made, why, and what problems we hit (and fixed) along the way.
|
||||
|
||||
> TL;DR: started as _NextVenture_, learned web dev the hard way, resurrected as _Voyage_, switched stacks twice, survived an chaotic Reddit launch, grew through community requests, and today the project is very much alive.
|
||||
|
||||
## Quick roadmap
|
||||
|
||||
- **Phase 0 — Ideation & Prototyping:** March 2023 → July 2023
|
||||
The seed. Lots of learning, lots of scrapped prototypes.
|
||||
- **Phase 1 — Voyage, SvelteKit roots:** March 2024 → July 2024
|
||||
Frontend-first, local-storage MVP, severe Docker struggles, file storage chaos, MinIO pain.
|
||||
- **Phase 2 — Django saves the day:** July 2024 → August 2024
|
||||
Backend matured quickly; REST API, Django admin, file storage sanity.
|
||||
- **Phase 3 — Definition, Community Growth, and Integrations:** Sept 2024 → June 2025
|
||||
Feature solidification, sharing, world data, Immich integration, big UX decisions.
|
||||
- **Phase 4 — Solidification & Expansion:** June 2025 → Present
|
||||
UI rebuild, rename of core concepts, activities/trails, heavy QoL and performance work.
|
||||
|
||||
## Phase 0 — Initial Ideation and Prototyping
|
||||
|
||||
**Dates:** March 2023 — July 2023
|
||||
|
||||
This phase was basically me being excited, naive, and wildly optimistic.
|
||||
|
||||
### What I planned
|
||||
|
||||
- Start as **NextVenture**: a curated list of national parks, cities, landmarks — places people check off. Simple premise, obvious joy.
|
||||
- A focus on letting users mark where they've been, build a list of places to visit, and keep a little travel log.
|
||||
|
||||
### What actually happened
|
||||
|
||||
- I was learning the **React / Node / Express** (MERN) stack on the fly. Every problem felt like a mountain and every mountain required rewriting whole parts of the codebase once I learned better practices (it was not that enjoyable to be honest).
|
||||
- I produced multiple small prototypes, each progressively less terrible than the last. Progress! But also lots of “why did I do that” moments.
|
||||
- Burnout + humility set in: I needed a break to learn fundamentals rather than pile band-aids on a shaky codebase (yeah I didn't really learn a lot during that break either, but at least I wasn't actively writing bad code).
|
||||
|
||||
### Small but important pivots
|
||||
|
||||
- While on break I renamed the project to **Voyage** — it felt better, cleaner, and more fitting than the working title.
|
||||
- I played with tiny experiments, tested UI ideas, and tried different stacks mentally so the next attempt wouldn’t be purely guesswork. I was very intrested in the project just lacking the right technical foundation.
|
||||
|
||||
### Takeaway
|
||||
|
||||
Phase 0 was less about shipping and more about surviving the learning curve. The project’s DNA (places, visits, memories) was clear; I just needed the right tools and patience to implement it.
|
||||
|
||||
## Phase 1 — Initial Development of Voyage (SvelteKit era)
|
||||
|
||||
**Dates:** March 2024 — July 2024
|
||||
**Versions:** v0.1.0-alpha → v0.3.1
|
||||
|
||||
This was the “frontend-first, learn-by-doing” era. SvelteKit won me because it’s delightful to write and let me prototype fast. I still use SvelteKit for the frontend today and love it.
|
||||
|
||||
### Core progress
|
||||
|
||||
- Built a single-page app MVP where adventures were stored in **localStorage**. Simple, demoable, and enough to prove the concept.
|
||||
- Learned SvelteKit app structure, routing, and how to think in reactive UI.
|
||||
|
||||
### Auth and backend beginnings
|
||||
|
||||
- Implemented authentication with **Lucia** so users could create accounts and persist data beyond local storage. That transition felt like leveling up.
|
||||
- Switched from local-only to a backend API using **SvelteKit’s API routes** to centralize storage and multi-device access.
|
||||
|
||||
### Deployment & DevOps pain
|
||||
|
||||
- Began containerizing everything: Dockerfiles (frontend & backend), `docker-compose`, and env variables. Took days of hair-pulling but I got a reliably deployable container. Victory was greatly needed at this point.
|
||||
- File uploads became a major sticking point: SvelteKit had no baked-in file handling story. I experimented with a self-hosted S3-compatible solution — **MinIO**. It worked, but felt hacky: extra moving parts, weird integration edges, and a general “this isn’t elegant” feeling. I pretty much knew at this point I was walking down a dead-end path...
|
||||
|
||||
### Major decision to pivot
|
||||
|
||||
- The MinIO + SvelteKit upload situation (and the need for a more robust API/admin story) made me decide to **rewrite the backend in Django**. I started the backend from scratch with a fresh project layout and a clearer architecture plan. This felt like ripping off a bandage: painful but necessary.
|
||||
|
||||
### Lessons learned
|
||||
|
||||
- Rapid frontend iteration is fantastic for shaping UX, but for persistent data and file handling, I needed a backend that provided batteries-included features (auth, file storage, admin) — enter Django.
|
||||
|
||||
## Phase 2 — Django Backend & Early Stability
|
||||
|
||||
**Dates:** July 2024 — August 2024
|
||||
**Versions:** v0.4.0 → v0.6.0
|
||||
|
||||
After the SvelteKit experiment I rewired the backend into Django + Django REST Framework. This phase is where the project matured technically in a big way.
|
||||
|
||||
### Why Django?
|
||||
|
||||
- **Django’s admin**, built-in auth, and mature file handling made life dramatically easier. I could iterate on the API fast and manage the DB through a UI when debugging or testing. Django REST Framework allowed a clean separation between API and frontend.
|
||||
|
||||
### What changed (notably)
|
||||
|
||||
- Reused frontend SvelteKit components where possible, but the API endpoints were completely reworked to talk to Django.
|
||||
- Switched file uploads from MinIO to Django’s file storage on the server filesystem — simpler and, honestly, a relief.
|
||||
- Introduced **collections**, **lodgings**, **notes**, **checklists** — broadening the scope beyond “just places” into trip planning and trip context. (Restaurants were later pruned and replaced with transportation models for better clarity.)
|
||||
|
||||
### Stability and schema work
|
||||
|
||||
- One big database change (v0.5.1): I switched primary keys to **UUIDs** instead of auto-incrementing integers. That was scary but intentional: UUIDs make merging and scaling safer later on. Happily, it was done early — before many users existed — which avoided painful migrations later.
|
||||
|
||||
### Community & launch
|
||||
|
||||
- I drafted a release post for r/selfhosted and decided to ship _before_ college started. On **August 15, 2024** I posted it, and it blew up more than I dared hope: **~400 upvotes, 180+ comments**, and a surge of installs and conversations. The repo got a large influx of attention and traffic, the kind of validation that keeps a project alive through times of doubt.
|
||||
|
||||
### Immediate aftermath
|
||||
|
||||
- I spent the next week triaging issues, helping users deploy, and shipping fixes. It was a stressful but extremely educational crunch while simultaneously moving to college. That crunch was intense, but it was also the moment I learned how real user feedback shapes a project’s priorities.
|
||||
|
||||
### Takeaway
|
||||
|
||||
Switching to Django was the right move, it reduced friction, sped up backend feature development, and made the application more maintainable.
|
||||
|
||||
## Phase 3 — Defining Voyage & Community-Guided Growth
|
||||
|
||||
**Dates:** September 2024 — June 2025
|
||||
**Versions:** v0.7.0 → v0.10.0
|
||||
|
||||
This phase is about defining the product: what is Voyage, what is it not, and how do we make it useful for other people?
|
||||
|
||||
### Core feature evolution
|
||||
|
||||
- **Multiple visits per location:** Users wanted to track repeat trips to the same place. Adding visit history became central to the data model.
|
||||
- **Collection sharing & permissions:** Collections could be shared with other accounts for collaborative trip planning, implementing the permission logic here was fiddly and involved a lot of debugging. But once it worked, collaboration felt genuinely useful.
|
||||
- **World travel data:** Initially we were manually entering countries and regions. A generous contributor pointed to a JSON dataset with countries/regions/cities - integrating that made world travel features robust and maintainable. (City support came later.)
|
||||
- **Categories & tags:** After debating categories vs tags, we leaned into categories as the primary organizational mechanism (with tags available as flexible metadata). Later, custom categories were added so users could create their own classification schemes.
|
||||
|
||||
### UX polish & identity
|
||||
|
||||
- Logo: I swapped out the placeholder Windows map emoji for a proper logo designed by a friend (thanks, Jacob!). It made the app look more “real” and brandable.
|
||||
- Localization: Frontend got translations to make Voyage accessible to more users.
|
||||
- Calendar view: added a calendar to visualize trips over time, another highly requested feature.
|
||||
|
||||
### Integrations & polish
|
||||
|
||||
- **Immich integration** (huge win): Sync photos from Immich to Voyage adventures. This solved the “where do my travel photos live?” problem for many self-hosters and reduced friction for users who already had an Immich instance.
|
||||
- **Backend optimizations:** performance tweaks, PWA support, OIDC support for enterprise-friendly auth, and other server configurability options.
|
||||
|
||||
### Community milestones
|
||||
|
||||
- Docker image downloads crossed **100K** — a concrete, surreal milestone. GitHub stars crossed **1K** shortly after. These numbers matter because they mean people are using and relying on Voyage.
|
||||
- Collections received “smart recommendations” — algorithmic suggestions for new locations to add to a collection based on existing entries. This added a bit of discovery and delight.
|
||||
|
||||
### Ops & deployment improvements
|
||||
|
||||
- Simplified deployment by removing an extra Nginx container. Instead the backend serves media via an internal Nginx proxy. Fewer containers made deployment easier for hobbyist hosts.
|
||||
|
||||
### Takeaway
|
||||
|
||||
Phase 3 is where Voyage stopped being “my little project” and started becoming a community-shaped tool. The roadmap was heavily guided by user requests, and that made the app both more useful and more fun to build.
|
||||
|
||||
## Phase 4 — Solidification & Expansion of the Core Platform
|
||||
|
||||
**Dates:** June 2025 — Present
|
||||
**Versions:** v0.11.0 → Present
|
||||
|
||||
Now the project focuses on _polish, robustness, and expanding the core platform_ rather than constantly changing directions.
|
||||
|
||||
### Primary themes
|
||||
|
||||
- **Solidifying core UX**: a major UI rebuild to improve accessibility, usability, and cohesion. The goal was not only to look nicer but to make features easier to discover and use.
|
||||
- **Expanding travel tracking & trip planning**: deeper integrations, better activity support, and more ways to view and interact with your travel history.
|
||||
|
||||
### Notable changes & features
|
||||
|
||||
- **Rename: “adventures” → “locations”**: This semantic pivot helped clarify the data model. A _location_ is a place that can have multiple _visits_; collections are groups of locations for trip planning. The rename reduced user confusion and aligned the product to real-world mental models.
|
||||
- **Activities & Trails**:
|
||||
- Activities: connect visits to activity providers (e.g., Strava imports) so users can show what they did at a location — not just that they were there.
|
||||
- Trails: link trail data either via a URL or by integrating with self-hosted platforms (like Wanderer). This enriches the outdoor-adventure use case.
|
||||
- **File attachments & broader media options:** allow PDFs and other travel documents to be attached to locations/visits.
|
||||
- **Server configurability & geocoding:** more options for self-hosted operators, plus an optional Google Maps integration for geocoding.
|
||||
- **New Itineraries**: a reimagined trip planning experience that focuses on day-by-day plans rather than just collections of locations. Uses a drag-and-drop interface for easy itinerary building.
|
||||
|
||||
### Ongoing priorities
|
||||
|
||||
- Performance tuning and bug fixes continue to be the top priority — the fewer regressions, the more people trust the app.
|
||||
- Accessibility improvements, better testing, and expanding integrations in a way that doesn’t bloat the core experience.
|
||||
|
||||
### Major community milestones
|
||||
|
||||
- Docker image downloads crossed **1 Million** — a huge milestone that reflects sustained interest and usage.
|
||||
|
||||
### Takeaway
|
||||
|
||||
This phase is about turning Voyage from “a promising tool” into “a dependable tool.” It’s less about big rewrites and more about incremental, meaningful improvements.
|
||||
|
||||
## Lessons, patterns, and a few thoughts
|
||||
|
||||
1. **Pick the right tool for the job**
|
||||
- The SvelteKit prototype phase taught me how fast UI iteration can progress. The Django rewrite taught me you can’t ignore backend primitives (auth, file handling, admin) if you want to ship a stable self-hosted app. Each stack had strengths, use them where they matter.
|
||||
|
||||
2. **Community feedback is gold**
|
||||
- The Reddit launch pushed the project into real usage. Responding to issues and user requests shaped core features more than any design doc ever could.
|
||||
|
||||
3. **Keep breaking changes reasonable**
|
||||
- UUIDs as primary keys were scary, but doing it early saved headaches. Plan big breaking changes early; avoid them once people rely on your software.
|
||||
|
||||
4. **Simplicity wins in deployment**
|
||||
- Removing extra containers and simplifying deployment options made Voyage more approachable for hobbyist hosts — which is the core audience.
|
||||
|
||||
5. **Iterate visibly**
|
||||
- Small, visible wins (better login flow, calendar, Immich sync) build momentum and community trust.
|
||||
|
||||
## Current state & what’s next
|
||||
|
||||
Voyage is alive, maintained, and focused on being the best self-hosted travel app it can be: accessible, performant, and useful for trip planning and personal travel history.
|
||||
|
||||
Writing this made me realize how much of Voyage’s identity came from mistakes, feedback, and stubbornness. It’s the result of learning, throwing away things that didn’t work, embracing tools that did, and listening to people who actually used it. I’m proud of how it’s evolved and excited for the next phase.
|
||||
|
||||
If you made it this far: thanks. If you want to help — issues, PRs, ideas, or design feedback are always welcome. The project is alive because of an amazing community of users and contributors!
|
||||
|
||||
— Sean
|
||||
121
docs/docs/changelogs/v0-10-0.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Voyage v0.10.0 - Trip Maps, Google Maps Integration & Quick Deploy Script
|
||||
|
||||
Released 06-10-2025
|
||||
|
||||
Hi everyone,
|
||||
|
||||
I’m pleased to share **Voyage v0.10.0**, a focused update that brings timezone-aware planning, smoother maps, and simpler deployment. This release refines many of the core features you’ve been using and addresses feedback from the community. Thank you for your contributions, suggestions, and ongoing support!
|
||||
|
||||
## 🧭 Time-Aware Travel Planning
|
||||
|
||||
**Timezone-Aware Visits & Timeline Logic**
|
||||
|
||||
- Exact start/end times with timezones for each visit, so your itinerary matches when and where events actually happen.
|
||||
- Collections now auto-order by date, giving your timeline a clear, chronological flow.
|
||||
- Lodging and transportation entries follow the same rules, making multi-city trips easier to visualize.
|
||||
- A chronologically accurate map and timeline view shows your adventure in the right order.
|
||||
|
||||
## 🗺️ Smart Mapping & Location Tools
|
||||
|
||||
**Google Maps Integration (Optional)**
|
||||
|
||||
- Autocomplete-powered location search (via Google Maps) for faster, more accurate entries.
|
||||
- Automatic geocoding ties new or updated adventures to the correct country, region, and city.
|
||||
- Improved map performance and cleaner markers throughout the app.
|
||||
|
||||
**Map Interaction Enhancements**
|
||||
|
||||
- Open any adventure location in Apple Maps, Google Maps, or OpenStreetMap with one click.
|
||||
- Full-width maps on mobile devices for better visibility.
|
||||
- Tidied-up markers and updated category icons for clarity.
|
||||
|
||||
## 🎨 UI & UX Refinements
|
||||
|
||||
- Updated adventure forms with clearer labels and streamlined inputs.
|
||||
- Smoother page transitions and consistent layouts on desktop and mobile.
|
||||
- Design and spacing adjustments for a more balanced, polished appearance.
|
||||
- Various bug fixes to address layout quirks and improve overall usability.
|
||||
|
||||
## 🌍 Localization & Navigation
|
||||
|
||||
- Expanded language support and updated locale files.
|
||||
- Improved back/forward navigation so you don’t lose your place when browsing collections.
|
||||
- Responsive collection cards that adapt to different screen sizes.
|
||||
- Fixed minor layout issues related to collections and navigation.
|
||||
|
||||
## 📷 Immich Integration Upgrades
|
||||
|
||||
- Choose whether to copy Immich images into Voyage storage or reference them via URL to avoid duplicating files.
|
||||
- Toggle “Copy Images” on or off to manage storage preferences.
|
||||
- Updated logic to prevent duplicate image uploads when using Immich.
|
||||
|
||||
## ⚙️ DevOps & Backend Enhancements
|
||||
|
||||
- Switched to `supervisord` in Docker for reliable container startup and centralized logging.
|
||||
- Restored IPv6 support for dual-stack deployments.
|
||||
- Upgraded to Node.js v22 for better performance and compatibility.
|
||||
- Added more tests, improved UTC-aware date validation, and refined ID generation.
|
||||
- Optimized database migrations for smoother updates.
|
||||
|
||||
## 📘 Documentation & Community Resources
|
||||
|
||||
- New guide for deploying with Caddy web server, covering TLS setup and reverse proxy configuration.
|
||||
- Updated instructions for Google Maps integration, including API key setup and troubleshooting.
|
||||
- Follow our Mastodon profile at [@voyage@mastodon.social](https://mastodon.social/@voyage) for updates and discussion.
|
||||
- Chat with other users on our [Discord server](https://discord.gg/wRbQ9Egr8C) to share feedback, ask questions, or swap travel tips.
|
||||
|
||||
## ✨ NEW: Quick Deploy Script
|
||||
|
||||
Based on community feedback, we’ve added a simple deployment script:
|
||||
|
||||
1. Run:
|
||||
|
||||
```bash
|
||||
curl -sSL https://get.voyage.app | bash
|
||||
```
|
||||
|
||||
2. Provide your domain/ip details when prompted.
|
||||
The script handles Docker Compose, and environment configuration automatically.
|
||||
|
||||
Self-hosting just got a bit easier—no more manual setup steps.
|
||||
|
||||
## ℹ️ Additional Notes
|
||||
|
||||
- **Bulk Geocoding**
|
||||
To geocode existing adventures in one go docker exec into the backend container and run:
|
||||
|
||||
```
|
||||
python manage.py bulk-adventure-geocode
|
||||
```
|
||||
|
||||
This will link all adventures to their correct country, region, and city.
|
||||
|
||||
- **Timezone Migrations**
|
||||
If you have older trips without explicit timezones, simply view a trip’s detail page and Voyage will auto-convert the dates.
|
||||
|
||||
## 👥 Thanks to Our Contributors
|
||||
|
||||
Your pull requests, issue reports, and ongoing feedback have been instrumental. Special thanks to:
|
||||
|
||||
- @ClumsyAdmin
|
||||
- @eidsheim98
|
||||
- @andreatitolo
|
||||
- @lesensei
|
||||
- @theshaun
|
||||
- @lkiesow
|
||||
- @larsl-net
|
||||
- @marcschumacher
|
||||
|
||||
Every contribution helps make Voyage more reliable and user-friendly.
|
||||
|
||||
## 💖 Support the Project
|
||||
|
||||
If you find Voyage helpful, consider sponsoring me! Your support keeps this project going:
|
||||
|
||||
📖 [View the Full Changelog on GitHub](https://github.com/Alex-Wiesner/voyage/compare/v0.9.0...v0.10.0)
|
||||
|
||||
Thanks for being part of the Voyage community. I appreciate your feedback and look forward to seeing where your next journey takes you!
|
||||
|
||||
Happy travels,
|
||||
**Sean Morley** (@seanmorley15)
|
||||
Project Lead, Voyage
|
||||
116
docs/docs/changelogs/v0-11-0.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Voyage v0.11.0 - Strava + Wanderer Integration, New UI, and More
|
||||
|
||||
Released 09-02-2025
|
||||
|
||||
Hi everyone,
|
||||
|
||||
I’m thrilled to announce **Voyage v0.11.0** - a huge update that **completely reimagines how you track and plan your adventures**. Adventures are now officially called **Locations**, and you can enrich them with **Activities** and **Trails**, whether added manually or imported via Strava and Wanderer.
|
||||
|
||||
On top of that, the app has a **full UI rewrite** with a cleaner, smoother interface, enhanced navigation, and improved mobile experience. Combined with expanded localization, this release gives you more ways than ever to explore, manage, and relive your journeys.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Localization & Translations
|
||||
|
||||
- Full updates to `ru.json` (Russian) and other languages (`es.json`, `nl.json`, `sv.json`, `zh.json`, `pt-BR.json`).
|
||||
- Added translations for new features: collections, activities, invites, Strava/Wanderer integrations, attachments, lodging, and transportation.
|
||||
- Localized all UI elements, buttons, navigation labels, and stats-related messages.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 UI & UX Enhancements
|
||||
|
||||
- **Fresh look and feel!** Navigation, modals, dashboards, and profile pages have been revamped for better style, clarity, and responsiveness.
|
||||
|
||||
- Enhanced mobile usability and accessibility for dropdowns, forms, and modals.
|
||||
- Updated inspirational quotes, background images, and login/signup visual effects.
|
||||
- New map view styles such as satellite and 3D terrain views are now available.
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Collections & Locations
|
||||
|
||||
- Adventures are now called **Locations** throughout the app.
|
||||
- Collections now use **invites**: send, accept, and manage shared access easily.
|
||||
- Manage collections more efficiently: sorting, filtering, linked collections, and quick start instructions.
|
||||
- Added **CollectionAllView** for a unified view across all collections.
|
||||
- Import and export options are available in settings to keep your data safe.
|
||||
|
||||
- Added attachment and image support for transportation and lodging entries.
|
||||
|
||||
---
|
||||
|
||||
## 🏃 Activities, Trails & Stats
|
||||
|
||||
- **Activities are new!** You can add them manually or import from Strava to track your trips, see them on the map, and get detailed stats.
|
||||
- **Trails are new!** Add them to Locations manually or link from Wanderer to enrich your adventure data for hiking trips.
|
||||
- Activity stats include distance, moving time, elevation, and category breakdowns.
|
||||
- Trails and activities support geoJSON and GPX for maps and integration with Wanderer/Strava.
|
||||
- All activities and visits respect **timezones** and allow **metric/imperial units** which can be changed in user settings.
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Integrations
|
||||
|
||||
- [Strava](https://strava.com) and [Wanderer](https://github.com/Flomp/wanderer) integrations for importing activities and trails.
|
||||
- Improved OAuth flows and token handling for smoother setup.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Backend & API
|
||||
|
||||
- Refined API endpoints for Locations, Activities, Trails, Visits, and Collections.
|
||||
- Enhanced permissions, ownership checks, and validations.
|
||||
- Models and serializers updated to support Activities, Trails, and attachments.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ DevOps & Workflow
|
||||
|
||||
- Updated GitHub Actions for backend/frontend testing, Docker builds, and security scans.
|
||||
- Docker builds now use BuildKit cache for faster builds.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Miscellaneous
|
||||
|
||||
- Fixed date formatting and all-day event handling for lodging and transportation.
|
||||
- Markdown rendering for event descriptions.
|
||||
- UI components refactored for clarity, usability, and improved localization.
|
||||
|
||||
---
|
||||
|
||||
## 👥 Thanks to Our Contributors
|
||||
|
||||
Special thanks to:
|
||||
|
||||
- @ShalunBdk
|
||||
- @jlcs-es
|
||||
- @DesarrolloAntonio
|
||||
- @Ycer0n
|
||||
- @taninme
|
||||
- @blitzdose
|
||||
- @fahmed1
|
||||
- @nordtektiger
|
||||
- @pplulee
|
||||
- @cathelijne
|
||||
- @mrekin
|
||||
|
||||
Every contribution makes Voyage more user-friendly and reliable.
|
||||
|
||||
---
|
||||
|
||||
## 💖 Support the Project
|
||||
|
||||
If you enjoy Voyage, consider sponsoring the project:
|
||||
|
||||
|
||||
---
|
||||
|
||||
📖 [Full Changelog on GitHub](https://github.com/Alex-Wiesner/voyage/compare/v0.10.0...v0.11.0)
|
||||
|
||||
Thanks for being part of the Voyage community!
|
||||
|
||||
Happy travels,
|
||||
**Sean Morley** (@seanmorley15)
|
||||
Project Lead, Voyage
|
||||
137
docs/docs/changelogs/v0-12-0.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Voyage v0.12.0 - Trip Planning Improvements, Itineraries & Budgets
|
||||
|
||||
Released 02-03-2026
|
||||
|
||||
Hi everyone 👋
|
||||
|
||||
I’m excited to announce **Voyage v0.12.0**, one of the **largest and most transformative updates** since the project began. This release takes Voyage beyond logging and into **true trip planning**, with a fully redesigned itinerary experience, smarter recommendations, budgeting tools, and major authentication improvements. The theme of this update is: **Planning, Itineraries & Smarter Trips**.
|
||||
|
||||
This update lays the foundation for **end-to-end trip planning** — from ideas, to routes, to schedules, to costs — all while continuing to strengthen self-hosted and privacy-respecting workflows.
|
||||
|
||||
## 🗺️ Planning, Itineraries & Trips (Major Upgrade)
|
||||
|
||||
- **Completely redesigned itinerary system**
|
||||
- Drag & drop places directly into itineraries
|
||||
- Reorder itinerary items freely
|
||||
- Add locations from map pins
|
||||
- More full detail views for lodgings and transportations
|
||||
- **Day-aware planning**
|
||||
- Day of week shown throughout the collection and itinerary views
|
||||
- Improved schedule management for multi-day trips
|
||||
- **Notes & Checklists**
|
||||
- Global items slot for trip-wide checklists and notes
|
||||
- Checklist items can be viewed and ticked directly from the itinerary
|
||||
- **Map-driven planning**
|
||||
- Search for places directly on map views
|
||||
- Filters for trip maps
|
||||
- Selectable map styles and configurable default zoom
|
||||
- Improved city, region, and country detection
|
||||
|
||||
## 🧭 Collections & UI Redesign
|
||||
|
||||
- **Collection UI redesign** for clarity, spacing, and scalability
|
||||
- Statuses / labels for collections
|
||||
- Primary photo selection for collections
|
||||
- Shared collections now correctly appear in owned views
|
||||
- Collection layout and sizing improvements across desktop and mobile
|
||||
- Collection link is shown immediately when sharing is enabled
|
||||
- “Visited” score is automatically hidden when trip dates are set
|
||||
|
||||
## 🧠 Recommendations & Smart Logic
|
||||
|
||||
- New **recommendation toggles** to better control suggestion behavior
|
||||
- Improved city detection and location lookups
|
||||
- Recommendation logic refined for accuracy and relevance
|
||||
|
||||
## 🚗 Transportation, Routes & GPX
|
||||
|
||||
- Upload **GPX files** to transportation entries
|
||||
- GPX distance is now used automatically when available
|
||||
- Improved transportation cards with clearer information display
|
||||
- Location lookups now work correctly with transportation entries
|
||||
- Price and cost fields added to transportation items
|
||||
- Immich integration for transportation and lodging images
|
||||
|
||||
## 💸 Budgets, Costs & Currency (New!)
|
||||
|
||||
- **Trip budget functionality**
|
||||
- Cost fields added to:
|
||||
- Locations
|
||||
- Transportations
|
||||
- Lodgings
|
||||
- Currency units and default currency setting
|
||||
- Prices now display consistently across trip views
|
||||
|
||||
## 🔐 Authentication & OIDC (Expanded)
|
||||
|
||||
- Automatic redirect to OIDC provider
|
||||
- Allow registration **only via auth provider** when local registration is disabled
|
||||
- Email-based auto-linking for OIDC accounts
|
||||
- Explicit support for OIDC user registration
|
||||
- Smoother and more predictable authentication flows overall
|
||||
|
||||
## 🌍 Timezones, Dates & Calendars
|
||||
|
||||
- Fixed itinerary times resetting on refresh
|
||||
- Calendar entries now respect:
|
||||
- User timezone
|
||||
- Location timezone
|
||||
- Safari-specific fixes for categories and new-location flows
|
||||
- Improved timezone selection UI and logic
|
||||
|
||||
## 📦 Backup, Uploads & Data Safety
|
||||
|
||||
- Itinerary items are now included in backup & restore
|
||||
- Fixed world travel country statistics not updating correctly
|
||||
|
||||
## 🐛 Bug Fixes & Polishing
|
||||
|
||||
- Apple touch icon resolution issue fixed
|
||||
- Itinerary badge text wrapping fixed
|
||||
- Editing locations no longer incorrectly converts them to personal
|
||||
- City → region → country relationships now update immediately
|
||||
- “Generate Description” no longer returns invalid fallback text
|
||||
- Numerous UI, cache, and rendering fixes across WebUI
|
||||
|
||||
## 🙌 Huge Thanks to the Community
|
||||
|
||||
This release was shaped by an incredible amount of feedback, ideas, testing, and code contributions from the community. Thank you to everyone who opened issues, reviewed changes, tested builds, and helped refine this massive update.
|
||||
|
||||
### 💻 Code Contributors
|
||||
|
||||
A special thank you to the developers who directly contributed code to this release:
|
||||
|
||||
- @eidsheim98
|
||||
- @Garciasergio
|
||||
- @fantastron27
|
||||
- @vorbeiei
|
||||
- @pplulee
|
||||
- @DuckyCB
|
||||
- @l3n0w0
|
||||
- @nordtektiger
|
||||
- @Alchez
|
||||
- @orhunavcu
|
||||
- @maksim2005UKR
|
||||
- @petrekanics
|
||||
- @kirby0025
|
||||
- @agarthand
|
||||
- @thefeltro
|
||||
- @sillevl
|
||||
- @larsl-net
|
||||
- @fullstack-nick
|
||||
- @madmp87
|
||||
|
||||
Your contributions — whether large features, small fixes, documentation improvements, or refactors — directly improve Voyage for everyone. Thank you for being part of the project!
|
||||
|
||||
## 💖 Support the Project
|
||||
|
||||
If Voyage helps you plan, remember, or relive your travels, consider supporting the project:
|
||||
|
||||
📖 **Full Changelog:**
|
||||
https://github.com/Alex-Wiesner/voyage/compare/v0.11.0...v0.12.0
|
||||
|
||||
Happy planning & happy travels!
|
||||
|
||||
**Sean Morley** (@seanmorley15)
|
||||
|
||||
Founder & Project Lead
|
||||
49
docs/docs/changelogs/v0-7-0.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Voyage v0.7.0
|
||||
|
||||
Released 10-15-2024
|
||||
|
||||
Hi everyone! I am super excited to announce Voyage v0.7.0! This is one of the biggest updates I have ever released and I am super happy its finally ready for all of you to enjoy. The majority of this update is based around community feedback and ideas which is awesome!
|
||||
|
||||
# What's New
|
||||
|
||||
### Adventures 📍
|
||||
|
||||
- Adventures can now be visited multiple times by adding a new visit.
|
||||
- Existing adventure dates will be automatically migrated to this new format
|
||||
- Adventures now use categories for organization.
|
||||
- A new adventure creation/edit modal simplifies the process and has a cleaner overall design with dropdown menus.
|
||||
|
||||
### Collections 🍱
|
||||
|
||||
- **Collections can now be shared with other public users for collaboration!**
|
||||
- Collections now have a link field so you can attach things like photo albums right to your collection.
|
||||
|
||||
### World Travel 🗺️
|
||||
|
||||
- The World Travel dataset now includes **every ISO defined country and region**. It is based off of a new dataset [dr5hn/countries-states-cities-database](https://github.com/dr5hn/countries-states-cities-database). Searching for countries is now supported. Capitals and world regions are now listed on the country card.
|
||||
|
||||
### Profiles 👥
|
||||
|
||||
- Users can now toggle their profile to be public. This allows other users to share collections with them for collaboration.
|
||||
|
||||
### Bug Fixes 🐛
|
||||
|
||||
- Fixed bug where collection dates during daylight savings time would cause errors in date placement
|
||||
- Fixed login issue with usernames of different cases
|
||||
|
||||
### Other
|
||||
|
||||
- New logo for Voyage! Thanks @redtechtiger!
|
||||
- Releases now include a multi-arch image like pushes to main
|
||||
- Docker compose file now has more comments for clarity
|
||||
- New Aesthetic Dark theme (its my favorite by far)
|
||||
|
||||
# Sponsorship 💖
|
||||
|
||||
As a computer science student, I pour my free time into developing and enhancing Voyage, driven by my passion for this project and its potential to make adventure planning easier for everyone. Your support, no matter the amount, means the world to me. It shows that you believe in the project and its future. I’m excited to announce that I’ve launched my page on Buy Me A Coffee—check it out!
|
||||
|
||||
Hope you all enjoy!
|
||||
Feel free to join the release discussion below to share feedback and ideas or anything else related to this update!
|
||||
|
||||
Happy travels,
|
||||
Sean @seanmorley15
|
||||
58
docs/docs/changelogs/v0-7-1.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Voyage v0.7.1
|
||||
|
||||
Released 11-13-2024
|
||||
|
||||
Hi everyone! I am super excited to announce the release of Voyage v0.7.1. This update includes a lot of improvements that make using Voyage more enjoyable and accessible. This update is largely community driven as it addresses more than 10 enhancement requests (thanks everyone!).
|
||||
|
||||
# What's New ✨
|
||||
|
||||
### Docker Compose Change 🐋
|
||||
|
||||
> [!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.voyage.app/docs/Guides/nginx_migration
|
||||
|
||||
- Migrated nginx inside of server container for easier deployment, removed external nginx requirement
|
||||
- App now uses gunicorn for better performance at scale
|
||||
|
||||
### Adventures 📍
|
||||
|
||||
- Adventures can now be sorted by visit status (visited or planned) on the adventures screen.
|
||||
- The Adventure create/edit modal now supports reverse geocoding locations. This means that for most places, the location field will be auto filled when you click on the map. It now has a popup of the associated world travel region and allows you to mark the region as visited if its not already. This makes it easier to track your world region visits!
|
||||
- The adventure map now shows previews of images and has the emoji of the category on the map pin!
|
||||
- In settings, you can perform a visited region check. This will scan all of your visited adventures and mark the associated world travel region as visited if its detected in the adventure. This serves as a bulk operation for for existing adventures.
|
||||
|
||||
### World Travel 🗺️
|
||||
|
||||
- World travel regions can now be sorted by world regions and visit status. The statuses are fully visited, partially visited, and not visited.
|
||||
|
||||
### Bug Fixes 🐛
|
||||
|
||||
- Fixed a bug where sorting by date would return to home screen
|
||||
|
||||
### Localization 🌐
|
||||
|
||||
- Migrated app to a localization framework
|
||||
- Added toggle for languages on the `...` menu in the top right.
|
||||
- **Supported Languages**: English, Spanish, French, German, Italian, Chinese, Dutch, Swedish
|
||||
|
||||
### Other
|
||||
|
||||
- New login and signup screen featuring adventures from community members (submitted in discord server).
|
||||
|
||||
## What's Next ⏭️
|
||||
|
||||
- Custom categories for adventures
|
||||
- Ability to link adventures to multiple collections
|
||||
- MFA and ODIC auth
|
||||
- Immich integration
|
||||
|
||||
# Sponsorship 💖
|
||||
|
||||
As a computer science student, I pour my free time into developing and enhancing Voyage, driven by my passion for this project and its potential to make adventure planning easier for everyone. Your support, no matter the amount, means the world to me. It shows that you believe in the project and its future. I’m excited to announce that I’ve launched my page on Buy Me A Coffee—check it out!
|
||||
|
||||
Hope you all enjoy!
|
||||
Feel free to join the release discussion below to share feedback and ideas or anything else related to this update!
|
||||
|
||||
Happy travels,
|
||||
Sean @seanmorley15
|
||||
104
docs/docs/changelogs/v0-8-0.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Voyage v0.8.0 - Immich Integration, Calendar and Customization
|
||||
|
||||
Released 01-08-2025
|
||||
|
||||
Hi everyone! 🚀
|
||||
I’m thrilled to announce the release of **Voyage v0.8.0**, a huge update packed with new features, improvements, and enhancements. This release focuses on delivering a better user experience, improved functionality, and expanded customization options. Let’s dive into what’s new!
|
||||
|
||||
---
|
||||
|
||||
## What's New ✨
|
||||
|
||||
### Immich Integration
|
||||
|
||||
- Voyage now integrates seamlessly with [Immich](https://github.com/immich-app), the amazing self-hostable photo library.
|
||||
- Import your photos from Immich directly into Voyage adventures and collections.
|
||||
- Use Immich Smart Search to search images to import based on natural queries.
|
||||
- Sort by photo album to easily import your trips photos to an adventure.
|
||||
|
||||
### 🚗 Transportation
|
||||
|
||||
- **New Transportation Edit Modal**: Includes detailed origin and destination location information for better trip planning.
|
||||
- **Autocomplete for Airport Codes**: Quickly find and add airport codes while planning transportation.
|
||||
- **New Transportation Card Design**: Redesigned for better clarity and aesthetics.
|
||||
|
||||
---
|
||||
|
||||
### 📝 Notes and Checklists
|
||||
|
||||
- **New Modals for Notes and Checklists**: Simplified creation and editing of your notes and checklists.
|
||||
- **Delete Confirmation**: Added a confirmation step when deleting notes, checklists, or transportation to prevent accidental deletions.
|
||||
|
||||
---
|
||||
|
||||
### 📍Adventures
|
||||
|
||||
- **Markdown Editor and Preview**: Write and format adventure descriptions with a markdown editor.
|
||||
- **Custom Categories**: Organize your adventures with personalized categories and icons.
|
||||
- **Primary Images**: Adventure images can now be marked as the "primary image" and will be the first one to be displayed in adventure views.
|
||||
|
||||
---
|
||||
|
||||
### 🗓️ Calendar
|
||||
|
||||
- **Calendar View**: View your adventures and transportation in a calendar layout.
|
||||
- **ICS File Export**: Export your calendar as an ICS file for use with external apps like Google Calendar or Outlook.
|
||||
|
||||
---
|
||||
|
||||
### 🌐 Localization
|
||||
|
||||
- Added support for **Polish** language (@dymek37).
|
||||
- Improved Swedish language data (@nordtechtiger)
|
||||
|
||||
---
|
||||
|
||||
### 🔒 Authentication
|
||||
|
||||
- **New Authentication System**: Includes MFA for added security.
|
||||
- **Admin Page Authentication**: Enhanced protection for admin operations.
|
||||
> [!IMPORTANT]
|
||||
> Ensure you know your credentials as you will be signed out after updating!
|
||||
|
||||
---
|
||||
|
||||
### 🖌️ UI & Theming
|
||||
|
||||
- **Nord Theme**: A sleek new theme option for a modern and clean interface.
|
||||
- **New Home Dashboard**: A revamped dashboard experience to access everything you need quickly and view your travel stats.
|
||||
|
||||
---
|
||||
|
||||
### ⚙️ Settings
|
||||
|
||||
- **Overhauled Settings Page**: Redesigned for better navigation and usability.
|
||||
|
||||
---
|
||||
|
||||
### 🐛 Bug Fixes and Improvements
|
||||
|
||||
- Fixed the **NGINX Upload Size Bug**: Upload larger files without issues.
|
||||
- **Prevents Duplicate Emails**: Improved account management; users can now add multiple emails to a single account.
|
||||
- General **code cleanliness** for better performance and stability.
|
||||
- Fixes Django Admin access through Traefik (@PascalBru)
|
||||
|
||||
---
|
||||
|
||||
### 🌐 Infrastructure
|
||||
|
||||
- Added **Kubernetes Configurations** for scalable deployments (@MaximUltimatum).
|
||||
- Launched a **New [Documentation Site](https://voyage.app)** for better guidance and support.
|
||||
|
||||
---
|
||||
|
||||
## Sponsorship 💖
|
||||
|
||||
As always, Voyage continues to grow thanks to your incredible support and feedback. If you love using the app and want to help shape its future, consider supporting me on **Buy Me A Coffee**. Your contributions go a long way in allowing for Voyage to continue to improve and thrive 😊
|
||||
|
||||
---
|
||||
|
||||
Enjoy the update! 🎉
|
||||
Feel free to share your feedback, ideas, or questions in the discussion below or on the official [discord server](https://discord.gg/wRbQ9Egr8C)!
|
||||
|
||||
Happy travels,
|
||||
**Sean Morley** (@seanmorley15)
|
||||
132
docs/docs/changelogs/v0-9-0.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Voyage v0.9.0 - Smart Recommendations, Attachments, and Maps
|
||||
|
||||
Released 03-19-2025
|
||||
|
||||
Hi travelers! 🌍
|
||||
I’m excited to unveil **Voyage v0.9.0**, one of our most feature-packed updates yet! From Smart Recommendations to enhanced maps and a refreshed profile system, this release is all about improving your travel planning and adventure tracking experience. Let’s dive into what’s new!
|
||||
|
||||
---
|
||||
|
||||
## What's New ✨
|
||||
|
||||
### 🧠 Smart Recommendations
|
||||
|
||||
- **Voyage Smart Recommendations**: Get tailored suggestions for new adventures and activities based on your collection destinations.
|
||||
- Leverages OpenStreetMap to recommend places and activities near your travel destinations.
|
||||
|
||||
---
|
||||
|
||||
### 🗂️ Attachments, GPX Maps & Global Search
|
||||
|
||||
- **Attachments System**: Attach files to your adventures to view key trip data like maps and tickets in Voyage!
|
||||
- **GPX File Uploads & Maps**: Upload GPX tracks to adventures to visualize them directly on your maps.
|
||||
- **Global Search**: A universal search bar to quickly find adventures, cities, countries, and more across your instance.
|
||||
|
||||
---
|
||||
|
||||
### 🏨 Lodging & Itinerary
|
||||
|
||||
- **Lodging Tracking**: Add and manage lodging accommodations as part of your collections, complete with check-in/check-out dates.
|
||||
- **Improved Itinerary Views**: Better day-by-day itinerary display with clear UI enhancements.
|
||||
|
||||
---
|
||||
|
||||
### 🗺️ Maps & Locations
|
||||
|
||||
- **Open Locations in Maps**: Directly open adventure locations and points of interest in your preferred mapping service.
|
||||
- **Adventure Category Icons on Maps**: View custom category icons right on your adventure and collection maps.
|
||||
|
||||
---
|
||||
|
||||
### 🗓️ Calendar
|
||||
|
||||
- **Collection Range View**: Improved calendar view showing the full date range of collections.
|
||||
|
||||
---
|
||||
|
||||
### 🌐 Authentication & Security
|
||||
|
||||
- **OIDC Authentication**: Added support for OpenID Connect (OIDC) for seamless integration with identity providers.
|
||||
- **Secure Session Cookies**: Improved session cookie handling with dynamic domain detection and better security for IP addresses.
|
||||
- **Disable Password Auth**: Option to disable password auth for users with connected OIDC/Social accounts.
|
||||
|
||||
---
|
||||
|
||||
### 🖥️ PWA Support
|
||||
|
||||
- **Progressive Web App (PWA) Support**: Install Voyage as a PWA on your desktop or mobile device for a native app experience.
|
||||
|
||||
---
|
||||
|
||||
### 🏗️ Infrastructure & DevOps
|
||||
|
||||
- **Dual-Stack Backend**: IPv4 and IPv6 ready backend system (@larsl-net).
|
||||
- **Kubernetes Configs** continue to be improved for scalable deployments.
|
||||
|
||||
---
|
||||
|
||||
### 🌐 Localization
|
||||
|
||||
- **Korean language support** (@seanmorley15).
|
||||
- **Improved Dutch** (@ThomasDetemmerman), **Simplified Chinese** (@jyyyeung), **German** (@Cathnan and @marcschumacher) translations.
|
||||
- **Polish and Swedish** translations improved in prior release!
|
||||
|
||||
---
|
||||
|
||||
### 📝 Documentation
|
||||
|
||||
- **New Unraid Installation Guide** with community-contributed updates (@ThunderLord956, @evertyang).
|
||||
- Updated **OIDC** and **Immich integration** docs for clarity (@UndyingSoul, @motox986).
|
||||
- General spell-check and documentation polish (@ThunderLord956, @mcguirepr89).
|
||||
|
||||
---
|
||||
|
||||
### 🐛 Bug Fixes and Improvements
|
||||
|
||||
- Fixed CSRF issues with admin tools.
|
||||
- Backend ready for **dual-stack** environments.
|
||||
- Improved itinerary element display and GPX file handling.
|
||||
- Optimized session cookie handling for domain/IP setups.
|
||||
- Various **small Python fixes** (@larsl-net).
|
||||
- Fixed container relations (@bucherfa).
|
||||
- Django updated to **5.0.11** for security and performance improvements.
|
||||
- General **codebase clean-up** and UI polish.
|
||||
|
||||
---
|
||||
|
||||
## 🌟 New Contributors
|
||||
|
||||
A huge shoutout to our amazing new contributors! 🎉
|
||||
|
||||
- @larsl-net
|
||||
- @bucherfa
|
||||
- @UndyingSoul
|
||||
- @ThunderLord956
|
||||
- @evertyang
|
||||
- @Thiesjoo
|
||||
- @motox986
|
||||
- @mcguirepr89
|
||||
- @ThomasDetemmerman
|
||||
- @Cathnan
|
||||
- @jyyyeung
|
||||
- @marcschumacher
|
||||
|
||||
Thank you for helping Voyage grow! 🙌
|
||||
|
||||
---
|
||||
|
||||
## Support My Work 💖
|
||||
|
||||
If Voyage has made your travels more organized or your trip memories richer, consider supporting my work on **Buy Me A Coffee**. Your support directly helps shape the future of this project! ☕
|
||||
|
||||
---
|
||||
|
||||
Enjoy this update and keep sharing your journeys with us! 🌍✈️
|
||||
As always, drop your feedback and ideas in the [official Discord](https://discord.gg/wRbQ9Egr8) or in the discussions!
|
||||
|
||||
Happy travels,
|
||||
**Sean Morley** (@seanmorley15)
|
||||
|
||||
---
|
||||
|
||||
**[Full Changelog](https://github.com/Alex-Wiesner/voyage/compare/v0.8.0...v0.9.0)**
|
||||
23
docs/docs/configuration/advanced_configuration.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 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 Voyage instance. These variables are not required for a basic setup but can enhance functionality and security.
|
||||
|
||||
| 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 |
|
||||
| `OSRM_BASE_URL` | No | Base URL of the OSRM routing server used for itinerary connector distance/travel-time metrics. The public OSRM demo server is used by default. Set this to point at your own OSRM instance (e.g. `http://osrm:5000`) for higher rate limits or offline use. When the OSRM server is unreachable, the backend automatically falls back to haversine-based approximations so the itinerary UI always shows metrics. | `https://router.project-osrm.org` | Backend |
|
||||
| `FIELD_ENCRYPTION_KEY` | No* | Fernet key used to encrypt user API keys at rest (integrations API key storage). Generate a 32-byte urlsafe base64 key (e.g. `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"`). If missing/invalid, only API-key storage endpoints fail gracefully and the rest of the app remains available. | _(none)_ | Backend |
|
||||
| `DJANGO_MCP_ENDPOINT` | No | HTTP path used for the Voyage Travel Agent MCP endpoint. Clients call this endpoint with `Authorization: Token <token>` using a DRF auth token for the target user account. | `api/mcp` | Backend |
|
||||
|
||||
## MCP endpoint authentication details
|
||||
|
||||
Voyage's MCP endpoint requires token authentication.
|
||||
|
||||
- Header format: `Authorization: Token <token>`
|
||||
- Default endpoint path: `api/mcp`
|
||||
- Override path with: `DJANGO_MCP_ENDPOINT`
|
||||
- Token bootstrap endpoint for authenticated sessions: `GET /auth/mcp-token/`
|
||||
|
||||
For MCP usage patterns and tool-level examples, see the [Travel Agent (MCP) guide](../guides/travel_agent.md).
|
||||
10
docs/docs/configuration/analytics.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Umami Analytics (optional)
|
||||
|
||||
Umami Analytics is a free, open-source, and privacy-focused web analytics tool that can be used as an alternative to Google Analytics. Learn more about Umami Analytics [here](https://umami.is/).
|
||||
|
||||
To enable Umami Analytics for your Voyage instance, you can set the following variables in your `docker-compose.yml` under the `web` service:
|
||||
|
||||
```yaml
|
||||
PUBLIC_UMAMI_SRC=https://cloud.umami.is/script.js # If you are using the hosted version of Umami
|
||||
PUBLIC_UMAMI_WEBSITE_ID=
|
||||
```
|
||||
10
docs/docs/configuration/disable_registration.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Disable Registration
|
||||
|
||||
To disable registration, you can set the following variable in your docker-compose.yml under the server service:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- DISABLE_REGISTRATION=True
|
||||
# OPTIONAL: Set the message to display when registration is disabled
|
||||
- DISABLE_REGISTRATION_MESSAGE='Registration is disabled for this instance of Voyage.'
|
||||
```
|
||||
34
docs/docs/configuration/email.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Change Email Backend
|
||||
|
||||
To change the email backend, you can set the following variable in your docker-compose.yml under the server service:
|
||||
|
||||
## Using Console (default)
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- EMAIL_BACKEND=console
|
||||
```
|
||||
|
||||
## With SMTP
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- EMAIL_BACKEND=email
|
||||
- EMAIL_HOST=smtp.gmail.com
|
||||
- EMAIL_USE_TLS=True
|
||||
- EMAIL_PORT=587
|
||||
- EMAIL_USE_SSL=False
|
||||
- EMAIL_HOST_USER=user
|
||||
- EMAIL_HOST_PASSWORD=password
|
||||
- DEFAULT_FROM_EMAIL=user@example.com
|
||||
```
|
||||
|
||||
## Customizing Emails
|
||||
|
||||
By default, the email will display `[example.com]` in the subject. You can customize this in the admin site.
|
||||
|
||||
1. Go to the admin site (serverurl/admin)
|
||||
2. Click on `Sites`
|
||||
3. Click on first site, it will probably be `example.com`
|
||||
4. Change the `Domain name` and `Display name` to your desired values
|
||||
5. Click `Save`
|
||||
42
docs/docs/configuration/google_maps_integration.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Google Maps Integration
|
||||
|
||||
To enable Google Maps integration in Voyage, you'll need to create a Google Maps API key. This key allows Voyage to use Google Maps services such as geocoding and location search throughout the application.
|
||||
|
||||
Follow the steps below to generate your own API key:
|
||||
|
||||
## Google Cloud Console Setup
|
||||
|
||||
1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
|
||||
2. Create an account if you don't have one in order to access the console.
|
||||
3. Click on the project dropdown in the top bar.
|
||||
4. Click **New Project**.
|
||||
5. Name your project (e.g., `Voyage Maps`) and click **Create**.
|
||||
6. Once the project is created, ensure it is selected in the project dropdown.
|
||||
7. Click on the **Navigation menu** (three horizontal lines in the top left corner).
|
||||
8. Navigate to **Google Maps Platform**.
|
||||
9. Once in the Maps Platform, click on **Keys & Credentials** in the left sidebar.
|
||||
10. Click on **Create credentials** and select **API key**.
|
||||
11. A dialog will appear with your new API key. Copy this key for later use.
|
||||
|
||||
> [!Note]
|
||||
> When creating the API Key, you can choose which APIs it can use.
|
||||
> For versions *v0.10.0* and _lower_, you need the *Geocoding* and *Places* APIs.
|
||||
> For versions _higher_ than v0.10.0, You'll need *Geocoding* and *Places (New)*.
|
||||
> Note that the latter isn't enabled by default!
|
||||
|
||||
<!-- To prevent misuse:
|
||||
|
||||
1. Click the **Edit icon** next to your new API key.
|
||||
2. Under **Application restrictions**, choose one:
|
||||
- Choose **Websites** as the restriction type.
|
||||
- Add the domain of the Voyage **backend** (e.g., `https://your-voyage-backend.com`). -->
|
||||
|
||||
## Configuration in Voyage
|
||||
|
||||
Set the API key in your environment file or configuration under the backend service of Voyage. This is typically done in the `docker-compose.yml` file or directly in your environment variables `.env` file.
|
||||
|
||||
```env
|
||||
GOOGLE_MAPS_API_KEY=your_api_key_here
|
||||
```
|
||||
|
||||
Once this is set, Voyage will be able to utilize Google Maps services for geocoding and location searches instead of relying on the default OpenStreetMap services.
|
||||
29
docs/docs/configuration/immich_integration.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Immich Integration
|
||||
|
||||
### What is Immich?
|
||||
|
||||
<!-- immich banner -->
|
||||
|
||||

|
||||
|
||||
Immich is a self-hosted, open-source platform that allows users to backup and manage their photos and videos similar to Google Photos, but with the advantage of storing data on their own private server, ensuring greater privacy and control over their media.
|
||||
|
||||
- [Immich Website and Documentation](https://immich.app/)
|
||||
- [GitHub Repository](https://github.com/immich-app/immich)
|
||||
|
||||
### How to integrate Immich with Voyage?
|
||||
|
||||
To integrate Immich with Voyage, you need to have an Immich server running and accessible from where Voyage is running.
|
||||
|
||||
1. Obtain the Immich API Key from the Immich server.
|
||||
- In the Immich web interface, click on your user profile picture, go to `Account Settings` > `API Keys`.
|
||||
- Click `New API Key` and name it something like `Voyage`.
|
||||
- Make sure the key has the following permissions: `asset.read, album.read, asset.view, library.read, user.read`
|
||||
- Copy the generated API Key, you will need it in the next step.
|
||||
2. Go to the Voyage web interface, click on your user profile picture, go to `Settings` and scroll down to the `Immich Integration` section.
|
||||
- Enter the URL of your Immich server, e.g. `https://immich.example.com/api`. Note that `localhost` or `127.0.0.1` will probably not work because Immich and Voyage are running on different docker networks. It is recommended to use the IP address of the server where Immich is running ex `http://my-server-ip:port` or a domain name.
|
||||
- Paste the API Key you obtained in the previous step.
|
||||
- Click `Enable Immich` to save the settings.
|
||||
3. Now, when you are adding images to an adventure, you will see an option to search for images in Immich or upload from an album.
|
||||
|
||||
Enjoy the privacy and control of managing your travel media with Immich and Voyage! 🎉
|
||||
16
docs/docs/configuration/social_auth.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Social Authentication
|
||||
|
||||
Voyage support authentication via 3rd party services and self-hosted identity providers. Once these services are enabled, users can log in to Voyage using their accounts from these services and link existing Voyage accounts to these services for easier access.
|
||||
|
||||
The steps for each service varies so please refer to the specific service's documentation for more information.
|
||||
|
||||
## Supported Services
|
||||
|
||||
- [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/voyage/)
|
||||
|
||||
## Linking Existing Accounts
|
||||
|
||||
If you already have an Voyage account and would like to link it to a 3rd party service, you can do so by logging in to Voyage and navigating to the `Account Settings` page. From there, scroll down to `Social and OIDC Authentication` and click the `Launch Account Connections` button. If identity providers have been enabled on your instance, you will see a list of available services to link to.
|
||||
70
docs/docs/configuration/social_auth/authentik.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Authentik OIDC Authentication
|
||||
|
||||
<img src="https://repository-images.githubusercontent.com/230885748/19f01d00-8e26-11eb-9a14-cf0d28a1b68d" alt="Authentik Logo" width="400" />
|
||||
|
||||
Authentik is a self-hosted identity provider that supports OpenID Connect and OAuth2. Voyage can be configured to use Authentik as an identity provider for social authentication. Learn more about Authentik at [goauthentik.io](https://goauthentik.io/).
|
||||
|
||||
Once Authentik is configured by the administrator, users can log in to Voyage using their Authentik account and link existing Voyage accounts to Authentik for easier access.
|
||||
|
||||
# Configuration
|
||||
|
||||
To enable Authentik as an identity provider, the administrator must first configure Authentik to allow Voyage to authenticate users.
|
||||
|
||||
### Authentik Configuration
|
||||
|
||||
1. Log in to Authentik and navigate to the `Providers` page and create a new provider.
|
||||
2. Select `OAuth2/OpenID Provider` as the provider type.
|
||||
3. Name it `Voyage` or any other name you prefer.
|
||||
4. Set the `Redirect URI` of type `Regex` to `^http://<voyage-server-url>/accounts/oidc/.*$` where `<voyage-url>` is the URL of your Voyage Server service.
|
||||
5. Copy the `Client ID` and `Client Secret` generated by Authentik, you will need these to configure Voyage.
|
||||
6. Create an application in Authentik and assign the provider to it, name the `slug` `voyage` or any other name you prefer.
|
||||
7. If you want the logo, you can find it [here](https://voyage.app/voyage.png).
|
||||
|
||||
### Voyage Configuration
|
||||
|
||||
This configuration is done in the [Admin Panel](../../guides/admin_panel.md). You can either launch the panel directly from the `Settings` page or navigate to `/admin` on your Voyage server.
|
||||
|
||||
1. Login to Voyage as an administrator and navigate to the `Settings` page.
|
||||
2. Scroll down to the `Administration Settings` and launch the admin panel.
|
||||
3. In the admin panel, navigate to the `Social Accounts` section and click the add button next to `Social applications`. Fill in the following fields:
|
||||
|
||||
- Provider: `OpenID Connect`
|
||||
- Provider ID: Authentik Client ID
|
||||
- Name: `Authentik`
|
||||
- Client ID: Authentik Client ID
|
||||
- Secret Key: Authentik Client Secret
|
||||
- Key: can be left blank
|
||||
- Settings: (make sure http/https is set correctly)
|
||||
|
||||
```json
|
||||
{
|
||||
"server_url": "http://<authentik_url>/application/o/[YOUR_SLUG]/"
|
||||
}
|
||||
```
|
||||
|
||||
::: warning
|
||||
`localhost` is most likely not a valid `server_url` for Authentik in this instance because `localhost` is the server running Voyage, not Authentik. You should use the IP address of the server running Authentik or the domain name if you have one.
|
||||
|
||||
- Sites: move over the sites you want to enable Authentik on, usually `example.com` and `www.example.com` unless you renamed your sites.
|
||||
|
||||
#### What it Should Look Like
|
||||
|
||||

|
||||
|
||||
4. Save the configuration.
|
||||
|
||||
Ensure that the Authentik server is running and accessible by Voyage. Users should now be able to log in to Voyage using their Authentik account.
|
||||
|
||||
## Linking to Existing Account
|
||||
|
||||
If a user has an existing Voyage account and wants to link it to their Authentik account, they can do so by logging in to their Voyage account and navigating to the `Settings` page. There is a button that says `Launch Account Connections`, click that and then choose the provider to link to the existing account.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 404 error when logging in.
|
||||
|
||||
Ensure the `<voyage-server-url>/accounts` path is routed to the backend, as it shouldn't hit the frontend when it's properly configured.
|
||||
|
||||
### Authentik - No Permission
|
||||
|
||||
In the Authentik instance, check access to the Voyage application from a specific user by using the Check Access/Test button on the Application dashboard. If the user doesn't have access, you can add an existing user/group policy to give your specific user/group access to the Voyage application.
|
||||
49
docs/docs/configuration/social_auth/github.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# GitHub Social Authentication
|
||||
|
||||
Voyage can be configured to use GitHub as an identity provider for social authentication. Users can then log in to Voyage using their GitHub account.
|
||||
|
||||
# Configuration
|
||||
|
||||
To enable GitHub as an identity provider, the administrator must first configure GitHub to allow Voyage to authenticate users.
|
||||
|
||||
### GitHub Configuration
|
||||
|
||||
1. Visit the GitHub OAuth Apps Settings page at [https://github.com/settings/developers](https://github.com/settings/developers).
|
||||
2. Click on `New OAuth App`.
|
||||
3. Fill in the following fields:
|
||||
|
||||
- Application Name: `Voyage` or any other name you prefer.
|
||||
- Homepage URL: `<voyage-frontend-url>` where `<voyage-frontend-url>` is the URL of your Voyage Frontend service.
|
||||
- Application Description: `Voyage` or any other description you prefer.
|
||||
- Authorization callback URL: `http://<voyage-backend-url>/accounts/github/login/callback/` where `<voyage-backend-url>` is the URL of your Voyage Backend service.
|
||||
- If you want the logo, you can find it [here](https://voyage.app/voyage.png).
|
||||
|
||||
### Voyage Configuration
|
||||
|
||||
This configuration is done in the [Admin Panel](../../guides/admin_panel.md). You can either launch the panel directly from the `Settings` page or navigate to `/admin` on your Voyage server.
|
||||
|
||||
1. Login to Voyage as an administrator and navigate to the `Settings` page.
|
||||
2. Scroll down to the `Administration Settings` and launch the admin panel.
|
||||
3. In the admin panel, navigate to the `Social Accounts` section and click the add button next to `Social applications`. Fill in the following fields:
|
||||
|
||||
- Provider: `GitHub`
|
||||
- Provider ID: GitHub Client ID
|
||||
- Name: `GitHub`
|
||||
- Client ID: GitHub Client ID
|
||||
- Secret Key: GitHub Client Secret
|
||||
- Key: can be left blank
|
||||
- Settings: can be left blank
|
||||
- Sites: move over the sites you want to enable Authentik on, usually `example.com` and `www.example.com` unless you renamed your sites.
|
||||
|
||||
4. Save the configuration.
|
||||
|
||||
Users should now be able to log in to Voyage using their GitHub account, and link it to existing accounts.
|
||||
|
||||
## Linking to Existing Account
|
||||
|
||||
If a user has an existing Voyage account and wants to link it to their Github account, they can do so by logging in to their Voyage account and navigating to the `Settings` page. There is a button that says `Launch Account Connections`, click that and then choose the provider to link to the existing account.
|
||||
|
||||
#### What it Should Look Like
|
||||
|
||||

|
||||
|
||||
7
docs/docs/configuration/social_auth/oidc.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# OIDC Social Authentication
|
||||
|
||||
Voyage can be configured to use OpenID Connect (OIDC) as an identity provider for social authentication. Users can then log in to Voyage using their OIDC account.
|
||||
|
||||
The configuration is basically the same as [Authentik](./authentik.md), but you replace the client and secret with the OIDC client and secret provided by your OIDC provider. The `server_url` should be the URL of your OIDC provider where you can find the OIDC configuration.
|
||||
|
||||
Each provider has a different configuration, so you will need to check the documentation of your OIDC provider to find the correct configuration.
|
||||
143
docs/docs/configuration/social_auth/pocket_id.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Pocket ID OIDC Authentication
|
||||
|
||||
<img src="https://pocket-id.org/logo.png" alt="Pocket ID Logo" width="400" />
|
||||
|
||||
Pocket ID is a lightweight, self-hosted OpenID Connect (OIDC) identity provider. Voyage can be configured to use Pocket ID for social authentication using its built-in OpenID Connect support.
|
||||
|
||||
Once Pocket ID is configured by an administrator, users can sign in to Voyage using their Pocket ID account and optionally link it to an existing Voyage account.
|
||||
|
||||
---
|
||||
|
||||
# Configuration
|
||||
|
||||
To enable Pocket ID as an identity provider, both Pocket ID and Voyage must be configured correctly. The most important (and least obvious) part of this setup is the **callback URL**, which must match Voyage’s internal OIDC routing.
|
||||
|
||||
---
|
||||
|
||||
## Pocket ID Configuration
|
||||
|
||||
1. Log in to your Pocket ID admin interface.
|
||||
|
||||
2. Navigate to **Clients** and create a new client.
|
||||
|
||||
3. Name the client something like `Voyage`.
|
||||
|
||||
4. Set the **Redirect / Callback URL** to:
|
||||
|
||||
```
|
||||
https://<voyage-backend.example.com>/accounts/oidc/<CLIENT_ID>/login/callback/
|
||||
```
|
||||
|
||||
- Replace `<voyage-backend.example.com>` with the **backend** URL of your Voyage instance.
|
||||
- Replace `<CLIENT_ID>` with the **Pocket ID client ID** exactly as generated.
|
||||
- This path is required and currently not auto-documented by Pocket ID or Voyage.
|
||||
|
||||
5. Ensure the client type is **Confidential**.
|
||||
|
||||
6. Copy the generated **Client ID** and **Client Secret** — you will need both for Voyage.
|
||||
|
||||
---
|
||||
|
||||
## Voyage Configuration
|
||||
|
||||
This configuration is done in the [Admin Panel](../../guides/admin_panel.md). You can launch it from the `Settings` page or navigate directly to `/admin` on your Voyage server.
|
||||
|
||||
1. Log in to Voyage as an administrator.
|
||||
2. Navigate to **Settings** → **Administration Settings** and launch the admin panel.
|
||||
3. Go to **Social Accounts**.
|
||||
4. Under **Social applications**, click **Add**.
|
||||
5. Fill in the fields as follows:
|
||||
|
||||
### Social Application Settings
|
||||
|
||||
- **Provider**: `OpenID Connect`
|
||||
- **Provider ID**: Pocket ID Client ID
|
||||
- **Name**: `Pocket ID`
|
||||
- **Client ID**: Pocket ID Client ID
|
||||
- **Secret Key**: Pocket ID Client Secret
|
||||
- **Key**: _(leave blank)_
|
||||
- **Settings**:
|
||||
|
||||
```json
|
||||
{
|
||||
"server_url": "https://<pocketid-url>/.well-known/openid-configuration"
|
||||
}
|
||||
```
|
||||
|
||||
- Replace `<pocketid-url>` with the base URL of your Pocket ID instance.
|
||||
|
||||
::: warning
|
||||
Do **not** use `localhost` unless Pocket ID is running on the same machine and is resolvable from inside the Voyage container or service. Use a domain name or LAN IP instead.
|
||||
:::
|
||||
|
||||
- **Sites**: Move the sites you want Pocket ID enabled on (usually `example.com` and `www.example.com`).
|
||||
|
||||
6. Save the configuration.
|
||||
|
||||
Ensure Pocket ID is running and reachable by Voyage.
|
||||
|
||||
---
|
||||
|
||||
## What It Should Look Like
|
||||
|
||||
Once configured correctly:
|
||||
|
||||
- Pocket ID appears as a login option on the Voyage login screen.
|
||||
- Logging in redirects to Pocket ID, then back to Voyage without errors.
|
||||
|
||||
---
|
||||
|
||||
## Linking to an Existing Account
|
||||
|
||||
If a user already has an Voyage account:
|
||||
|
||||
1. Log in to Voyage normally.
|
||||
2. Go to **Settings**.
|
||||
3. Click **Launch Account Connections**.
|
||||
4. Choose **Pocket ID** to link the identity to the existing account.
|
||||
|
||||
This allows future logins using Pocket ID without creating a duplicate account.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 404 Error After Login
|
||||
|
||||
Ensure that:
|
||||
|
||||
- `/accounts` routes are handled by the **backend**, not the frontend.
|
||||
- Your reverse proxy (Nginx, Traefik, Caddy, etc.) forwards `/accounts/*` correctly.
|
||||
|
||||
---
|
||||
|
||||
### Invalid Redirect URI
|
||||
|
||||
- Double-check that the callback URL in Pocket ID exactly matches:
|
||||
|
||||
```
|
||||
/accounts/oidc/<CLIENT_ID>/login/callback/
|
||||
```
|
||||
|
||||
- The `<CLIENT_ID>` must match the value used in the Voyage social application.
|
||||
|
||||
---
|
||||
|
||||
### Cannot Reach Pocket ID
|
||||
|
||||
- Verify that the `.well-known/openid-configuration` endpoint is accessible from the Voyage server.
|
||||
- Test by opening:
|
||||
|
||||
```
|
||||
https://<pocketid-url>/.well-known/openid-configuration
|
||||
```
|
||||
|
||||
in a browser.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Pocket ID configuration is very similar to Authentik.
|
||||
- The main difference is the **explicit callback URL requirement** and the use of the `.well-known/openid-configuration` endpoint as the `server_url`.
|
||||
- This setup works with Docker, Docker Compose, and bare-metal deployments as long as networking i
|
||||
43
docs/docs/configuration/strava_integration.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Strava Integration
|
||||
|
||||
Strava is a popular platform for athletes to track their activities, share their workouts, and connect with other fitness enthusiasts. Integrating Strava with Voyage allows you to import your Strava activities directly into your vists, making it easier to keep track of your outdoor experiences.
|
||||
|
||||
To enable Strava integration in Voyage, you'll need to create a Strava API application. This application will provide you with the necessary client ID and client secret to authenticate with the Strava API.
|
||||
|
||||
Follow the steps below to generate your own Strava API credentials:
|
||||
|
||||
## Strava API Application Setup
|
||||
|
||||
1. Login to your Strava account at [Strava](https://www.strava.com/).
|
||||
2. Go to the [Strava API Applications page](https://www.strava.com/settings/api).
|
||||
3. Click on **Create a New Application**.
|
||||
4. Fill in the application details:
|
||||
- **Application Name**: Voyage Strava Integration
|
||||
- **Website**: Your Voyage instance URL (e.g., `https://your-voyage-instance.com`)
|
||||
- **Authorization Callback Domain**: Your Voyage instance domain (e.g., `your-voyage-instance.com`)
|
||||
5. Agree to the Strava API Terms
|
||||
6. Click **Create** to generate your application.
|
||||
7. After creation, you will see your **Client ID** and **Client Secret**. Keep these credentials safe as you will need them to configure Voyage.
|
||||
|
||||
## Configuration in Voyage
|
||||
|
||||
8. Once you have your Strava API credentials, you can configure Voyage to use them. Open your `.env` file in the root of your Voyage project and add the following lines:
|
||||
|
||||
```env
|
||||
STRAVA_CLIENT_ID=your_client_id_here
|
||||
STRAVA_CLIENT_SECRET=your_client_secret_here
|
||||
```
|
||||
|
||||
9. After adding these lines, save the file and restart your Voyage server to apply the changes.
|
||||
10. Navigate to Voyage's settings page, click the integration tab, and find the Strava section.
|
||||
11. Click the **Connect Account** button. This will redirect you to Strava's authorization page.
|
||||
12. Log in to your Strava account and authorize Voyage to access your Strava data.
|
||||
13. After authorization, you will be redirected back to Voyage, and your Strava account will be linked.
|
||||
|
||||
## Importing Strava Activities
|
||||
|
||||
The Strava integration appears on the visit create/edit part of the location edit popup. Once a visit is added, there will be a button on it to search for Strava activities. Clicking this button will search then you can import the activity into the visit. The imported activity will include details such as distance, duration, elevation gain, and more.
|
||||
|
||||
**Note**: Due to API limitations on Strava's side, when you import an activity, there will be a button that says **Download GPX** then you can download the GPX file of the activity and drop it into the input field of the visit. This manual action is necessary because Strava does not provide a direct way to import GPX files into Voyage.
|
||||
|
||||
Enjoy tracking your adventures with Strava and Voyage! If you encounter any issues or have questions about the integration, feel free to reach out to the Voyage community!
|
||||
43
docs/docs/configuration/updating.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Updating
|
||||
|
||||
Updating Voyage when using docker can be quite easy. Run a collections backup before upgrading, then pull the latest version and restart the containers.
|
||||
|
||||
## Pre-upgrade backup (recommended)
|
||||
|
||||
Before running migrations or updating containers, export a collections snapshot:
|
||||
|
||||
```bash
|
||||
docker compose exec server python manage.py export_collections_backup
|
||||
```
|
||||
|
||||
You can also provide a custom output path:
|
||||
|
||||
```bash
|
||||
docker compose exec server python manage.py export_collections_backup --output /code/backups/collections_backup_pre_upgrade.json
|
||||
```
|
||||
|
||||
The backup file includes a timestamp, record counts, and snapshot data for:
|
||||
|
||||
- `Collection`
|
||||
- `CollectionItineraryItem`
|
||||
|
||||
Note: Make sure you are in the same directory as your `docker-compose.yml` file.
|
||||
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Updating the Region Data
|
||||
|
||||
Region and Country data in Voyage 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 Voyage 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 Voyage. 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.
|
||||
|
||||
```bash
|
||||
python manage.py download-countries --force
|
||||
```
|
||||
26
docs/docs/configuration/wanderer_integration.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Wanderer Integration
|
||||
|
||||
[Wanderer](https://wanderer.to) is a self-hosted trail database. Integrating Wanderer with Voyage allows you to import trails directly into your locations, making it easier to plan and track your outdoor adventures.
|
||||
|
||||
## Wanderer Integration Setup
|
||||
|
||||
1. Navigate to the Voyage settings page.
|
||||
2. Click on the **Integrations** tab.
|
||||
3. Find the **Wanderer** section and input the URL of your Wanderer instance, your username, and password.
|
||||
4. Click the **Connect Account** button to authenticate with your Wanderer instance.
|
||||
|
||||
### Important Notes
|
||||
|
||||
1. The URL to the Wanderer server must be accessible from the Voyage server. This means values like `localhost` or `127.0.0.1` will likely cause some issues.
|
||||
2. Voyage **does not store your Wanderer credentials**. They are only used to fetch an authorization token for the Wanderer API. This token will last for around 2 weeks before needing to be refreshed. Using the token refreshes the token for another 2 weeks. Should the token expire, you will need to re-enter your credentials in the Voyage settings page.
|
||||
|
||||
## Importing Wanderer Trails
|
||||
|
||||
1. Open the create/edit location popup in Voyage.
|
||||
2. Naviage to the **Media** tab and scroll down to the **Trail Managment** section.
|
||||
3. Click the **Add Wanderer Trail** button.
|
||||
4. A search input will appear. Type in the name of the trail you want to import.
|
||||
5. Select the desired trail from the search results and click the link icon to import it into your location.
|
||||
6. The imported trail will be added to your location's trails list, and you can view its details, including distance, elevation gain, and more.
|
||||
|
||||
Enjoy exploring new trails with Wanderer and Voyage! If you encounter any issues or have questions about the integration, feel free to reach out to the Voyage community!
|
||||
11
docs/docs/guides/admin_panel.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Voyage Admin Panel
|
||||
|
||||
The Voyage Admin Panel, powered by Django, is a web-based interface that allows administrators to manage objects in the Voyage database. The Admin Panel is accessible at the `/admin` endpoint of the Voyage server. Example: `https://al-server.yourdomain.com/admin`.
|
||||
|
||||
Features of the Admin Panel include:
|
||||
|
||||
- **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.
|
||||
|
||||
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.
|
||||
6
docs/docs/guides/invite_user.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Invite a User
|
||||
|
||||
Voyage allows for admin users to invite new users to create an account via an email invitation.
|
||||
Invites are sent from the Voyage [Admin Panel](admin_panel.md) or via a custom invite form. The invite section of the admin panel can be found at `/admin/invitations/invitation/add/`.
|
||||
|
||||
Tip: make sure you have a working email setup for Voyage to send emails. See the [Email Configuration Guide](../configuration/email.md) for more information.
|
||||
155
docs/docs/guides/travel_agent.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Travel Agent (MCP)
|
||||
|
||||
Voyage includes a **Travel Agent** interface exposed through an **MCP-compatible HTTP endpoint**. This lets external MCP clients read and manage trip itineraries programmatically for authenticated users.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- Default path: `api/mcp`
|
||||
- Configurable with: `DJANGO_MCP_ENDPOINT`
|
||||
|
||||
If you run Voyage at `https://voyage.example.com`, the default MCP URL is:
|
||||
|
||||
```text
|
||||
https://voyage.example.com/api/mcp
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
MCP requests must include a DRF token in the `Authorization` header:
|
||||
|
||||
```text
|
||||
Authorization: Token <token>
|
||||
```
|
||||
|
||||
Use a token associated with the Voyage user account that should execute the MCP actions.
|
||||
|
||||
### Get a token from an authenticated session
|
||||
|
||||
Voyage exposes a token bootstrap endpoint for logged-in users:
|
||||
|
||||
- `GET /auth/mcp-token/`
|
||||
|
||||
Call it with your authenticated browser session (or any authenticated session cookie flow). It returns:
|
||||
|
||||
```json
|
||||
{ "token": "<token>" }
|
||||
```
|
||||
|
||||
Then use that token in all MCP requests with the same header format:
|
||||
|
||||
```text
|
||||
Authorization: Token <token>
|
||||
```
|
||||
|
||||
## Available MCP tools
|
||||
|
||||
The Voyage MCP server currently exposes these tools:
|
||||
|
||||
- `list_collections`
|
||||
- `get_collection_details`
|
||||
- `list_itinerary_items`
|
||||
- `create_itinerary_item`
|
||||
- `reorder_itinerary`
|
||||
|
||||
### Tool parameters
|
||||
|
||||
#### `list_collections`
|
||||
|
||||
- No parameters.
|
||||
|
||||
#### `get_collection_details`
|
||||
|
||||
- `collection_id` (required, string UUID): collection to inspect.
|
||||
|
||||
#### `list_itinerary_items`
|
||||
|
||||
- `collection_id` (optional, string UUID): if provided, limits results to one collection.
|
||||
|
||||
#### `create_itinerary_item`
|
||||
|
||||
Required:
|
||||
|
||||
- `collection_id` (string UUID)
|
||||
- `content_type` (`location` \| `transportation` \| `note` \| `lodging` \| `visit` \| `checklist`)
|
||||
- `object_id` (string UUID, id of the referenced content object)
|
||||
|
||||
Optional:
|
||||
|
||||
- `date` (ISO date string, required when `is_global` is `false`)
|
||||
- `is_global` (boolean, default `false`; when `true`, `date` must be omitted)
|
||||
- `order` (integer; if omitted, Voyage appends to the end of the relevant scope)
|
||||
|
||||
#### `reorder_itinerary`
|
||||
|
||||
Required:
|
||||
|
||||
- `items` (list of item update objects)
|
||||
|
||||
Each entry in `items` should include:
|
||||
|
||||
- `id` (required, string UUID of `CollectionItineraryItem`)
|
||||
- `date` (ISO date string for dated items)
|
||||
- `order` (integer target order)
|
||||
- `is_global` (optional boolean; include when moving between global and dated scopes)
|
||||
|
||||
## End-to-end example flow
|
||||
|
||||
This example shows a typical interaction from an MCP client.
|
||||
|
||||
1. **Connect** to the MCP endpoint using your Voyage server URL and token header.
|
||||
2. Call **`list_collections`** to find the trip/collection you want to work with.
|
||||
3. Call **`get_collection_details`** for the selected collection ID to inspect current trip context.
|
||||
4. Call **`list_itinerary_items`** for a specific date or collection scope.
|
||||
5. Call **`create_itinerary_item`** to add a new stop (for example, a location or note) to the itinerary.
|
||||
6. Call **`reorder_itinerary`** to persist the final ordering after insertion.
|
||||
|
||||
### Example request headers (HTTP transport)
|
||||
|
||||
```http
|
||||
POST /api/mcp HTTP/1.1
|
||||
Host: voyage.example.com
|
||||
Authorization: Token <token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
### Example interaction sequence (conceptual)
|
||||
|
||||
```text
|
||||
Client -> list_collections
|
||||
Server -> [{"id": "6c5d9f61-2f09-4882-b277-8884b633d36b", "name": "Japan 2026"}, ...]
|
||||
|
||||
Client -> get_collection_details({"collection_id": "6c5d9f61-2f09-4882-b277-8884b633d36b"})
|
||||
Server -> {...collection metadata...}
|
||||
|
||||
Client -> list_itinerary_items({"collection_id": "6c5d9f61-2f09-4882-b277-8884b633d36b"})
|
||||
Server -> [...current ordered itinerary items...]
|
||||
|
||||
Client -> create_itinerary_item({
|
||||
"collection_id": "6c5d9f61-2f09-4882-b277-8884b633d36b",
|
||||
"content_type": "location",
|
||||
"object_id": "fe7ee379-8a2b-456d-9c59-1eafcf83979b",
|
||||
"date": "2026-06-12",
|
||||
"order": 3
|
||||
})
|
||||
Server -> {"id": "5eb8c40c-7e36-4709-b4ec-7dc4cfa26ca5", ...}
|
||||
|
||||
Client -> reorder_itinerary({"items": [
|
||||
{
|
||||
"id": "5eb8c40c-7e36-4709-b4ec-7dc4cfa26ca5",
|
||||
"date": "2026-06-12",
|
||||
"order": 0
|
||||
},
|
||||
{
|
||||
"id": "a044f903-d788-4f67-bba7-3ee73da6d504",
|
||||
"date": "2026-06-12",
|
||||
"order": 1,
|
||||
"is_global": false
|
||||
}
|
||||
]})
|
||||
Server -> [...updated itinerary items...]
|
||||
```
|
||||
|
||||
## Related docs
|
||||
|
||||
- [Advanced Configuration](../configuration/advanced_configuration.md)
|
||||
- [How to use Voyage](../usage/usage.md)
|
||||
37
docs/docs/guides/v0-7-1_migration.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Voyage v0.7.1 Migration
|
||||
|
||||
In order to make installation easier, the Voyage v0.7.1 release has **removed the need for a separate nginx container** and config to serve the media files. Instead, the media files are now served by an instance of nginx running in the same container as the Django application.
|
||||
|
||||
## Docker Compose Changes
|
||||
|
||||
::: tip
|
||||
|
||||
You can also just use the new `docker-compose.yml` file in the repository and change the environment variables to match your setup.
|
||||
|
||||
:::
|
||||
|
||||
1. Remove the `nginx` service from your `docker-compose.yml` file.
|
||||
2. Update the `PUBLIC_URL` environment variable in the `server` service (backend) to match the address of your **server**, instead of the previous nginx instance. For example, if your server is exposed to `http://localhost:8000`, set `PUBLIC_URL` to `http://localhost:8000`. If you are using a domain name, set `PUBLIC_URL` to `https://api.yourdomain.com` as an example.
|
||||
3. Change port mapping for the `server` service. Right now it probably looks like this:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "your-exposed-port:8000"
|
||||
```
|
||||
|
||||
Change it to:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "your-exposed-port:80"
|
||||
```
|
||||
|
||||
This is because the nginx instance in the container is now serving the Django application on port 80. The port on the left side of the colon is the port on your host machine and this can be changed to whatever you want. The port on the right side of the colon is the port the Django application is running on in the container and should not be changed.
|
||||
|
||||
That's it! You should now be able to run the application with the new configuration! This update also includes some performance enhancements so there should be a slight speed increase as well, especially with multiple users.
|
||||
|
||||
Enjoy the new version of Voyage! 🎉
|
||||
|
||||
View the full changelog [here](https://github.com/Alex-Wiesner/voyage/releases/tag/v0.7.1)
|
||||
|
||||
Report any bugs [GitHub repository](https://github.com/Alex-Wiesner/voyage) or ask for help in the [Discord server](https://discord.gg/wRbQ9Egr8C).
|
||||
67
docs/docs/install/caddy.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Installation with Caddy
|
||||
|
||||
Caddy is a modern HTTP reverse proxy. It automatically integrates with Let's Encrypt (or other certificate providers) to generate TLS certificates for your site.
|
||||
|
||||
As an example, if you want to add Caddy to your Docker compose configuration, add the following service to your `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
caddy:
|
||||
image: docker.io/library/caddy:2
|
||||
container_name: voyage-caddy
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./caddy:/etc/caddy
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
|
||||
web: ...
|
||||
server: ...
|
||||
db: ...
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
```
|
||||
|
||||
Since all ingress traffic to the Voyage containsers now travels through Caddy, we can also remove the external ports configuration from those containsers in the `docker-compose.yml`. Just delete this configuration:
|
||||
|
||||
```yaml
|
||||
web:
|
||||
ports:
|
||||
- "8016:80"
|
||||
…
|
||||
server:
|
||||
ports:
|
||||
- "8015:3000"
|
||||
```
|
||||
|
||||
That's it for the Docker compose changes. Of course, there are other methods to run Caddy which are equally valid.
|
||||
|
||||
However, we also need to configure Caddy. For this, create a file `./caddy/Caddyfile` in which you configure the requests which are proxied to the frontend and backend respectively and what domain Caddy should request a certificate for:
|
||||
|
||||
```
|
||||
voyage.example.com {
|
||||
|
||||
@frontend {
|
||||
not path /media* /admin* /static* /accounts*
|
||||
}
|
||||
reverse_proxy @frontend web:3000
|
||||
|
||||
reverse_proxy server:80
|
||||
}
|
||||
```
|
||||
|
||||
Once configured, you can start up the containsers:
|
||||
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
|
||||
Your Voyage should now be up and running.
|
||||
180
docs/docs/install/dev_container_wsl.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Dev Container + WSL 🧰
|
||||
|
||||
Running Voyage in a **Dev Container** allows you to contribute to the project or work on features locally in a fully reproducible development environment with hot reloading, debugging, and tooling isolated inside Docker.
|
||||
|
||||
This guide focuses on **Windows using WSL 2**, but the workflow is similar on other platforms.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, ensure you have the following installed:
|
||||
|
||||
* **Docker Desktop**
|
||||
Download from: [https://www.docker.com/products/docker-desktop/](https://www.docker.com/products/docker-desktop/)
|
||||
|
||||
> Docker Desktop must be configured to use **WSL 2**
|
||||
> Make sure Docker Desktop is running before you start the steps below.
|
||||
|
||||
* **WSL 2 with a Linux distribution installed**
|
||||
Ubuntu is recommended.
|
||||
|
||||
```bash
|
||||
wsl --install -d Ubuntu
|
||||
```
|
||||
Run this in **Windows PowerShell** (or **Windows Terminal**).
|
||||
|
||||
* **Visual Studio Code**
|
||||
[https://code.visualstudio.com/](https://code.visualstudio.com/)
|
||||
|
||||
* **VS Code Extensions**
|
||||
|
||||
* Dev Containers
|
||||
* WSL
|
||||
|
||||
## ⚠️ Important Notes (Read First)
|
||||
|
||||
> **TIP**
|
||||
> Do not use the `docker-desktop` WSL distribution for development.
|
||||
> Always use a real Linux distro such as **Ubuntu**.
|
||||
|
||||
> **TIP**
|
||||
> Avoid working in `/mnt/c/...`.
|
||||
> Clone and work inside your Linux home directory (`/home/<user>`), otherwise file watching and container mounts may behave incorrectly.
|
||||
|
||||
> **TIP**
|
||||
> Docker must be available *inside* WSL. Make sure WSL integration is enabled in Docker Desktop:
|
||||
>
|
||||
> **Docker Desktop → Settings → Resources → WSL Integration → Enable Ubuntu**
|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Clone the Repository (inside WSL)
|
||||
|
||||
Open a WSL terminal (search for "WSL" in the Windows Start menu and open the WSL terminal), then run:
|
||||
|
||||
```bash
|
||||
cd ~
|
||||
git clone https://github.com/Alex-Wiesner/voyage.git
|
||||
cd Voyage
|
||||
```
|
||||
|
||||
> **TIP**
|
||||
> If you plan to contribute changes, fork the repository on GitHub and clone your fork instead:
|
||||
>
|
||||
> ```bash
|
||||
> git clone https://github.com/<your-username>/Voyage.git
|
||||
> ```
|
||||
|
||||
### 2. Create the Development `.env` File (via WSL)
|
||||
|
||||
```bash
|
||||
cp .env.example .env && sed -i 's/^DEBUG=.*/DEBUG=True/' .env
|
||||
```
|
||||
|
||||
This creates the `.env` file required for the containers to start and enables DEBUG for local development.
|
||||
|
||||
> **NOTE**
|
||||
> The rest of the defaults in `.env.example` are sufficient for running the project.
|
||||
|
||||
#### Environment Variables
|
||||
|
||||
The Dev Container setup uses the same `.env` configuration as the standard Docker installation.
|
||||
|
||||
For a full list of available environment variables and optional configuration options, see the
|
||||
[**Docker 🐋 installation guide**](docker.md#configuration).
|
||||
|
||||
### 3. Open the Project in VS Code (via WSL)
|
||||
|
||||
From the project directory:
|
||||
|
||||
```bash
|
||||
code .
|
||||
```
|
||||
|
||||
VS Code should indicate that the folder is opened **in WSL**.
|
||||
|
||||
### 4. Reopen the Project in a Dev Container
|
||||
|
||||
In VS Code:
|
||||
|
||||
1. Press **Ctrl + Shift + P**
|
||||
2. Select **Dev Containers: Reopen in Container**
|
||||
|
||||
VS Code will:
|
||||
|
||||
* Build the development containers
|
||||
* Install dependencies
|
||||
* Attach the editor to the running container
|
||||
|
||||
The first build usually takes around 30 seconds.
|
||||
|
||||
## Running the Application
|
||||
|
||||
Once the Dev Container is running, the services are started using Docker Compose.
|
||||
Use the VS Code terminal (inside the Dev Container) for the commands below.
|
||||
|
||||
To start the app, enter the following command:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml up --build
|
||||
```
|
||||
|
||||
Bringing the app up usually takes around 1-2 minutes.
|
||||
|
||||
To fully reset the database and media volumes, run:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml down -v
|
||||
```
|
||||
|
||||
## Accessing the App
|
||||
|
||||
* **Frontend (Web UI)**
|
||||
[http://localhost:8015](http://localhost:8015)
|
||||
|
||||
* **Backend (API)**
|
||||
[http://localhost:8016](http://localhost:8016)
|
||||
|
||||
Admin credentials are taken from your `.env` file. The `docker-compose.dev.yml` setup auto-creates a superuser on startup using those values so you can log in right away.
|
||||
It also checks whether the countries/flags data already exists before re-importing it, so the first build can take longer and subsequent `down`/`up` runs are faster.
|
||||
This dev setup can feel a bit slower because hot reload, dependency installs, and initial database bootstrapping all happen inside containers.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Docker Not Found Inside WSL
|
||||
|
||||
If you see:
|
||||
|
||||
```
|
||||
The command 'docker' could not be found in this WSL 2 distro
|
||||
```
|
||||
|
||||
Ensure:
|
||||
|
||||
* Docker Desktop is running
|
||||
* WSL integration is enabled for **Ubuntu**
|
||||
* Docker Desktop has been restarted after enabling integration
|
||||
|
||||
### Accidentally Using `/mnt/c`
|
||||
|
||||
If the project lives under `/mnt/c/...`, move it to:
|
||||
|
||||
```bash
|
||||
/home/<user>/Voyage
|
||||
```
|
||||
|
||||
This avoids performance issues and file watcher bugs.
|
||||
|
||||
## Dev vs Production
|
||||
|
||||
| Feature | Docker Install | Dev Container |
|
||||
| ------------ | --------------- | ------------------ |
|
||||
| Intended use | Running the app | Developing the app |
|
||||
| Hot reload | ❌ | ✅ |
|
||||
| Debugging | ❌ | ✅ |
|
||||
| Code editing | ❌ | ✅ |
|
||||
|
||||
For production or personal hosting, follow the standard
|
||||
[**Docker 🐋 installation guide**](docker.md).
|
||||
|
||||
Enjoy contributing to Voyage! 🎉
|
||||
If you run into issues not covered here, please open a discussion or issue so the docs can be improved.
|
||||
92
docs/docs/install/docker.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Docker 🐋
|
||||
|
||||
Docker is the preferred way to run Voyage on your local machine. It is a lightweight containerization technology that allows you to run applications in isolated environments called containers.
|
||||
|
||||
> **Note**: This guide mainly focuses on installation with a Linux-based host machine, but the steps are similar for other operating systems.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker installed on your machine/server. You can learn how to download it [here](https://docs.docker.com/engine/install/).
|
||||
|
||||
## Getting Started
|
||||
|
||||
Get the `docker-compose.yml` and `.env.example` files from the Voyage repository. You can download them here:
|
||||
|
||||
- [Docker Compose](https://github.com/Alex-Wiesner/voyage/blob/main/docker-compose.yml)
|
||||
- [Environment Variables](https://github.com/Alex-Wiesner/voyage/blob/main/.env.example)
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/Alex-Wiesner/voyage/main/docker-compose.yml
|
||||
wget https://raw.githubusercontent.com/Alex-Wiesner/voyage/main/.env.example
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
::: tip
|
||||
|
||||
If running on an ARM based machine, you will need to use a different PostGIS Image. It is recommended to use the `imresamu/postgis:15-3.3-alpine3.21` image or a custom version found [here](https://hub.docker.com/r/imresamu/postgis/tags). The Voyage containers are ARM compatible.
|
||||
|
||||
:::
|
||||
|
||||
## Configuration
|
||||
|
||||
The `.env` file contains all the configuration settings for your Voyage instance. Here’s a breakdown of each section:
|
||||
|
||||
### 🌐 Frontend (web)
|
||||
|
||||
| Name | Required | Description | Default Value |
|
||||
| ------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| `PUBLIC_SERVER_URL` | Yes | Used by the frontend SSR server to connect to the backend. Almost every user user will **never have to change this from default**! | `http://server:8000` |
|
||||
| `ORIGIN` | Sometimes | Needed only if not using HTTPS. Set it to the domain or IP you'll use to access the frontend. | `http://localhost:8015` |
|
||||
| `BODY_SIZE_LIMIT` | Yes | Maximum upload size in bytes. | `Infinity` |
|
||||
| `FRONTEND_PORT` | Yes | Port that the frontend will run on inside Docker. | `8015` |
|
||||
|
||||
### 🐘 PostgreSQL Database
|
||||
|
||||
| Name | Required | Description | Default Value |
|
||||
| ------------------- | -------- | --------------------- | ------------- |
|
||||
| `PGHOST` | Yes | Internal DB hostname. | `db` |
|
||||
| `POSTGRES_DB` | Yes | DB name. | `database` |
|
||||
| `POSTGRES_USER` | Yes | DB user. | `adventure` |
|
||||
| `POSTGRES_PASSWORD` | Yes | DB password. | `changeme123` |
|
||||
|
||||
### 🔒 Backend (server)
|
||||
|
||||
| Name | Required | Description | Default Value |
|
||||
| ----------------------- | -------- | ---------------------------------------------------------------------------------- | --------------------------------------------- |
|
||||
| `SECRET_KEY` | Yes | Django secret key. Change this in production! | `changeme123` |
|
||||
| `DJANGO_ADMIN_USERNAME` | Yes | Default Django admin username. | `admin` |
|
||||
| `DJANGO_ADMIN_PASSWORD` | Yes | Default Django admin password. | `admin` |
|
||||
| `DJANGO_ADMIN_EMAIL` | Yes | Default admin email. | `admin@example.com` |
|
||||
| `PUBLIC_URL` | Yes | Publicly accessible URL of the **backend**. Used for generating image URLs. | `http://localhost:8016` |
|
||||
| `CSRF_TRUSTED_ORIGINS` | Yes | Comma-separated list of frontend/backend URLs that are allowed to submit requests. | `http://localhost:8016,http://localhost:8015` |
|
||||
| `FRONTEND_URL` | Yes | URL to the **frontend**, used for email generation. | `http://localhost:8015` |
|
||||
| `BACKEND_PORT` | Yes | Port that the backend will run on inside Docker. | `8016` |
|
||||
| `DEBUG` | No | Should be `False` in production. | `False` |
|
||||
|
||||
## Optional Configuration
|
||||
|
||||
- [Disable Registration](../configuration/disable_registration.md)
|
||||
- [Google Maps](../configuration/google_maps_integration.md)
|
||||
- [Email Configuration](../configuration/email.md)
|
||||
- [Immich Integration](../configuration/immich_integration.md)
|
||||
- [Umami Analytics](../configuration/analytics.md)
|
||||
|
||||
## Running the Containers
|
||||
|
||||
Once you've configured `.env`, you can start Voyage with:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Frontend type check in Docker (dev/CI)
|
||||
|
||||
Use the development compose file so the frontend container has Node + bun tooling available:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml run --rm --no-deps --build web sh -lc "bun install --frozen-lockfile && bun run check"
|
||||
```
|
||||
|
||||
This runs the Svelte type check fully inside Docker (no host Node/bun required).
|
||||
|
||||
Enjoy using Voyage! 🎉
|
||||
28
docs/docs/install/getting_started.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 🚀 Install Options for Voyage
|
||||
|
||||
Voyage can be installed in a variety of ways, depending on your platform or preference.
|
||||
|
||||
## 📦 Docker Quick Start
|
||||
|
||||
::: tip Quick Start Script
|
||||
**The fastest way to get started:**
|
||||
[Install Voyage with a single command →](quick_start.md)
|
||||
Perfect for Docker beginners.
|
||||
:::
|
||||
|
||||
## 🐳 Popular Installation Methods
|
||||
|
||||
- [Docker](docker.md) — Simple containerized 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/voyage) — Home server app store
|
||||
- [TrueNAS](https://apps.truenas.com/catalog/voyage/) — TrueNAS app catalog
|
||||
|
||||
## ⚙️ Advanced & Alternative Setups
|
||||
|
||||
- [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
|
||||
34
docs/docs/install/kustomize.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Kubernetes and Kustomize (k8s)
|
||||
|
||||
_Voyage can be run inside a kubernetes cluster using [kustomize](https://kustomize.io/)._
|
||||
|
||||
## Prerequisites
|
||||
|
||||
A working kubernetes cluster. Voyage has been tested on k8s, but any Kustomize-capable flavor should be easy to use.
|
||||
|
||||
## Cluster Routing
|
||||
|
||||
Because the Voyage backend must be reachable by **both** the web browser and the Voyage frontend, k8s-internal routing mechanisms traditional for standing up other similar applications **cannot** be used.
|
||||
|
||||
In order to host Voyage in your cluster, you must therefor configure an internally and externally resolvable ingress that routes to your Voyage backend container.
|
||||
|
||||
Once you have made said ingress, set `PUBLIC_SERVER_URL` and `PUBLIC_URL` env variables below to the url of that ingress.
|
||||
|
||||
## Tailscale and Headscale
|
||||
|
||||
Many k8s homelabs choose to use [Tailscale](https://tailscale.com/) or similar projects to remove the need for open ports in your home firewall.
|
||||
|
||||
The [Tailscale k8s Operator](https://tailscale.com/kb/1185/kubernetes/) will set up an externally resolvable service/ingress for your Voyage instance,
|
||||
but it will fail to resolve internally.
|
||||
|
||||
You must [expose tailnet IPs to your cluster](https://tailscale.com/kb/1438/kubernetes-operator-cluster-egress#expose-a-tailnet-https-service-to-your-cluster-workloads) so the Voyage pods can resolve them.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Take a look at the [example config](https://github.com/Alex-Wiesner/voyage/blob/main/kustomization.yml) and modify it for your use case.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Look at the [environment variable summary](docker.md#configuration) in the docker install section to see available and required configuration options.
|
||||
|
||||
Enjoy Voyage! 🎉
|
||||
48
docs/docs/install/nginx_proxy_manager.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Installation with Nginx Proxy Manager
|
||||
|
||||
Nginx Proxy Manager is a simple and powerful tool that allows you to manage Nginx proxy hosts and SSL certificates. It is designed to be easy to use and configure, and it integrates well with Docker.
|
||||
|
||||
It is fairly simple to set up Nginx Proxy Manager with Voyage.
|
||||
|
||||
## Deploy Voyage using Docker
|
||||
|
||||
View the [Docker installation guide](docker.md) for instructions on how to deploy Voyage using Docker.
|
||||
|
||||
## Ensure Correct Environment Variables
|
||||
|
||||
- `ORIGIN` - The domain where you will be hosting Voyage. This is where the **frontend** will be served from.
|
||||
- `PUBLIC_URL` - This needs to match the **outward port of the server** and be accessible from where the app is used. It is used for the creation of image URLs.
|
||||
|
||||
## Setup Docker Network
|
||||
|
||||
Ensure that the Nginx Proxy Manager and Voyage containers are on the same Docker network. You can create a new network using the following command:
|
||||
|
||||
```bash
|
||||
docker network create nginx-proxy-manager
|
||||
```
|
||||
|
||||
Add the following to the bottom of the `docker-compose.yml` file for the Nginx Proxy Manager service and the Voyage service.
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
default:
|
||||
name: nginx-proxy-manager
|
||||
external: true
|
||||
```
|
||||
|
||||
## Setting Up Nginx Proxy Manager
|
||||
|
||||
1. Install Nginx Proxy Manager on your server. You can find the installation instructions [here](https://nginxproxymanager.com/setup/).
|
||||
2. Open the Nginx Proxy Manager web interface and log in with your credentials.
|
||||
3. Add a new proxy host for the Voyage **frontend**:
|
||||
- **Domain Names**: Enter the domain name where you will be hosting Voyage.
|
||||
- **Scheme**: `http`
|
||||
- **Forward Hostname/IP**: `voyage-frontend` The name of the Voyage **frontend** container in the `docker-compose.yml` file.
|
||||
- **Forward Port**: `3000` This is the internal port of the Voyage **frontend** container so you will not need to change it even if you change the external port.
|
||||
4. Add a new proxy host for the Voyage **backend**:
|
||||
- **Domain Names**: Enter the domain name where you will be hosting Voyage.
|
||||
- **Scheme**: `http`
|
||||
- **Forward Hostname/IP**: `voyage-backend` The name of the Voyage **backend** container in the `docker-compose.yml` file.
|
||||
- **Forward Port**: `80` This is the internal port of the Voyage **backend** container so you will not need to change it even if you change the external port.
|
||||
|
||||
This will allow you to access Voyage using the domain name you specified in the Nginx Proxy Manager configuration.
|
||||
4
docs/docs/install/proxmox_lxc.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Proxmox LXC 🐧
|
||||
|
||||
Voyage can be installed in a Proxmox LXC container. This script created by the community will help you install Voyage in a Proxmox LXC container.
|
||||
[Proxmox VE Helper-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts?id=voyage)
|
||||
45
docs/docs/install/quick_start.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 🚀 Quick Start Install
|
||||
|
||||
Install **Voyage** in seconds using our automated script.
|
||||
|
||||
## 🧪 One-Liner Install
|
||||
|
||||
```bash
|
||||
curl -sSL https://get.voyage.app | bash
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
- Check dependencies (Docker, Docker Compose)
|
||||
- Set up project directory
|
||||
- Download required files
|
||||
- Prompt for basic configuration (like domain name)
|
||||
- Start Voyage with Docker Compose
|
||||
|
||||
## ✅ Requirements
|
||||
|
||||
- Docker + Docker Compose
|
||||
- Linux server or VPS
|
||||
- Optional: Domain name for HTTPS
|
||||
|
||||
## 🔍 What It Does
|
||||
|
||||
The script automatically:
|
||||
|
||||
1. Verifies Docker is installed and running
|
||||
2. Downloads `docker-compose.yml` and `.env`
|
||||
3. Prompts you for domain and port settings
|
||||
4. Waits for services to start
|
||||
5. Prints success info with next steps
|
||||
|
||||
## 🧼 Uninstall
|
||||
|
||||
To remove everything:
|
||||
|
||||
```bash
|
||||
cd voyage
|
||||
docker compose down -v
|
||||
rm -rf voyage
|
||||
```
|
||||
|
||||
Need more control? Explore other [install options](getting_started.md) like Docker, Proxmox, Synology NAS, and more.
|
||||
7
docs/docs/install/synology_nas.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Installation on a Synology NAS
|
||||
|
||||
Voyage can be deployed on a Synology NAS using Docker. This guide from Marius Hosting will walk you through the process.
|
||||
|
||||
[Read the guide Here](https://mariushosting.com/how-to-install-voyage-on-your-synology-nas/)
|
||||
|
||||
In recent versions of Synology DSM, there might be some adjustments needed to fix Nginx should a 502 Bad Gateway Error be returned. That guide can be found [here](https://mariushosting.com/synology-nginx-reverse-proxy-how-to-fix-502-bad-gateway-error/).
|
||||
7
docs/docs/install/traefik.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Installation with Traefik
|
||||
|
||||
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.
|
||||
|
||||
Voyage has a built-in Traefik configuration that makes it easy to deploy and manage your Voyage instance.
|
||||
|
||||
The most recent version of the Traefik `docker-compose.yml` file can be found in the [Voyage GitHub repository](https://github.com/Alex-Wiesner/voyage/blob/main/docker-compose-traefik.yaml).
|
||||
77
docs/docs/install/unraid.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Installation with Unraid
|
||||
|
||||
Voyage is available in the Unraid Community Applications store. You can install it by searching for `Voyage` in the Community Applications store, where you will find the frontend and the backend. The database can be found by searching `PostGIS`.
|
||||
|
||||
Community Applications Page for Voyage: [Voyage on CA Store](https://unraid.net/community/apps?q=Voyage)\
|
||||
Community Applications Page for PostGIS: [PostGIS on CA Store](https://unraid.net/community/apps?q=PostGIS)
|
||||
|
||||
## Installation Configuration
|
||||
|
||||
- **Note:** It is recommended to install the applications in the order of these instructions, as failing to do so could cause issues.
|
||||
- Container names can be set to whatever you desire.
|
||||
- Also ensure they are all on the same custom network so they can communicate with one another. You can create one by running the following command in your command line, with `example` being set to your desired name. This network will then show up for selection when making the apps/containers.
|
||||
|
||||
```bash
|
||||
docker network create example
|
||||
```
|
||||
|
||||
## Database
|
||||
|
||||
- Network type should be set to your **custom network**.
|
||||
- There is **no** Voyage---Database app, to find the database application search for `PostGIS` on the Unraid App Store then add and fill out the fields as shown below
|
||||
- Change the repository version to `postgis/postgis:15-3.3`
|
||||
- Ensure that the variables `POSTGRES_DB`, `POSTGRES_USER`, and `POSTGRES_PASSWORD` are set in the `PostGIS` container. If not, then add them as custom variables. The template should have `POSTGRES_PASSWORD` already and you will simply have to add `POSTGRES_DB` and `POSTGRES_USER`.
|
||||
- The forwarded port of `5012` is not needed unless you plan to access the database outside of the container's network.
|
||||
|
||||
| Name | Required | Description | Default Value |
|
||||
| ------------------- | -------- | -------------------------------------------------------------------------------- | ------------- |
|
||||
| `POSTGRES_DB` | Yes | The name of the database in PostGIS. | `N/A` |
|
||||
| `POSTGRES_USER` | Yes | Name of the user generated on first start that will have access to the database. | `N/A` |
|
||||
| `POSTGRES_PASSWORD` | Yes | Password of the user that will be generated on first start. | `N/A` |
|
||||
|
||||
- Here's some visual instructions of how to configure the database template, click the image to open larger version in new tab.\
|
||||
[](/unraid-config-2.png)
|
||||
|
||||
## Backend
|
||||
|
||||
- Network type should be set to your **custom network**.
|
||||
- **Note:** If you're running the server in a docker network that is other than "host" (for example "bridge"), then you need to add the IP of the host machine in the CSRF Trusted Origins variable instead of using localhost. This is only necessary when accessing locally, otherwise you will use the domain name.
|
||||
|
||||
| Name | Required | Description | Default Value |
|
||||
| ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
|
||||
| `API Port` | Yes | This is the port of the backend. This is a port, not a variable. | `8016` |
|
||||
| `PGHOST` | Yes | This is how the backend will access the database. Use the database container's name. | `N/A` |
|
||||
| `PGDATABASE` | Yes | Name of the database in PostGIS to access. | `N/A` |
|
||||
| `PGUSER` | Yes | Name of the user to access with. This is the same as the variable in the database. | `N/A` |
|
||||
| `PGPASSWORD` | Yes | Password of the user it's accessing with. This is the same as the variable in the database. | `N/A` |
|
||||
| `SECRET_KEY` | Yes | Secret Backend Key. Change to anything. | `N/A` |
|
||||
| `DJANGO_ADMIN_USERNAME` | Yes | Default username for admin access. | `admin` |
|
||||
| `DJANGO_ADMIN_EMAIL` | Yes | Default admin user's email. **Note:** You cannot make more than one user with each email. | `N/A` |
|
||||
| `DJANGO_ADMIN_PASSWORD` | Yes | Default password for admin access. Change after initial login. | `N/A` |
|
||||
| `PUBLIC_URL` | Yes | This needs to match how you will connect to the backend, so either local ip with matching port or domain. It is used for the creation of image URLs. | `http://IP_ADDRESS:8016` |
|
||||
| `FRONTEND_URL` | Yes | This needs to match how you will connect to the frontend, so either local ip with matching port or domain. This link should be available for all users. Used for email generation. | `http://IP_ADDRESS:8015` |
|
||||
| `CSRF_TRUSTED_ORIGINS` | Yes | This needs to be changed to the URLs of how you connect to your backend server and frontend. These values are comma-separated and usually the same as the 2 above values. | `http://IP_ADDRESS:8016,http://IP_ADDRESS:8015` |
|
||||
|
||||
- Here's some visual instructions of how to configure the backend template, click the image to open larger version in new tab.\
|
||||
[](/unraid-config-1.png)
|
||||
|
||||
## Frontend
|
||||
|
||||
- Network type should be set to your **custom network**.
|
||||
- **Note:** The default value for `PUBLIC_SERVER_URL` is `http://IP_ADDRESS:8000`, however `IP_ADDRESS` **should be changed** to the name of the backend container for simplicity.
|
||||
|
||||
| Name | Required | Description | Default Value |
|
||||
| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||
| `WEB UI Port` | Yes | The port of the frontend. This is not a variable. | `8015` |
|
||||
| `PUBLIC_SERVER_URL` | Yes | What the frontend SSR server uses to connect to the backend. Change `IP_ADDRESS` to the name of the backend container. | `http://IP_ADDRESS:8000` |
|
||||
| `ORIGIN` | Sometimes | Set to the URL you will access the frontend from, such as localhost with correct port, or set it to the domain of what you will access the app from. | `http://IP_ADDRESS:8015` |
|
||||
| `BODY_SIZE_LIMIT` | Yes | Used to set the maximum upload size to the server. Should be changed to prevent someone from uploading too much! Custom values must be set in **bytes**. | `Infinity` |
|
||||
|
||||
- Here's some visual instructions of how to configure the frontend template, click the image to open larger version in new tab.\
|
||||
[](/unraid-config-3.png)
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Youtuber AlienTech42 has created a helpful video walking through the installation of Voyage on Unraid:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/hJnoePdAhXg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
38
docs/docs/intro/voyage_overview.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# About Voyage
|
||||
|
||||
> **Voyage is a fork of [AdventureLog](https://github.com/seanmorley15/AdventureLog)**, the open-source travel companion created by [Sean Morley](https://seanmorley.com). Voyage builds on AdventureLog's foundation to make additional changes and improvements.
|
||||
|
||||
Voyage is a full-fledged travel companion. With Voyage, 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. **Voyage is the ultimate travel companion for the modern-day explorer**.
|
||||
|
||||
## 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.
|
||||
- Locations can be sorted into custom categories for easy organization.
|
||||
- Locations can be marked as private or public, allowing you to share your adventures with friends and family.
|
||||
- Keep track of the countries and regions you've visited with the world travel book.
|
||||
- Upload trails and activities to your locations to remember your experiences with detailed maps and stats.
|
||||
- **Plan Your Next Trip** 📃: Take the guesswork out of planning your next adventure with an easy-to-use itinerary planner.
|
||||
- Itineraries can be created for any number of days and can include multiple destinations.
|
||||
- A timeline-style day view shows ordered stops with numbered markers and compact location cards (no image banners) for a dense overview. Lodging placement follows directional rules: on check-in day lodging appears after the last stop, on check-out day it appears before the first stop, and on days with no locations a single lodging card is shown (or two cards when a checkout and checkin are different lodgings). Lodging cards use the same compact style (no image header) as location cards within the itinerary.
|
||||
- Connector rows between adjacent items display distance and travel time powered by [OSRM](https://project-osrm.org/) routing (walking if ≤ 20 min, driving otherwise), with automatic haversine fallback when OSRM is unavailable. Self-hosted OSRM instances are supported via the `OSRM_BASE_URL` environment variable. Transportation items appear as compact cards (same style as location cards — no image banners) showing mode, duration, and distance; connector routing uses the transportation's origin coordinates when approaching and destination coordinates when departing. Boundary transitions between lodging and adjacent stops are also shown as connector rows.
|
||||
- Each day has a single `+ Add` control to insert new places, and day-level quick actions include Auto-fill and Optimize (nearest-neighbor ordering for coordinate-backed stops). The day date pill includes a weather temperature summary when available. Lodging added from within a day is automatically scheduled to that day.
|
||||
- Itineraries include many planning features like flight information, notes, checklists, and links to external resources.
|
||||
- Itineraries can be shared with friends and family for collaborative planning.
|
||||
- **Share Your Experiences** 📸: Share your adventures with friends and family and collaborate on trips together.
|
||||
- Locations and itineraries can be shared via a public link or directly with other Voyage users.
|
||||
- Collaborators can view and edit shared itineraries (collections), making planning a breeze.
|
||||
- **Customizable Themes** 🎨: Choose from 10 built-in themes including Light, Dark, Dim, Night, Forest, Aqua, Catppuccin Mocha, Aesthetic Light, Aesthetic Dark, and Northern Lights. Theme selection persists across sessions.
|
||||
- **Travel Agent (MCP) access** 🤖: Voyage exposes an authenticated MCP endpoint so external clients can list collections, inspect itineraries, create itinerary items, and reorder trip timelines. See the [Travel Agent (MCP) guide](../guides/travel_agent.md).
|
||||
|
||||
## Why Voyage?
|
||||
|
||||
Voyage inherits AdventureLog's mission: to provide a modern, open-source, user-friendly alternative to travel apps that are too complex, too expensive, or too closed off. Voyage builds on this foundation with additional changes and improvements.
|
||||
|
||||
### Open Source (GPL-3.0)
|
||||
|
||||
Voyage is open-source software, licensed under the GPL-3.0 license. This means that you are free to use, modify, and distribute Voyage as you see fit. The source code is available on GitHub, and contributions are welcome from anyone who wants to help improve the project.
|
||||
|
||||
## Upstream Project
|
||||
|
||||
Voyage is a fork of [AdventureLog](https://github.com/seanmorley15/AdventureLog), created by [Sean Morley](https://seanmorley.com). Credit and thanks go to Sean and all contributors to the original project for building the foundation that Voyage is built upon.
|
||||
18
docs/docs/troubleshooting/login_unresponsive.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Troubleshooting: Login and Registration Unresponsive
|
||||
|
||||
When you encounter issues with the login and registration pages being unresponsive in Voyage, it can be due to various reasons. This guide will help you troubleshoot and resolve the unresponsive login and registration pages in Voyage.
|
||||
|
||||
1. Check to make sure the backend container is running and accessible.
|
||||
|
||||
- Check the backend container logs to see if there are any errors or issues blocking the container from running.
|
||||
2. Check the connection between the frontend and backend containers.
|
||||
|
||||
- Attempt login with the browser console network tab open to see if there are any errors or issues with the connection between the frontend and backend containers. If there is a connection issue, the code will show an error like `Failed to load resource: net::ERR_CONNECTION_REFUSED`. If this is the case, check the `PUBLIC_SERVER_URL` in the frontend container and refer to the installation docs to ensure the correct URL is set.
|
||||
- If the error is `403`, continue to the next step.
|
||||
|
||||
3. The error most likely is due to a CSRF security config issue in either the backend or frontend.
|
||||
|
||||
- Check that the `ORIGIN` variable in the frontend is set to the URL where the frontend is access and you are accessing the app from currently.
|
||||
- Check that the `CSRF_TRUSTED_ORIGINS` variable in the backend is set to a comma separated list of the origins where you use your backend server and frontend. One of these values should match the `ORIGIN` variable in the frontend.
|
||||
|
||||
4. If you are still experiencing issues, please refer to the [Voyage Discord Server](https://discord.gg/wRbQ9Egr8C) for further assistance, providing as much detail as possible about the issue you are experiencing!
|
||||
45
docs/docs/troubleshooting/nginx_failed.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Troubleshooting: `Starting nginx: nginx failed!` in the Backend Container
|
||||
|
||||
::: tip
|
||||
As of 1-10-2024, this should be resolved in the latest version of Voyage. If you are still experiencing this issue, please reach out to the Voyage community on Discord or GitHub for further assistance.
|
||||
:::
|
||||
|
||||
The Voyage backend container uses a built-in Nginx container with a built-in nginx config that relies on the name `server` to be the service name of the backend container. If the Nginx service fails to start in the backend container, the whole backend service will keep restarting and fail to start.
|
||||
|
||||
**The primary reason for this error is changing the backend service name `server` to something different**
|
||||
|
||||
If you're experiencing issues with the Nginx service failing to start in the backend container, follow these troubleshooting steps to resolve the issue.
|
||||
|
||||
### 1. **Check the `server` Service Name**:
|
||||
|
||||
- Verify that the service name of the backend container is set to `server` in the `docker-compose.yml` file.
|
||||
- The service name should be set to `server` in the `docker-compose.yml` file. For example:
|
||||
```yaml
|
||||
server:
|
||||
image: ghcr.io/alex-wiesner/voyage-backend:latest
|
||||
container_name: voyage-backend
|
||||
```
|
||||
|
||||
### 2. **To keep the backend service name different**:
|
||||
|
||||
- If you want to keep the backend service name different from `server`, you can mount a custom Nginx configuration file to the backend container.
|
||||
|
||||
- Get the default Nginx configuration file from the Voyage repository:
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/Alex-Wiesner/voyage/refs/heads/main/backend/nginx.conf
|
||||
```
|
||||
|
||||
- Update the `nginx.conf` file to replace all occurrences of `server` with your custom service name.
|
||||
- Mount the custom Nginx configuration file to the backend container in the `docker-compose.yml` file. For example:
|
||||
```yaml
|
||||
server:
|
||||
image: ghcr.io/alex-wiesner/voyage-backend:latest
|
||||
container_name: voyage-backend
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
```
|
||||
|
||||
### 3. **Restart the Backend Container**:
|
||||
|
||||
These steps should help you resolve the issue with the Nginx service failing to start in the backend container. If you continue to face issues, please reach out to the Voyage community on Discord or GitHub for further assistance.
|
||||
20
docs/docs/troubleshooting/no_images.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Troubleshooting: Images Not Displayed in Voyage
|
||||
|
||||
The Voyage backend container uses a built-in Nginx container to serve media to the frontend. The `PUBLIC_URL` environment variable is set to the external URL of the **backend** container. This URL is used to generate the URLs for the images in the frontend. If this URL is not set correctly or not accessible from the frontend, the images will not be displayed.
|
||||
|
||||
If you're experiencing issues with images not displaying in Voyage, follow these troubleshooting steps to resolve the issue.
|
||||
|
||||
1. **Check the `PUBLIC_URL` Environment Variable**:
|
||||
|
||||
- Verify that the `PUBLIC_URL` environment variable is set correctly in the `docker-compose.yml` file for the `server` service.
|
||||
- The `PUBLIC_URL` should be set to the external URL of the backend container. For example:
|
||||
```
|
||||
PUBLIC_URL=http://backend.example.com
|
||||
```
|
||||
|
||||
2. **Check `CSRF_TRUSTED_ORIGINS` Environment Variable**:
|
||||
- If you have set the `CSRF_TRUSTED_ORIGINS` environment variable in the `docker-compose.yml` file, ensure that it includes the frontend URL and the backend URL.
|
||||
- For example:
|
||||
```
|
||||
CSRF_TRUSTED_ORIGINS=http://frontend.example.com,http://backend.example.com
|
||||
```
|
||||
42
docs/docs/usage/usage.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# How to use Voyage
|
||||
|
||||
Welcome to Voyage! This guide will help you get started with Voyage and provide you with an overview of the features available to you.
|
||||
|
||||
Voyage also includes a Travel Agent MCP interface for authenticated programmatic trip access and itinerary actions. See the [Travel Agent (MCP) guide](../guides/travel_agent.md).
|
||||
|
||||
## Key Terms
|
||||
|
||||
#### Locations
|
||||
|
||||
::: tip Terminology Update
|
||||
**Location has replaced Adventure:**
|
||||
The term "Location" is now used instead of "Adventure" - the usage remains the same, just the name has changed to better reflect the purpose of the feature.
|
||||
:::
|
||||
|
||||
- **Location**: think of a location as a point on a map, a place you want to visit, have visited, or a place you want to explore. A location can be anything you want it to be, from a local park to a famous landmark. These are the building blocks of Voyage and are the fundamental unit of information in the app.
|
||||
- **Visit**: a visit is added to an location. It contains a date and notes about when the location was visited. If a location is visited multiple times, multiple visits can be added. If there are no visits on a location or the date of all visits is in the future, the location is considered planned. If the date of the visit is in the past, the location is considered completed.
|
||||
- **Category**: a category is a way to group locations together. For example, you could have a category for parks, a category for museums, and a category for restaurants.
|
||||
- **Tag**: a tag is a way to add additional information to a location. For example, you could have a tag for the type of cuisine at a restaurant or the type of art at a museum. Multiple tags can be added to a location.
|
||||
- **Image**: an image is a photo that is added to a location. Images can be added to a location to provide a visual representation or to capture a memory of the visit. These can be uploaded from your device or with a service like [Immich](/docs/configuration/immich_integration) if the integration is enabled.
|
||||
- **Attachment**: an attachment is a file that is added to a location. Attachments can be added to a location to provide additional information, such as a map of the location or a brochure from the visit.
|
||||
- **Trail**: a trail is a path or route that is associated with a location. Trails can be used to document hiking paths, biking routes, or any other type of journey that has a specific path. Trails are linked to locations either by link to an external service (e.g., AllTrails) or from the [Wanderer](/docs/configuration/wanderer_integration) integration. When linked via the Wanderer integration, trails can provide additional context and information about the journey such as distance and elevation gain.
|
||||
- **Activity**: an activity is what you actually do at a location. This can include things like hiking, biking, skiing, kayaking, or any other outdoor activity. Activities are associated with a visit and include fields such as the type of activity, time, distance, and trail taken. They can be manually entered or imported from the [Strava](/docs/configuration/strava_integration) integration. Once an activity is added, it will appear on the location map based on the data from the GPX file.
|
||||
|
||||
#### Collections
|
||||
|
||||
- **Collection**: a collection is a way to group locations together. Collections are flexible and can be used in many ways. When no start or end date is added to a collection, it acts like a folder to group locations together. When a start and end date is added to a collection, it acts like a trip to group locations together that were visited during that time period. With start and end dates, the collection is transformed into a full itinerary with a timeline-style day view — each day displays numbered stops as compact cards (without image banners), connector rows between consecutive locations showing distance and travel time via OSRM routing (walking if ≤ 20 min, driving otherwise) with automatic haversine fallback when OSRM is unavailable, and a single `+ Add` control for inserting new places. Lodging placement follows directional rules: on check-in day it appears after the last stop, on check-out day it appears before the first stop, and on days with no locations a single lodging card is shown (or two cards when a checkout and checkin are different lodgings). Connector rows link lodging to adjacent locations. Day-level quick actions include Auto-fill (populates an empty itinerary from dated records) and Optimize (nearest-neighbor route ordering for coordinate-backed stops). The day date pill displays a weather temperature summary when available, with graceful fallback if weather data is unavailable. The itinerary also includes a map showing the route taken between locations. Your most recently updated collections also appear on the dashboard. For example, you could have a collection for a trip to Europe with dates so you can plan where you want to visit, a collection of local hiking trails, or a collection for a list of restaurants you want to try.
|
||||
- **Transportation**: a transportation is a collection exclusive feature that allows you to add transportation information to your trip. In the itinerary timeline view, transportation items appear as compact cards (same style as location cards — no image banners) showing the travel mode, duration, and distance. Connector rows adjacent to transportation use directional coordinates: the row before a transportation segment measures distance to the transportation's origin, while the row after measures distance from its destination. This can be used to show the route taken between locations and the mode of transportation used. It can also be used to track flight information, such as flight number and departure time.
|
||||
- **Lodging**: a lodging is a collection exclusive feature that allows you to add lodging information to your trip. This can be used to plan where you will stay during your trip and add notes about the lodging location. It can also be used to track reservation information, such as reservation number and check-in time. In the itinerary timeline view, lodging is displayed as compact cards (without image headers) using directional placement: on check-in day the lodging card appears after the last stop, on check-out day it appears before the first stop, and on days with no locations a single card is shown unless the checkout and checkin are different lodgings (in which case both appear). Lodging added from within a specific day is automatically scheduled to that day. Connector rows show boundary transitions between lodging and adjacent locations.
|
||||
- **Note**: a note is a collection exclusive feature that allows you to add notes to your trip. This can be used to add additional information about your trip, such as a summary of the trip or a list of things to do. Notes can be assigned to a specific day of the trip to help organize the information.
|
||||
- **Checklist**: a checklist is a collection exclusive feature that allows you to add a checklist to your trip. This can be used to create a list of things to do during your trip or for planning purposes like packing lists. Checklists can be assigned to a specific day of the trip to help organize the information.
|
||||
|
||||
#### World Travel
|
||||
|
||||
- **World Travel**: the world travel feature of Voyage allows you to track the countries, regions, and cities you have visited during your lifetime. You can add visits to countries, regions, and cities, and view statistics about your travels. The world travel feature is a fun way to visualize where you have been and where you want to go next.
|
||||
- **Country**: a country is a geographical area that is recognized as an independent nation. You can add visits to countries to track where you have been.
|
||||
- **Region**: a region is a geographical area that is part of a country. You can add visits to regions to track where you have been within a country.
|
||||
- **City**: a city is a geographical area that is a populated urban center. You can add visits to cities to track where you have been within a region.
|
||||
|
||||
## Tutorial Video
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/4Y2LvxG3xn4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
305
docs/index.md
Normal file
@@ -0,0 +1,305 @@
|
||||
---
|
||||
# https://vitepress.dev/reference/default-theme-home-page
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: "Voyage"
|
||||
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/voyage_overview
|
||||
- theme: alt
|
||||
text: Demo
|
||||
link: https://demo.voyage.app
|
||||
image:
|
||||
src: ./voyage.svg
|
||||
alt: Voyage 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: 📸
|
||||
---
|
||||
|
||||
## ⚡️ Quick Start
|
||||
|
||||
Get Voyage running in under 60 seconds:
|
||||
|
||||
```bash [One-Line Install]
|
||||
curl -sSL https://get.voyage.app | bash
|
||||
```
|
||||
|
||||
You can also explore our [full installation guide](/docs/install/getting_started) for plenty of options, including Docker, Proxmox, Synology NAS, and more.
|
||||
|
||||
## 📸 See It In Action
|
||||
|
||||
::: 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/Alex-Wiesner/voyage/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, 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/Alex-Wiesner/voyage/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 you’ve 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/Alex-Wiesner/voyage/refs/heads/main/brand/screenshots/map.png" alt="Interactive World Map" style="max-width:100%; margin-top:10px;" />
|
||||
<img src="https://raw.githubusercontent.com/Alex-Wiesner/voyage/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/Alex-Wiesner/voyage/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/Alex-Wiesner/voyage/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/Alex-Wiesner/voyage/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 you’ve visited or plan to visit with an organized list, filtering by visit status. Dive deeper into each country’s regions, complete with interactive maps to help you visually select and track your regional travels.
|
||||
<img src="https://raw.githubusercontent.com/Alex-Wiesner/voyage/refs/heads/main/brand/screenshots/countries.png" alt="Countries List" style="max-width:100%; margin-top:10px;" />
|
||||
<img src="https://raw.githubusercontent.com/Alex-Wiesner/voyage/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 Voyage. 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. Voyage 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—don’t let them be held hostage by closed platforms, hidden fees, or privacy risks. Voyage represents a new era of travel tracking: open, private, comprehensive, and truly yours. Whether you’re a casual traveler, digital nomad, family vacation planner, or anyone who values their adventures, Voyage offers a compelling alternative that puts you back in control.”
|
||||
>
|
||||
> — _Open Source Daily_
|
||||
|
||||
[Article Link](https://opensourcedaily.blog/voyage-private-open-source-travel-tracking-trip-planning/)
|
||||
|
||||
:::
|
||||
|
||||
::: details 📱 **Android Authority**
|
||||
|
||||
> "Voyage 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 Voyage 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
|
||||
|
||||
Voyage is lovingly maintained by passionate developers and supported by amazing users like you:
|
||||
|
||||
- ⭐ [Star us on GitHub](https://github.com/Alex-Wiesner/voyage)
|
||||
- 💬 [Join our Discord community](https://discord.gg/wRbQ9Egr8C)
|
||||
- 🐛 [Report bugs & request features](https://github.com/Alex-Wiesner/voyage/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.voyage.app) • [**📚 Read the Docs**](/docs/intro/voyage_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>
|
||||
14
docs/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"vitepress": "^1.6.4"
|
||||
},
|
||||
"scripts": {
|
||||
"docs:dev": "vitepress dev",
|
||||
"docs:build": "vitepress build",
|
||||
"docs:preview": "vitepress preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"prettier": "^3.7.4",
|
||||
"vue": "^3.5.26"
|
||||
}
|
||||
}
|
||||
1568
docs/pnpm-lock.yaml
generated
Normal file
BIN
docs/public/authentik_settings.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
docs/public/github_settings.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
docs/public/unraid-config-1.png
Normal file
|
After Width: | Height: | Size: 337 KiB |
BIN
docs/public/unraid-config-2.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
docs/public/unraid-config-3.png
Normal file
|
After Width: | Height: | Size: 335 KiB |
BIN
docs/public/voyage.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
303
docs/public/voyage.svg
Normal file
@@ -0,0 +1,303 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="2000"
|
||||
height="2000"
|
||||
viewBox="0 0 529.16665 529.16666"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
sodipodi:docname="AdventureLog.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
inkscape:export-filename="AdventureLog.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="0.35190083"
|
||||
inkscape:cx="1140.9464"
|
||||
inkscape:cy="1112.5293"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1131"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter391"
|
||||
x="-0.59415994"
|
||||
y="-1.3323052"
|
||||
width="2.1926628"
|
||||
height="3.6743487">
|
||||
<!-- Removed feFlood and feGaussianBlur elements -->
|
||||
<feOffset
|
||||
result="offset"
|
||||
in="SourceGraphic"
|
||||
dx="1.000000"
|
||||
dy="1.000000"
|
||||
id="feOffset389" />
|
||||
<feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
id="feComposite388" />
|
||||
<feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite389" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter391"
|
||||
x="-0.59415994"
|
||||
y="-1.3323052"
|
||||
width="2.1926628"
|
||||
height="3.6743487">
|
||||
<feFlood
|
||||
result="flood"
|
||||
in="SourceGraphic"
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
id="feFlood389" />
|
||||
<feGaussianBlur
|
||||
result="blur"
|
||||
in="SourceGraphic"
|
||||
stdDeviation="57.004227"
|
||||
id="feGaussianBlur389" />
|
||||
<feOffset
|
||||
result="offset"
|
||||
in="blur"
|
||||
dx="1.000000"
|
||||
dy="1.000000"
|
||||
id="feOffset389" />
|
||||
<feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="flood"
|
||||
in2="offset"
|
||||
id="feComposite390" />
|
||||
<feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite391" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter393"
|
||||
x="-1.1482379"
|
||||
y="-0.96121423"
|
||||
width="3.3048687"
|
||||
height="2.9294544">
|
||||
<feFlood
|
||||
result="flood"
|
||||
in="SourceGraphic"
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
id="feFlood391" />
|
||||
<feGaussianBlur
|
||||
result="blur"
|
||||
in="SourceGraphic"
|
||||
stdDeviation="57.004227"
|
||||
id="feGaussianBlur391" />
|
||||
<feOffset
|
||||
result="offset"
|
||||
in="blur"
|
||||
dx="1.000000"
|
||||
dy="1.000000"
|
||||
id="feOffset391" />
|
||||
<feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="flood"
|
||||
in2="offset"
|
||||
id="feComposite392" />
|
||||
<feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite393" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter395"
|
||||
x="-1.3398814"
|
||||
y="-1.1275613"
|
||||
width="3.6895566"
|
||||
height="3.2633644">
|
||||
<feFlood
|
||||
result="flood"
|
||||
in="SourceGraphic"
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
id="feFlood393" />
|
||||
<feGaussianBlur
|
||||
result="blur"
|
||||
in="SourceGraphic"
|
||||
stdDeviation="57.004227"
|
||||
id="feGaussianBlur393" />
|
||||
<feOffset
|
||||
result="offset"
|
||||
in="blur"
|
||||
dx="1.000000"
|
||||
dy="1.000000"
|
||||
id="feOffset393" />
|
||||
<feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="flood"
|
||||
in2="offset"
|
||||
id="feComposite394" />
|
||||
<feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite395" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter397"
|
||||
x="-1.8571666"
|
||||
y="-0.84804253"
|
||||
width="4.7279079"
|
||||
height="2.7022837">
|
||||
<feFlood
|
||||
result="flood"
|
||||
in="SourceGraphic"
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
id="feFlood395" />
|
||||
<feGaussianBlur
|
||||
result="blur"
|
||||
in="SourceGraphic"
|
||||
stdDeviation="57.004227"
|
||||
id="feGaussianBlur395" />
|
||||
<feOffset
|
||||
result="offset"
|
||||
in="blur"
|
||||
dx="1.000000"
|
||||
dy="1.000000"
|
||||
id="feOffset395" />
|
||||
<feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="flood"
|
||||
in2="offset"
|
||||
id="feComposite396" />
|
||||
<feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite397" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter427"
|
||||
x="-0.096054554"
|
||||
y="-0.10772674"
|
||||
width="1.1947073"
|
||||
height="1.2117496">
|
||||
<feFlood
|
||||
result="flood"
|
||||
in="SourceGraphic"
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
id="feFlood426" />
|
||||
<feGaussianBlur
|
||||
result="blur"
|
||||
in="SourceGraphic"
|
||||
stdDeviation="13.320559"
|
||||
id="feGaussianBlur426" />
|
||||
<feOffset
|
||||
result="offset"
|
||||
in="blur"
|
||||
dx="1.000000"
|
||||
dy="1.000000"
|
||||
id="feOffset426" />
|
||||
<feComposite
|
||||
result="comp1"
|
||||
operator="in"
|
||||
in="flood"
|
||||
in2="offset"
|
||||
id="feComposite426" />
|
||||
<feComposite
|
||||
result="comp2"
|
||||
operator="over"
|
||||
in="SourceGraphic"
|
||||
in2="comp1"
|
||||
id="feComposite427" />
|
||||
</filter>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g379">
|
||||
<path
|
||||
style="display:inline;fill:#48b5ff;fill-opacity:1;stroke-width:94.45;stroke-dasharray:none"
|
||||
d="m 971.77794,1568.1491 -215.24252,-108.5775 -232.07676,98.4805 -232.07678,98.4806 -0.63034,-550.1231 c -0.34668,-302.56774 0.21559,-550.94143 1.2495,-551.94157 1.03391,-1.00014 105.33804,-45.69109 231.78696,-99.31323 L 754.69512,357.65999 970.68644,466.2139 c 118.79516,59.70465 217.23796,108.5539 218.76156,108.5539 1.5236,0 108.4326,-50.70974 237.5755,-112.68831 129.1428,-61.97858 245.2097,-117.568 257.9264,-123.53205 l 23.1212,-10.84372 -0.6303,551.00102 -0.6303,551.00106 -257.396,123.4976 c -141.5678,67.9237 -258.5206,123.5034 -259.895,123.5104 -1.3745,0.01 -99.3582,-48.8471 -217.74156,-108.5647 z"
|
||||
id="path1"
|
||||
transform="scale(0.26458333)" />
|
||||
<path
|
||||
style="fill:#00ff00;fill-opacity:1;stroke-width:10;stroke-dasharray:none;filter:url(#filter389)"
|
||||
d="m 154.50783,108.88503 c -2.85572,6.51915 -3.99705,17.36183 -0.2277,23.7036 3.00168,5.05017 8.28922,6.62967 13.3295,9.04742 3.90851,1.87485 7.96149,3.93177 11.47307,6.51256 13.62566,10.01398 23.98335,27.67115 20.06743,44.94435 -0.12449,0.54916 -1.48104,7.01695 -1.85641,7.87642 -2.34196,5.36214 -12.56252,15.09064 -18.05999,17.60459 -0.31647,0.14472 -6.14257,1.6119 -6.77744,1.77975 -5.74767,1.51955 -11.84,3.00805 -16.77513,6.51256 -2.81536,1.99923 -13.27557,11.47452 -14.84205,14.54 -0.76687,1.5007 -1.22537,3.14442 -1.97026,4.65615 -2.34545,4.75997 -5.79169,9.60118 -9.20077,13.63154 -3.11382,3.68129 -2.36218,2.17313 -5.86897,5.3764 -6.0653,5.54035 -12.38233,10.68303 -18.66873,15.97822 -2.95625,2.4901 -1.77292,2.02049 -4.80717,4.24024 -4.376145,3.20143 -19.485134,11.83259 -25.104617,8.25513 -5.798267,-3.69128 -1.637855,-18.91136 -2.537182,-24.27052 -0.665342,-3.96483 -2.868842,-7.73278 -3.824359,-11.66126 -1.060926,-4.36186 0.244798,-8.61424 0.415894,-12.95078 0.166198,-4.2124 0.437509,-8.63608 -0.03717,-12.8346 -0.54496,-4.82011 -2.197963,-8.2219 -2.197963,-13.32717 0,-3.83658 -0.26317,-7.9553 0.0395,-11.77513 0.113016,-1.42634 0.682535,-2.78477 0.871283,-4.20307 0.705311,-5.2999 1.237988,-11.08737 0.831787,-16.4336 -0.205095,-2.69936 5.511498,-10.74899 5.093496,-13.38624 -0.980816,-6.18814 -7.14978,-6.25695 -6.304002,-12.32247 0.451585,-3.23855 0.187248,-7.10749 1.740246,-10.07205 0.835928,-1.59571 1.639732,-4.10023 2.915902,-5.3764 3.741116,-3.74112 13.330719,-6.06402 18.250511,-7.60923 3.127833,-0.98238 6.027592,-2.45779 8.975394,-3.86385 3.27336,-1.56136 5.87838,-3.71819 8.93589,-5.60178 3.52017,-2.16861 7.75174,-3.29655 11.51025,-4.96052 11.45567,-5.07163 22.44821,-10.89093 34.60976,-14.01026 z"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="csssscssssssssssssssssssssssssssc" />
|
||||
<path
|
||||
style="fill:#00ff00;fill-opacity:1;stroke-width:10;stroke-dasharray:none;filter:url(#filter393)"
|
||||
d="m 282.71911,236.75014 c -1.07341,-0.51813 -2.0389,-1.39597 -3.22027,-1.55438 -1.88367,-0.25258 -5.13392,0.85934 -7.00513,1.44053 -8.45275,2.62538 -18.44379,6.81757 -22.49075,15.37179 -3.20748,6.77976 -1.80841,13.94405 -1.21283,21.05255 0.70345,8.39597 0.60913,17.64626 3.06924,25.78307 3.80766,12.59377 15.78781,28.09023 29.11717,31.23845 5.76255,1.36104 8.68662,1.0038 15.10925,0.26487 11.5788,-1.33212 23.20626,-7.9298 31.04795,-16.39408 3.10414,-3.3506 5.50955,-7.21715 8.59666,-10.6018 3.18743,-3.49465 5.51775,-7.04064 8.06463,-10.9805 3.48445,-5.39025 5.91,-9.43047 3.44564,-16.12924 -1.0297,-2.79895 -5.0392,-5.98461 -7.08181,-8.10411 -4.91808,-5.10316 -8.81666,-9.96675 -9.42845,-17.30255 -0.51679,-6.19651 0.806,-12.46011 0.11382,-18.62923 -0.87048,-7.75843 -3.35968,-15.22014 -5.56458,-22.67895 -1.97014,-6.66463 -5.2514,-14.24288 -11.70078,-17.79745 -15.70897,-8.65796 -36.07811,2.92981 -49.03591,11.73795 -1.87759,1.2763 -4.03614,1.97474 -5.86898,3.29462 -1.50247,1.08197 -2.65518,2.55672 -4.05205,3.74768 -2.7825,2.37234 -5.73488,4.72293 -8.59435,7.00513 -6.38056,5.09245 -15.28401,9.78925 -16.88899,18.59206 -0.67926,3.72553 7.14966,3.49307 9.04975,3.44332 9.16411,-0.23998 18.38306,-4.78561 26.08975,-9.42615 2.57984,-1.55343 5.60029,-3.28025 8.59434,-3.90103 3.15601,-0.65434 6.73357,-0.98782 9.69333,0.56924 1.40962,0.74156 2.32511,2.61628 3.3713,3.74769 3.81595,4.12676 4.11615,7.5098 -3.21795,6.21052 z"
|
||||
id="path5" />
|
||||
<path
|
||||
style="fill:#00ff00;fill-opacity:1;stroke-width:10;stroke-dasharray:none;filter:url(#filter391)"
|
||||
d="m 99.110381,433.18186 c 4.670059,-2.86644 7.566889,-7.59439 11.398729,-11.3964 11.22457,-11.13721 20.23699,-24.24948 28.43641,-37.74871 5.53049,-9.10519 9.71389,-19.38771 16.16872,-27.90433 3.11752,-4.11332 7.50709,-7.12695 11.43358,-10.41361 4.20791,-3.52221 7.6504,-6.81593 12.8741,-8.67103 15.36185,-5.45544 26.73636,1.95538 38.47129,11.2454 3.5267,2.79191 7.05706,4.28564 10.90616,6.47539 4.29758,2.44485 7.73021,6.21292 12.19102,8.44333 8.94937,4.47469 19.38222,5.65478 29.15668,6.89126 7.14631,0.90405 14.16066,2.50237 21.1664,4.12641 16.46849,3.81768 33.64484,8.74959 32.67668,29.34489 -0.28171,5.99241 -3.32624,12.60742 -8.02513,16.39408 -3.91306,3.15339 -9.22134,3.33169 -13.89873,4.20307 -5.87557,1.09461 -11.90458,2.75058 -17.94615,2.91592 -3.19683,0.0875 -11.4417,-2.50979 -14.9954,-3.33179 -3.80158,-0.87937 -8.26721,-0.9415 -11.73793,-2.84158 -3.87055,-2.11894 -6.90769,-5.47743 -10.45078,-8.0251 -4.87127,-3.50271 -1.08518,-0.58992 -4.96051,-2.91589 -3.30897,-1.98607 -6.204,-4.669 -9.57948,-6.54974 -5.1211,-2.8534 -13.86293,-3.58071 -19.69104,-4.77231 -5.67771,-1.16089 -11.01578,-3.30923 -16.81231,-4.01257 -13.91552,-1.68849 -29.45142,5.70987 -40.9318,13.09947 -2.56659,1.65206 -4.97173,3.56039 -7.42102,5.33924 -2.67583,1.94339 -5.80257,3.32094 -8.7082,4.88384 -7.53479,4.05288 -15.4307,7.2287 -22.90898,11.35922 -2.00201,1.1058 -11.46055,6.02861 -13.17615,5.68079 -1.32827,-0.26929 -2.33944,-2.21337 -3.636159,-1.81925 -2.267678,0.68921 -3.219347,3.63569 -5.339231,4.69564"
|
||||
id="path6" />
|
||||
<path
|
||||
style="fill:#00ff00;fill-opacity:1;stroke-width:10;stroke-dasharray:none;filter:url(#filter395)"
|
||||
d="m 450.19631,298.04907 c -5.5282,0.50496 -11.31189,-0.22132 -16.58461,1.51487 -12.17369,4.0086 -28.70549,15.28393 -34.1172,28.28309 -2.07438,4.98277 -2.95732,10.25334 -3.37129,15.59946 -0.22418,2.89552 -0.0933,5.87015 -0.83177,8.70821 -1.64349,6.31634 -4.7022,13.0625 -8.78488,18.17616 -2.91534,3.65154 -6.67846,6.51549 -10.14873,9.54 -8.24569,7.18651 -23.60925,23.91071 -21.96103,36.31049 0.19262,1.44907 0.77642,2.27965 2.1213,2.87872 2.17652,0.96954 6.3614,-0.53234 8.63153,-0.8341 7.76113,-1.03164 12.12755,-1.31003 19.57718,-5.03486 1.44111,-0.72054 2.84964,-1.3653 4.31694,-2.04462 6.05637,-2.80398 11.89083,-6.01507 17.83461,-9.04973 2.26536,-1.15663 4.74779,-1.77562 7.04231,-2.87642 2.15358,-1.03317 3.83749,-2.63954 5.98281,-3.67334 1.5544,-0.74904 3.25289,-1.02836 4.80949,-1.70307 1.86055,-0.80645 3.54978,-1.97313 5.33924,-2.87872 2.17898,-1.10271 4.61735,-1.2749 6.92846,-1.8936 1.4836,-0.39716 2.68676,-1.23536 4.08921,-1.81692 1.65156,-0.68485 3.50653,-0.57332 5.22539,-0.98512 1.56427,-0.37476 2.48695,-2.11201 3.74769,-2.99024 0.6309,-0.4395 1.52495,-0.5375 2.00745,-1.13618 0.48395,-0.60047 0.25164,-1.54802 0.6064,-2.23279 0.46074,-0.88932 1.51323,-1.21002 1.96794,-2.1213 1.8632,-3.73398 0.31491,-12.51823 0.41823,-16.62178 0.11186,-4.44304 0.41844,-8.86217 0.71795,-13.29 0.23315,-3.44704 -0.22538,-6.93523 -0.22538,-10.3741 0,-1.49648 0.38465,-2.89922 0.30203,-4.39359 -0.0821,-1.48571 -0.45538,-2.97958 -0.45538,-4.46796 0,-3.04234 0.0308,0.34052 0.49258,-2.53484 0.34938,-2.17554 0.005,-4.54488 0.0767,-6.74026 0.0808,-2.47037 0.58761,-4.89522 0.37872,-7.38386 -0.13973,-1.66495 -1.12795,-2.77178 -1.32667,-4.39127 -0.18376,-1.49751 0.63254,-5.63655 0,-6.74026 -0.3973,-0.69326 -1.71445,-0.36851 -2.23282,-0.72027 -0.91319,-0.61968 -1.71622,-1.38785 -2.57435,-2.0818 z"
|
||||
id="path7" />
|
||||
<path
|
||||
style="fill:#00ff00;fill-opacity:1;stroke-width:10;stroke-dasharray:none;filter:url(#filter397)"
|
||||
d="m 375.33553,121.34324 c 3.39913,22.93503 -2.23867,43.81133 -8.17846,65.50203 -3.10168,11.32658 -4.27915,22.46486 -4.96051,34.11486 -0.32861,5.61878 -0.89162,6.02837 -0.26487,12.41872 0.34464,3.51408 1.85081,7.80185 3.29461,11.01768 1.13398,2.52573 4.32978,4.06396 6.85411,4.73282 14.37217,3.80815 26.65789,-2.23088 33.69898,-15.18127 6.74126,-12.399 4.57229,-24.42084 3.86151,-37.75102 -0.38232,-7.17036 -0.76689,-14.97137 -0.26487,-22.11205 0.6106,-8.68483 5.02068,-16.55987 8.71053,-24.231 2.27978,-4.73962 3.62913,-9.80406 5.52744,-14.69103 1.30437,-3.35796 2.65044,-5.86766 3.82436,-9.39129 1.51609,-4.55069 0.62532,-9.15948 1.17333,-13.78023 0.47889,-4.03804 2.7718,-7.5475 3.82436,-11.39873 1.04624,-3.828179 1.90934,-7.787484 2.87872,-11.661277"
|
||||
id="path8" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#afafaf;stroke-width:10;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter427)"
|
||||
d="M 456.91785,381.08869 314.6716,449.29929 199.88458,391.55258 72.03927,445.77735 72.039268,143.494 199.88458,89.269234 314.6716,147.01594 456.91785,78.805342 Z"
|
||||
id="path2-2"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
</g>
|
||||
<path
|
||||
id="rect378"
|
||||
style="fill:#6d6d6d;fill-opacity:0.31908;stroke-width:16.7412"
|
||||
d="m 200.16234,83.744919 114.47572,57.762111 0,313.26052 -114.47572,-57.8148 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/static/img/favicon.png
vendored
Normal file
|
After Width: | Height: | Size: 87 KiB |