MyGround Documentation

Everything you need to self-host your digital life.

Installation

MyGround runs on Linux (x86_64, ARM64) and macOS (Intel, Apple Silicon). The install script handles everything — Docker, the binary, and a systemd/launchd service.

$ curl -fsSL https://myground.online/install.sh | sh

Package Managers

MyGround is also available through system package managers:

# Arch Linux (AUR)
$ yay -S myground

# macOS (Homebrew)
$ brew tap backmeupplz/myground && brew install myground

# Debian / Ubuntu (APT)
$ curl -fsSL https://myground.online/apt/myground.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/myground.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/myground.gpg] https://myground.online/apt stable main" | sudo tee /etc/apt/sources.list.d/myground.list
$ sudo apt update && sudo apt install myground
Note: The install script is the recommended method — it also installs Docker and sets up a systemd/launchd service. Package manager installs only provide the binary.

What the script does:

After installation, open http://<your-ip>:8080 in your browser.

Tip: To install to a custom data directory, set MYGROUND_DATA_DIR before running the script, or use myground start --data-dir /path.

First Setup

On first visit, you'll be prompted to create an admin account. Pick a strong password — this protects your entire server.

After setup, you're taken to the dashboard. From here you can install apps, configure backups, and set up remote access.

The Dashboard

The dashboard shows:

The sidebar gives you access to Backups, Tailscale, Cloudflare, Updates, and Settings.

App Catalog

MyGround ships with 13 curated apps. Each includes a Docker Compose template, health checks, and backup support.

AppCategoryReplacesFeatures
ImmichPhotosGoogle PhotosGPU, PostgreSQL backup
JellyfinMediaNetflix / PlexGPU, hardware transcoding
NavidromeMusicSpotifySubsonic-compatible clients
NextcloudProductivityGoogle Drive / CalendarMariaDB backup, office suite
VaultwardenSecurityBitwardenRequires HTTPS
Pi-holeNetworkAd blockersDNS server, Tailscale DNS
qBittorrentDownloadsDesktop torrent clientsWeb UI, VPN support
MemosProductivityNote-taking appsLightweight memo hub
File BrowserFilesFile managersWeb-based file access
BeszelMonitoringGrafana (lightweight)Docker stats, alerts
AudiobookshelfMediaAudibleAudiobooks, podcasts, progress sync
MeTubeDownloadsYouTube downloadersyt-dlp web UI
KavitaMediaCalibre-web, KomgaManga, comics, ebooks, OPDS
Open WebUIAIChatGPT UILLM web interface, works with Ollama
OllamaAILocal LLM runner, GPU support
GiteaDevelopmentGitHub, GitLabSelf-hosted Git, issues, PRs
Firefly IIIFinanceMint, YNABTransactions, budgets, financial goals
Home AssistantAutomationSmartThingsSmart home control, automations
VaneAIPerplexityAI search, local LLM support
MealieLifestylePaprika, TandoorRecipes, meal planning, shopping lists
WhoamiUtilitiesTest / demo app

Installing & Managing Apps

From the dashboard, click Add App, pick an app, and fill in any required variables (passwords, media paths, etc). MyGround pulls the Docker images and starts the containers.

For each installed app you can:

CLI equivalent:

$ myground app install immich
$ myground app start immich
$ myground app stop immich
$ myground app remove immich
$ myground app list

Storage Paths

Each app defines one or more storage volumes (e.g., Immich has "upload", "ml_cache", and "db_data"). By default, these are stored under ~/.myground/apps/<app-id>/volumes/.

You can change any volume's path to point to a different disk — useful for putting large media on a dedicated drive while keeping databases on an SSD.

Change storage paths via the app's Manage → Storage tab, or set a global default in Settings.

Backup Overview

MyGround uses Restic for backups. Restic runs inside a Docker container — no installation needed. Backups are incremental, encrypted, and deduplicated.

Key concepts:

Destinations

Supported backup destinations:

TypeRepository format
Local disk/path/to/backups
Amazon S3s3:s3.amazonaws.com/bucket
Backblaze B2s3:s3.us-west-001.backblazeb2.com/bucket
Wasabis3:s3.wasabisys.com/bucket
MinIOs3:minio.example.com/bucket

Set a default destination in Settings → Backups, or configure per-job in each app's backup settings.

For S3 destinations, MyGround includes an AWS setup wizard that configures IAM credentials and bucket access.

CLI configuration:

$ myground backup configure s3:s3.amazonaws.com/mybucket my-encryption-password
$ myground backup init

Scheduling Jobs

Each app can have multiple backup jobs with different schedules and destinations. Create jobs in the app's Manage → Backups tab.

Schedule options:

You can also trigger a backup manually at any time:

$ myground backup run            # all apps
$ myground backup run immich     # specific app

Browsing & Restoring

Browse all snapshots in the Backups page. Click a snapshot to see its files, then restore it.

File restore: Choose a target directory and restore the snapshot's files there. If restoring to the original location, you'll be asked to confirm (data will be overwritten).

Database restore: For database snapshots (PostgreSQL, MariaDB), MyGround extracts the dump from the snapshot, wipes the existing database, and imports the backup. A confirmation is required since this replaces all current data.

Restore progress (extracting, wiping, importing) is shown in real-time.

CLI restore:

$ myground backup snapshots
$ myground backup restore abc123 --target /tmp/restore

Crash Recovery

If the server crashes or reboots mid-backup, MyGround automatically detects the interrupted job on startup and re-runs it. Restic handles incremental backups natively, so re-running is safe and efficient — only new or changed data is uploaded.

Tailscale

Tailscale gives each app its own VPN address with automatic HTTPS. Set it up from the Tailscale page in the sidebar.

  1. Generate an auth key at Tailscale admin
  2. Enter the key in MyGround's Tailscale settings
  3. Enable Tailscale per-app — each gets a sidecar container with its own Tailscale node

Features:

CLI:

$ myground tailscale enable tskey-auth-xxxxx
$ myground tailscale status
$ myground tailscale disable
Note: Vaultwarden requires HTTPS to function. Tailscale (or Cloudflare Tunnel) is required to use it.

Cloudflare Tunnel

Expose apps to the public internet through Cloudflare Tunnel. No port forwarding needed.

  1. Create a Cloudflare API token with Zone and Tunnel permissions
  2. Enter the token in MyGround's Cloudflare settings
  3. Select your zone (domain) and bind apps to subdomains

MyGround automatically creates the tunnel, configures ingress rules, and runs a cloudflared container.

LAN Access

By default, apps are accessible on your local network at http://<server-ip>:<port>. You can toggle LAN access per-app from the app's settings page.

VPN (Gluetun)

Route any app's traffic through a VPN using Gluetun. This is especially useful for qBittorrent.

Configure your VPN provider credentials in the app's Manage → VPN tab, or set a global default in Settings that applies to all new apps. MyGround injects a Gluetun sidecar container and routes the app's network through it. Supports WireGuard, OpenVPN, and 60+ providers.

GPU Acceleration

Enable GPU pass-through for apps that support it (Immich for ML processing, Jellyfin for hardware transcoding).

Supported GPUs:

MyGround auto-detects available GPUs on your system. Toggle GPU per-app from the app's Manage page. The app restarts automatically to apply the change.

Disk Management

The Settings page shows all mounted disks with used/available space. MyGround also runs SMART health checks to warn about failing drives.

CLI:

$ myground disk list      # space info for all disks
$ myground disk health    # SMART health status

CLI Reference

The myground binary is both the server and the CLI. Every action in the web UI is available from the command line.

Global Options

FlagDescription
--data-dir PATHData directory (default: ~/.myground)
--username USERAdmin username for authentication
--password PASSAdmin password for authentication
--api-key KEYAPI key (or set MYGROUND_API_KEY env var)

Commands

# Server
$ myground start                          # Start server (default: localhost:8080)
$ myground start --address 0.0.0.0 --port 9000
$ myground status                         # Show platform and app status

# Authentication
$ myground login                          # Interactive login
$ myground logout                         # Remove session

# Apps
$ myground app list                       # List all apps with status
$ myground app install jellyfin           # Install an app
$ myground app start jellyfin             # Start app containers
$ myground app stop jellyfin              # Stop app containers
$ myground app remove jellyfin            # Remove app and data

# Backups
$ myground backup configure REPO PASSWORD # Set backup destination
$ myground backup init                    # Initialize repository
$ myground backup run                     # Backup all apps
$ myground backup run immich              # Backup one app
$ myground backup snapshots               # List snapshots
$ myground backup restore SNAPSHOT_ID --target /path

# Disks
$ myground disk list                      # Disk space info
$ myground disk health                    # SMART health status

# Tailscale
$ myground tailscale status               # Show Tailscale status
$ myground tailscale enable AUTH_KEY      # Enable with auth key
$ myground tailscale disable              # Disable Tailscale

# Destructive
$ myground nuke                           # Stop all, delete everything

REST API

MyGround exposes a full REST API at /api/*. The same API powers both the web UI and the CLI — every action you can perform in the UI is available as an API call.

The API is documented with an OpenAPI 3.1 specification. An interactive Swagger UI is built into every MyGround instance:

 http://<your-server>:8080/api/docs

From Swagger UI you can browse all endpoints, see request/response schemas, and try requests live. The raw OpenAPI JSON spec is at /api/docs/openapi.json.

Example API call:

$ curl -H "Authorization: Bearer YOUR_API_KEY" \
    http://localhost:8080/api/apps

$ curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \
    http://localhost:8080/api/apps/jellyfin/start
Tip: Point AI agents at /api/docs/openapi.json — they can parse the full spec and discover all available endpoints automatically.

API Keys

API keys allow programmatic access without username/password. Create and manage them in Settings → API Keys or via the API.

# Authenticate with API key
$ curl -H "Authorization: Bearer YOUR_API_KEY" \
    http://localhost:8080/api/apps

# Or use the CLI
$ myground --api-key YOUR_API_KEY app list

# Or set an environment variable
$ export MYGROUND_API_KEY=YOUR_API_KEY
$ myground app list

API keys are stored as bcrypt hashes — the plaintext is shown only once at creation time. Each key has a name for identification and can be revoked individually.

AI Agents

MyGround is designed to be managed by AI agents. The full OpenAPI specification means any agent that understands REST APIs can manage your server.

How to set it up:

  1. Create an API key in Settings
  2. Give your AI agent the server URL and API key
  3. Point it at /api/docs/openapi.json — the full OpenAPI 3.1 spec the agent can parse to discover all endpoints, schemas, and parameters automatically

What an agent can do:

The CLI works equally well — pipe commands through SSH for remote management:

$ ssh myserver "myground --api-key $KEY status"
When something breaks at 3 AM, your AI agent can check health endpoints, read app logs, restart containers, and even trigger a restore from backup — all without waking you up.

Auto-Updates

MyGround checks for updates every 6 hours. Configure in Settings → Updates:

Both can be toggled independently. Manual update checks and installs are always available in the Updates page.

Troubleshooting

Docker services unreachable when using Tailscale exit node

Symptoms: Docker containers start and show as "Running" but accessing the service on its assigned port hangs indefinitely.

Cause: When your machine routes traffic through a Tailscale exit node, Tailscale adds a default route in its routing table (table 52) that captures all traffic — including packets destined for Docker's bridge subnets (172.16.0.0/12). Packets are sent through tailscale0 instead of docker0.

Confirm:

$ ip route get 172.17.0.3
# If output shows "dev tailscale0" instead of "dev docker0", this is the issue

Fix: Add a routing policy rule that forces Docker bridge traffic through the main table:

$ sudo ip rule add from all to 172.16.0.0/12 lookup main priority 5200

Verify:

$ ip route get 172.17.0.3
# Should now show "dev docker0" or "dev br-*"
Important: This rule is not persistent across reboots. Add it to a systemd service or network configuration script to make it permanent. This only affects machines that are clients of a Tailscale exit node — the exit node server itself is not affected.

Vaultwarden shows a blank page

Vaultwarden's web vault requires HTTPS. Enable Tailscale or Cloudflare Tunnel for the app, then access it via the HTTPS URL.

App stuck in "Starting" state

Check the app's logs in Manage → Logs. Common causes:

Backup fails with "repository not found"

The backup repository needs to be initialized first. Go to Backups → Settings and click "Initialize Repository", or run:

$ myground backup init

Data Directory

By default, MyGround stores everything in ~/.myground/:

~/.myground/
├── auth.toml                # Admin account, API keys
├── global.toml              # Global config (defaults, updates)
├── tailscale.toml           # Tailscale configuration
├── cloudflare.toml          # Cloudflare Tunnel configuration
└── apps/
    └── <app-id>/
        ├── config.toml      # App state, backup jobs, storage paths
        ├── docker-compose.yml
        ├── .env
        └── volumes/         # Default storage location

Override with --data-dir or the MYGROUND_DATA_DIR environment variable.