Skip to main content
Photo of Anton ShubinAnton ShubinContact

rostok one-command scaffolder for a self-hosted homelab In use

Scaffold a self-hosted homelab from a curated catalog.

Run rostok in an empty folder and answer a few questions: the server's name, its SSH address, your domain and email. The wizard turns that into a Git repo with one folder per server, and a deploy copies the files to the server over SSH and starts them with Docker Compose.

1 min 28 s, with captions and music: install rostok, answer the wizard, pick Traefik and OmniTools from the catalog, deploy to the server, then use OmniTools at its own HTTPS address.
deno install -g -A -n rostok jsr:@rostok/cli@1.28.0

From JSR, pinned to 1.28.0.

Three commands

  1. rostok

    Wizard: init → server create → stack add

  2. rostok stack list

    Browse the bundled catalog

  3. rostok deploy home

    Deploy what you configured

The catalog

49 stacks. Each is an ordinary Docker Compose file you can read and change.

AI6 stacks

  • caldav-mcpCalDAV MCP server for AI assistants: events and tasks (spy4x/caldav-mcp)

    Asks for: CALDAV_MCP_SERVER_URLCALDAV_MCP_USERNAMECALDAV_MCP_PASSWORDCALDAV_MCP_TOKEN

    Secrets: CALDAV_MCP_PASSWORDCALDAV_MCP_TOKENCALDAV_MCP_OWNER_PASSWORD_HASHCALDAV_MCP_AUTH_PEPPEREncrypted into .env.age, so the repo is safe to push.

    rostok stack add caldav-mcp --server=home

    This tool's page

  • email-mcpEmail MCP server (IMAP and SMTP) for AI assistants (ai-zerolab/mcp-email-server)

    Asks for: EMAIL_MCP_TOKENEMAIL_MCP_HOSTEMAIL_MCP_USEREMAIL_MCP_PASSWORDEMAIL_MCP_ACCOUNT_NAMEEMAIL_MCP_ACCOUNT_NAME_2

    Secrets: EMAIL_MCP_TOKENEMAIL_MCP_PASSWORDEMAIL_MCP_PASSWORD_2Encrypted into .env.age, so the repo is safe to push.

    rostok stack add email-mcp --server=home
  • github-mcpGitHub MCP server over Streamable HTTP for AI assistants

    Asks for: GITHUB_MCP_TOKEN

    Secrets: GITHUB_MCP_TOKENEncrypted into .env.age, so the repo is safe to push.

    rostok stack add github-mcp --server=home
  • google-maps-mcpGoogle Maps MCP server: places, geocoding, directions, weather

    Asks for: GOOGLE_MAPS_MCP_API_KEY

    Secrets: GOOGLE_MAPS_MCP_API_KEYEncrypted into .env.age, so the repo is safe to push.

    rostok stack add google-maps-mcp --server=home
  • ollamaLocal LLM server with an OpenAI-compatible API (NVIDIA GPU required)

    Asks for: OLLAMA_DOMAINOLLAMA_CPU_LIMITOLLAMA_MEM_LIMIT

    Secrets: none

    rostok stack add ollama --server=home
  • open-webuiChat UI for local and hosted LLMs (open-webui/open-webui)

    Asks for: OPEN_WEBUI_DOMAINOPEN_WEBUI_WEBUI_SECRET_KEYOPEN_WEBUI_MCPO_API_KEYOPEN_WEBUI_ENABLE_IMAGE_GENERATIONOPEN_WEBUI_ENABLE_RAG_LOCAL_WEB_FETCHOPEN_WEBUI_ENABLE_WEB_SEARCHOPEN_WEBUI_WEB_SEARCH_ENGINEOPEN_WEBUI_SEARXNG_QUERY_URLOPEN_WEBUI_WEB_SEARCH_RESULT_COUNTOPEN_WEBUI_BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVALOPEN_WEBUI_ENABLE_OLLAMA_APIOPEN_WEBUI_OLLAMA_API_BASE_URLOPEN_WEBUI_OLLAMA_BASE_URLOPEN_WEBUI_ENABLE_PLAYWRIGHT_MCPOPEN_WEBUI_ENABLE_CALDAV_MCPOPEN_WEBUI_ENABLE_EMAIL_MCPOPEN_WEBUI_ENABLE_GOOGLE_MAPS_MCPOPEN_WEBUI_ENABLE_GITHUB_MCPOPEN_WEBUI_DEFAULT_USER_ROLEOPEN_WEBUI_ENABLE_SIGNUPOPEN_WEBUI_ENABLE_LOGIN_FORMOPEN_WEBUI_RAG_TOP_KOPEN_WEBUI_RAG_FILE_MAX_COUNTOPEN_WEBUI_RAG_FILE_MAX_SIZEOPEN_WEBUI_ENABLE_PERSISTENT_CONFIGOPEN_WEBUI_WEBUI_NAME

    Secrets: OPEN_WEBUI_OPENAI_API_KEYSOPEN_WEBUI_WEBUI_SECRET_KEYOPEN_WEBUI_HF_TOKENOPEN_WEBUI_MCPO_API_KEYOPEN_WEBUI_CALDAV_MCP_TOKENOPEN_WEBUI_EMAIL_MCP_TOKENEncrypted into .env.age, so the repo is safe to push.

    rostok stack add open-webui --server=home

Auth1 stack

  • autheliaSingle sign-on portal (Authelia) for services behind Traefik

    Asks for: AUTHELIA_DOMAINAUTHELIA_SESSION_SECRETAUTHELIA_STORAGE_ENCRYPTION_KEYAUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRETAUTHELIA_ADMIN_USERAUTHELIA_ADMIN_EMAILAUTHELIA_ADMIN_PASSWORD

    Secrets: AUTHELIA_SESSION_SECRETAUTHELIA_STORAGE_ENCRYPTION_KEYAUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRETAUTHELIA_ADMIN_PASSWORDAUTHELIA_SMTP_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add authelia --server=home

Communication1 stack

  • mirotalkPeer-to-peer video calls with a bundled TURN relay (MiroTalk P2P + coturn)

    Asks for: MIROTALK_DOMAINMIROTALK_PUBLIC_IPMIROTALK_TURN_SERVER_USERNAMEMIROTALK_TURN_SERVER_CREDENTIALMIROTALK_JWT_KEYMIROTALK_API_KEY_SECRET

    Secrets: MIROTALK_TURN_SERVER_USERNAMEMIROTALK_TURN_SERVER_CREDENTIALMIROTALK_JWT_KEYMIROTALK_API_KEY_SECRETEncrypted into .env.age, so the repo is safe to push.

    rostok stack add mirotalk --server=home

Dev tools2 stacks

  • giteaSelf-hosted Git service (gitea/gitea + Postgres)

    Asks for: GITEA_DOMAINGITEA_DB_PASSWORDGITEA_SMTP_HOSTGITEA_SMTP_PORTGITEA_SMTP_USERNAMEGITEA_SMTP_PASSWORDGITEA_SMTP_FROM

    Secrets: GITEA_DB_PASSWORDGITEA_SMTP_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add gitea --server=home
  • woodpeckerCI server and Docker agent (woodpeckerci) with GitHub sign-in

    Asks for: WOODPECKER_DOMAINWOODPECKER_AGENT_SECRETWOODPECKER_GITHUB_CLIENTWOODPECKER_GITHUB_SECRETWOODPECKER_ADMIN

    Secrets: WOODPECKER_AGENT_SECRETWOODPECKER_GITHUB_SECRETEncrypted into .env.age, so the repo is safe to push.

    rostok stack add woodpecker --server=home

Home1 stack

  • home-assistantOpen source home automation, host networking for LAN device discovery

    Asks for: HOME_ASSISTANT_ZIGBEE_DEVICEHOME_ASSISTANT_CPU_LIMITHOME_ASSISTANT_MEM_LIMIT

    Secrets: none

    rostok stack add home-assistant --server=home

Infrastructure5 stacks

  • docker-registryPrivate Docker registry with a web UI (registry:2 + joxit/docker-registry-ui)

    Asks for: DOCKER_REGISTRY_DOMAINDOCKER_REGISTRY_USERDOCKER_REGISTRY_PASSWORD

    Secrets: DOCKER_REGISTRY_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add docker-registry --server=home
  • docker-sock-proxyFiltered Docker API for containers that need it (tecnativa/docker-socket-proxy)

    Asks for: none

    Secrets: none

    rostok stack add docker-sock-proxy --server=home
  • syncthingContinuous file sync between servers (syncthing/syncthing)

    Asks for: SYNCTHING_DOMAINSYNCTHING_API_KEYSYNCTHING_GUI_USERSYNCTHING_GUI_PASSWORDSYNCTHING_CPU_LIMITSYNCTHING_MEM_LIMIT

    Secrets: SYNCTHING_API_KEYSYNCTHING_GUI_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add syncthing --server=home
  • watchtowerAutomatic Docker container image updates (nickfedor/watchtower)

    Asks for: WATCHTOWER_CPU_LIMITWATCHTOWER_MEM_LIMIT

    Secrets: none

    rostok stack add watchtower --server=home
  • wireguardWireGuard VPN server (linuxserver/wireguard)

    Asks for: WIREGUARD_DOMAINWIREGUARD_PEERSWIREGUARD_DNS

    Secrets: none

    rostok stack add wireguard --server=home

Media6 stacks

  • audiobookshelfAudiobook and ebook server (advplyr/audiobookshelf)

    Asks for: AUDIOBOOKSHELF_DOMAINPATH_BOOKS

    Secrets: none

    rostok stack add audiobookshelf --server=home
  • immichPhoto library with machine learning and kiosk slideshow (immich-app/immich)

    Asks for: IMMICH_DOMAINIMMICH_KIOSK_DOMAINIMMICH_DB_PASSWORDIMMICH_KIOSK_PASSWORDPATH_PHOTOS

    Secrets: IMMICH_DB_PASSWORDIMMICH_KIOSK_PASSWORDIMMICH_MCP_API_KEYIMMICH_KIOSK_API_KEYEncrypted into .env.age, so the repo is safe to push.

    rostok stack add immich --server=home
  • jellyfinSelf-hosted media server (movies, TV, music, books)

    Asks for: JELLYFIN_DOMAINPATH_MEDIAPATH_VIDEOSPATH_MUSIC

    Secrets: none

    rostok stack add jellyfin --server=home
  • metubeWeb front end for yt-dlp downloads (alexta69/metube)

    Asks for: METUBE_DOMAINPATH_VIDEOSPATH_MUSIC

    Secrets: none

    rostok stack add metube --server=home
  • pipedPrivacy-friendly YouTube front end (TeamPiped/Piped)

    Asks for: PIPED_DOMAINPIPED_API_DOMAINPIPED_PROXY_DOMAINPIPED_DB_NAMEPIPED_DB_USERPIPED_DB_PASSWORD

    Secrets: PIPED_DB_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add piped --server=home
  • transmissionBitTorrent client with web UI (linuxserver/transmission)

    Asks for: TRANSMISSION_DOMAINPATH_MOVIESPATH_SERIESPATH_MUSICPATH_BOOKSPATH_OTHER

    Secrets: none

    rostok stack add transmission --server=home

Monitoring7 stacks

  • gatusLightweight health-check status page with ntfy alerting

    Asks for: GATUS_DOMAINGATUS_NTFY_TOPIC_UPTIMEGATUS_CPU_LIMITGATUS_MEM_LIMIT

    Secrets: GATUS_BASIC_AUTH_BASE64GATUS_NTFY_TOKEN_UPTIMEEncrypted into .env.age, so the repo is safe to push.

    rostok stack add gatus --server=home
  • healthchecksCron job and scheduled task monitoring with alerts for missed pings

    Asks for: HEALTHCHECKS_DOMAINHEALTHCHECKS_SECRET_KEY

    Secrets: HEALTHCHECKS_SECRET_KEYHEALTHCHECKS_SMTP_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add healthchecks --server=home
  • ntfySelf-hosted push notifications (binwiederhier/ntfy)

    Asks for: NTFY_DOMAINNTFY_CPU_LIMITNTFY_MEM_LIMIT

    Secrets: none

    rostok stack add ntfy --server=home
  • okoServer-rendered homelab dashboard fed by Gatus (spy4x/oko)

    Asks for: OKO_DOMAINOKO_UPTIME_HOSTS

    Secrets: none

    rostok stack add oko --server=home

    This tool's page

  • umamiPrivacy-first web analytics with a PostgreSQL database (Umami)

    Asks for: UMAMI_DOMAINUMAMI_PROXY_DOMAINUMAMI_PROXY_WWW_DOMAINUMAMI_DB_PASSWORDUMAMI_APP_SECRET

    Secrets: UMAMI_DB_PASSWORDUMAMI_APP_SECRETEncrypted into .env.age, so the repo is safe to push.

    rostok stack add umami --server=home
  • victoria-metricsMetrics and logs stack (VictoriaMetrics, VictoriaLogs, vmagent, promtail)

    Asks for: none

    Secrets: none

    rostok stack add victoria-metrics --server=home
  • zondHealth-probe bridge: 200 or 503 per container for external monitors (spy4x/zond)

    Asks for: ZOND_DOMAINZOND_CPU_LIMITZOND_MEM_LIMIT

    Secrets: none

    rostok stack add zond --server=home

    This tool's page

Network2 stacks

  • adguardNetwork-wide ad and tracker blocking DNS server (AdGuard Home)

    Asks for: ADGUARD_DOMAINADGUARD_DNS_BIND

    Secrets: none

    rostok stack add adguard --server=home
  • cloudflaredCloudflare Tunnel connector: expose services without open ports

    Asks for: CLOUDFLARED_TUNNEL_TOKENCLOUDFLARED_CPU_LIMITCLOUDFLARED_MEM_LIMIT

    Secrets: CLOUDFLARED_TUNNEL_TOKENEncrypted into .env.age, so the repo is safe to push.

    rostok stack add cloudflared --server=home

Productivity9 stacks

  • akauntingSelf-hosted accounting and invoicing (Akaunting + MariaDB)

    Asks for: AKAUNTING_DOMAINAKAUNTING_DB_ROOT_PASSWORDAKAUNTING_DB_PASSWORD

    Secrets: AKAUNTING_DB_ROOT_PASSWORDAKAUNTING_DB_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add akaunting --server=home
  • bulwarkModern JMAP webmail client for the Stalwart mail server

    Asks for: BULWARK_DOMAINBULWARK_ADMIN_PASSWORDBULWARK_SESSION_SECRET

    Secrets: BULWARK_ADMIN_PASSWORDBULWARK_SESSION_SECRETEncrypted into .env.age, so the repo is safe to push.

    rostok stack add bulwark --server=home
  • caldav-tasks-webWeb client for the tasks on a CalDAV server: one owner, one account, no database

    Asks for: CALDAV_TASKS_WEB_DOMAIN

    Secrets: none

    rostok stack add caldav-tasks-web --server=home

    This tool's page

  • caldiyCal.diy scheduling platform (community edition of Cal.com)

    Asks for: CALDIY_DOMAINCALDIY_DB_PASSWORDCALDIY_NEXTAUTH_SECRETCALDIY_ENCRYPTION_KEYCALDIY_CRON_API_KEYCALDIY_SMTP_HOSTCALDIY_SMTP_PORTCALDIY_SMTP_FROMCALDIY_SMTP_USERNAME

    Secrets: CALDIY_DB_PASSWORDCALDIY_NEXTAUTH_SECRETCALDIY_ENCRYPTION_KEYCALDIY_CRON_API_KEYCALDIY_SMTP_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add caldiy --server=home
  • deepseek-harnessAI agent harness with plugin-based web UI (DeepSeek) — host-level

    Asks for: none

    Secrets: none

    rostok stack add deepseek-harness --server=home
  • migTiny self-hosted meeting scheduler: one owner, one URL, book a time slot

    Asks for: MIG_DOMAIN

    Secrets: none

    rostok stack add mig --server=home

    This tool's page

  • stalwartSelf-hosted mail server (Stalwart) with Let's Encrypt certificates synced from Traefik

    Asks for: STALWART_DOMAINSTALWART_MTA_STS_DOMAINSTALWART_WEBMAIL_ORIGINSTALWART_ADMIN_PASSWORDSTALWART_MEM_LIMITSTALWART_CPU_LIMIT

    Secrets: STALWART_ADMIN_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add stalwart --server=home
  • traggoTag-based time tracker (traggo/server)

    Asks for: TRAGGO_DOMAINTRAGGO_MEM_LIMITTRAGGO_CPU_LIMIT

    Secrets: none

    rostok stack add traggo --server=home
  • usememosSelf-hosted notes (usememos/memos)

    Asks for: USEMEMOS_DOMAIN

    Secrets: none

    rostok stack add usememos --server=home

Proxy2 stacks

  • pangolinSelf-hosted tunnel broker: publish services of remote sites over WireGuard

    Asks for: PANGOLIN_DOMAINPANGOLIN_MEM_LIMITPANGOLIN_CPU_LIMITPANGOLIN_GERBIL_MEM_LIMITPANGOLIN_GERBIL_CPU_LIMITPANGOLIN_TRAEFIK_MEM_LIMITPANGOLIN_TRAEFIK_CPU_LIMIT

    Secrets: none

    rostok stack add pangolin --server=home
  • traefikReverse proxy with auto-TLS via Let's Encrypt

    Asks for: TRAEFIK_DOMAINTRAEFIK_BASIC_AUTH_USERTRAEFIK_BASIC_AUTH_PASSWORDTRAEFIK_CPU_LIMITTRAEFIK_MEM_LIMIT

    Secrets: TRAEFIK_BASIC_AUTH_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add traefik --server=home

Security1 stack

  • vaultwardenBitwarden-compatible password manager with SMTP notifications

    Asks for: VAULTWARDEN_DOMAIN

    Secrets: VAULTWARDEN_SMTP_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add vaultwarden --server=home

Storage1 stack

  • filebrowserSelf-hosted web-based file manager

    Asks for: FILEBROWSER_DOMAINPATH_MEDIAPATH_VIDEOSPATH_MUSICPATH_BOOKSPATH_SYNCPATH_MOVIESPATH_SERIESPATH_OTHER

    Secrets: none

    rostok stack add filebrowser --server=home

Tools4 stacks

  • librespeedSelf-hosted speed-test tool (librespeed/speedtest)

    Asks for: LIBRESPEED_DOMAINLIBRESPEED_CPU_LIMITLIBRESPEED_MEM_LIMITLIBRESPEED_PASSWORD

    Secrets: LIBRESPEED_PASSWORDEncrypted into .env.age, so the repo is safe to push.

    rostok stack add librespeed --server=home
  • omni-toolsEveryday online tools that run in your browser (iib0011/omni-tools)

    Asks for: OMNI_TOOLS_DOMAINOMNI_TOOLS_CPU_LIMITOMNI_TOOLS_MEM_LIMIT

    Secrets: none

    rostok stack add omni-tools --server=home
  • playwrightPlaywright browser server and MCP proxy for AI agents

    Asks for: none

    Secrets: none

    rostok stack add playwright --server=home
  • searxngMeta search engine (searxng/searxng)

    Asks for: SEARXNG_DOMAINSEARXNG_SECRET_KEY

    Secrets: SEARXNG_SECRET_KEYEncrypted into .env.age, so the repo is safe to push.

    rostok stack add searxng --server=home

Web1 stack

  • nginxStatic site server for a landing page, dashboard or docs (nginx)

    Asks for: NGINX_CONTAINER_NAME

    Secrets: none

    rostok stack add nginx --server=home

What you get

After rostok, your project folder holds:

.
├── deno.jsonc              # imports map for @rostok/cli
├── .gitignore              # ignores plaintext .env / .env.root
├── .env.root               # CLI-managed cross-server vars (gitignored)
├── .env.root.age           # encrypted — safe to commit
└── servers/
    └── home/
        ├── config.json     # which stacks (CLI-managed, committed)
        ├── .env            # per-server vars (gitignored)
        └── .env.age        # encrypted — safe to commit

Every .env mutation is auto-encrypted to .env.age once a key exists (rostok env setup), so secrets are safe to commit.

Use it if

  • You run Docker on one to a few machines (an old PC, a homelab, or a small company replacing SaaS) and want the setup in a Git repo.

Skip it if

  • You run a big company's fleet: rostok stays small and homelab-shaped.

The story behind it

Two ways to use it

Use it yourself

The code is on GitHub under the MIT licence.

deno install -g -A -n rostok jsr:@rostok/cli@1.28.0

From JSR, pinned to 1.28.0.

View on GitHub

Have me build it

Need something like this for your team? That's my day job.

More tools

  • oko

    one page for every self-hosted service, with its status and 30-day uptime from gatus.

    In use
  • Zond

    internal health probe bridge for services behind SSO proxies.

    In use
  • Seed

    SaaS starter.

    WIP

All tools