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
What the script does:
- Detects your OS and architecture
- Installs Docker if not present (Debian/Ubuntu, Arch, Fedora)
- Downloads the latest
mygroundbinary from GitHub Releases - Verifies SHA-256 checksums
- Creates a systemd service (Linux) or LaunchAgent (macOS)
- Starts the server on port 8080
After installation, open http://<your-ip>:8080 in your browser.
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:
- System stats — CPU and RAM usage, GPU if available
- Installed apps — Status (Running/Stopped), health indicator, quick actions
- Add App — Browse and install from the app catalog
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.
| App | Category | Replaces | Features |
|---|---|---|---|
| Immich | Photos | Google Photos | GPU, PostgreSQL backup |
| Jellyfin | Media | Netflix / Plex | GPU, hardware transcoding |
| Navidrome | Music | Spotify | Subsonic-compatible clients |
| Nextcloud | Productivity | Google Drive / Calendar | MariaDB backup, office suite |
| Vaultwarden | Security | Bitwarden | Requires HTTPS |
| Pi-hole | Network | Ad blockers | DNS server, Tailscale DNS |
| qBittorrent | Downloads | Desktop torrent clients | Web UI, VPN support |
| Memos | Productivity | Note-taking apps | Lightweight memo hub |
| File Browser | Files | File managers | Web-based file access |
| Beszel | Monitoring | Grafana (lightweight) | Docker stats, alerts |
| Audiobookshelf | Media | Audible | Audiobooks, podcasts, progress sync |
| MeTube | Downloads | YouTube downloaders | yt-dlp web UI |
| Kavita | Media | Calibre-web, Komga | Manga, comics, ebooks, OPDS |
| Open WebUI | AI | ChatGPT UI | LLM web interface, works with Ollama |
| Ollama | AI | — | Local LLM runner, GPU support |
| Gitea | Development | GitHub, GitLab | Self-hosted Git, issues, PRs |
| Firefly III | Finance | Mint, YNAB | Transactions, budgets, financial goals |
| Home Assistant | Automation | SmartThings | Smart home control, automations |
| Vane | AI | Perplexity | AI search, local LLM support |
| Mealie | Lifestyle | Paprika, Tandoor | Recipes, meal planning, shopping lists |
| Whoami | Utilities | — | Test / 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:
- Start / Stop — Toggle the app's containers
- Manage — View logs, storage, backup config, health status
- Remove — Stop containers and delete app data
- Rename — Change the display name
- Open — Access the app's web UI (via LAN, Tailscale, or Cloudflare)
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:
- Backup Job — A named backup task for an app, targeting a specific destination
- Destination — Where backups go (local disk or S3-compatible storage)
- Snapshot — A point-in-time backup. Browse files, restore, or delete
- Database dump — For apps with databases (Immich, Nextcloud), MyGround dumps the database before backing up, ensuring consistency
Destinations
Supported backup destinations:
| Type | Repository format |
|---|---|
| Local disk | /path/to/backups |
| Amazon S3 | s3:s3.amazonaws.com/bucket |
| Backblaze B2 | s3:s3.us-west-001.backblazeb2.com/bucket |
| Wasabi | s3:s3.wasabisys.com/bucket |
| MinIO | s3: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:
- Daily — Runs at 2:00 AM UTC
- Weekly — Runs once per week at 2:00 AM UTC
- Monthly — Runs once per month at 2:00 AM UTC
- Cron — Standard 5-field cron expression (e.g.,
0 3 * * 1-5for weekdays at 3 AM) - Manual — No schedule, trigger via UI or API only
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.
- Generate an auth key at Tailscale admin
- Enter the key in MyGround's Tailscale settings
- Enable Tailscale per-app — each gets a sidecar container with its own Tailscale node
Features:
- Per-app sidecar — Each app gets its own Tailscale identity and HTTPS certificate via MagicDNS
- Exit node — Use your server as a Tailscale exit node, routing all your traffic through your home network
- Pi-hole DNS — Route DNS through Pi-hole when using the exit node for network-wide ad blocking on the go
- Auto-cleanup — When you remove an app, its Tailscale sidecar is automatically stopped and logged out
CLI:
$ myground tailscale enable tskey-auth-xxxxx
$ myground tailscale status
$ myground tailscale disable
Cloudflare Tunnel
Expose apps to the public internet through Cloudflare Tunnel. No port forwarding needed.
- Create a Cloudflare API token with Zone and Tunnel permissions
- Enter the token in MyGround's Cloudflare settings
- 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:
- NVIDIA — Requires NVIDIA Container Toolkit. MyGround adds
runtime: nvidiato the Docker Compose config. - Intel iGPU / AMD — MyGround maps
/dev/driinto the container for VA-API acceleration.
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
| Flag | Description |
|---|---|
--data-dir PATH | Data directory (default: ~/.myground) |
--username USER | Admin username for authentication |
--password PASS | Admin password for authentication |
--api-key KEY | API 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
/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:
- Create an API key in Settings
- Give your AI agent the server URL and API key
- 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:
- Install, start, stop, and remove apps
- Trigger and monitor backups
- Check system health, disk space, and app status
- Configure networking (Tailscale, Cloudflare)
- Read logs and diagnose issues
- Manage storage paths and updates
The CLI works equally well — pipe commands through SSH for remote management:
$ ssh myserver "myground --api-key $KEY status"
Auto-Updates
MyGround checks for updates every 6 hours. Configure in Settings → Updates:
- Auto-update apps — Automatically pull new container images and restart apps
- Auto-update MyGround — Automatically download and install new binary versions
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-*"
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:
- Port conflict — another service is using the same port
- Docker image pull failure — check internet connectivity
- Permission issues on storage paths
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.