Homelab

Remote access and hosting for your homelab

Octelium is a free and open source, self-hosted zero trust access platform. It reaches everything on your home network from anywhere without forwarding a port, publishes what you want on your own domain with a managed certificate, and can deploy and host containerized applications itself.

  • Free and open source
  • No port forwarding
  • Runs on a small VM
service.yaml
A resource at homeThe upstream address is resolved from the side of a connected host, so no port is forwarded.
A resource at home. The upstream address is resolved from the side of a connected host, so no port is forwarded.
kind: Service
metadata:
  name: jellyfin
spec:
  mode: WEB
  isPublic: true
  config:
    upstream:
      url: http://192.168.1.30:8096
      user: nas
A Policy. Access is authorized per request, so family and friends do not need the same rights.
kind: Policy
metadata:
  name: household
spec:
  rules:
    - effect: ALLOW
      condition:
        all:
          of:
            - match: ctx.user.spec.type == "HUMAN"
            - match: '"household" in ctx.user.spec.groups'
A public site. Anonymous access turns the Cluster into a host for a personal site or a public API.
kind: Service
metadata:
  name: blog
spec:
  mode: WEB
  isPublic: true
  isAnonymous: true
  config:
    upstream:
      container:
        port: 3000
        image: ghcr.io/me/blog:latest
service-remote.yaml
Behind NAT, no port forwardingA connected host serves the upstream over its own outbound tunnel to the Cluster.
Behind NAT, no port forwarding. A connected host serves the upstream over its own outbound tunnel to the Cluster.
kind: Service
metadata:
  name: jellyfin
spec:
  mode: WEB
  config:
    upstream:
      url: http://192.168.1.30:8096
      user: nas
The same resource, publicly. One added field publishes it over HTTPS, with the certificate managed by the Cluster.
kind: Service
metadata:
  name: jellyfin
spec:
  mode: WEB
  isPublic: true
  config:
    upstream:
      url: http://192.168.1.30:8096
      user: nas
Your own DNS resolver. A DNS Service puts a home resolver behind identity, and can filter by question name.
kind: Service
metadata:
  name: pihole-dns
spec:
  mode: DNS
  port: 53
  config:
    upstream:
      url: dns://192.168.1.5
      user: nas
policy-groups.yaml
Who gets whatGroups keep household, guests and your own devices on separate sets of resources.
Who gets what. Groups keep household, guests and your own devices on separate sets of resources.
kind: Policy
metadata:
  name: guests
spec:
  rules:
    - effect: ALLOW
      condition:
        all:
          of:
            - match: ctx.request.http.method == "GET"
            - match: '"guests" in ctx.user.spec.groups'
DNS questions. The DNS mode authorizes on the question name and type, not only on who is connected.
kind: Policy
metadata:
  name: dns-com-only
spec:
  rules:
    - effect: ALLOW
      condition:
        match: ctx.request.dns.name.endsWith(".com.") &&
          ctx.request.dns.typeID == 1
A public site with rules. Anonymous authorization keeps a Service public while still filtering on the request.
kind: Service
metadata:
  name: blog
spec:
  mode: HTTP
  isPublic: true
  isAnonymous: true
  config:
    upstream:
      url: http://192.168.1.40:3000
      user: nas
  authorization:
    enableAnonymous: true
    inlinePolicies:
      - spec:
          rules:
            - effect: ALLOW
              condition:
                match: ctx.request.http.method == "GET"
ssh.yaml
SSH into the boxNo private keys or passwords are distributed, and no PKI has to be operated.
SSH into the box. No private keys or passwords are distributed, and no PKI has to be operated.
kind: Service
metadata:
  name: nas-ssh
spec:
  mode: SSH
  port: 22
  config:
    upstream:
      url: ssh://192.168.1.30
      user: nas
    ssh:
      user: admin
      auth:
        privateKey:
          fromSecret: nas-key
A database at home. The database password stays in the Cluster, and the Service forces the database user.
kind: Service
metadata:
  name: pg-home
spec:
  mode: POSTGRES
  port: 5432
  config:
    upstream:
      url: postgres://192.168.1.35:5432
      user: nas
    postgres:
      user: app
      database: app
      auth:
        password:
          fromSecret: pg-password
An API you pay for. An API key is injected upstream after authorization, so it is not copied into scripts.
kind: Service
metadata:
  name: weather
spec:
  mode: HTTP
  isPublic: true
  config:
    upstream:
      url: https://api.weather.example
    http:
      auth:
        bearer:
          fromSecret: weather-api-key
idp.yaml
Sign in with GitHubGitHub OAuth2 works as an identity provider, alongside OpenID Connect and SAML 2.0.
Sign in with GitHub. GitHub OAuth2 works as an identity provider, alongside OpenID Connect and SAML 2.0.
kind: IdentityProvider
metadata:
  name: github
spec:
  github:
    clientID: Iv1.0123456789abcdef
    clientSecret:
      fromSecret: github-oauth2
A workload User. The host serving your resources is itself a User, with its own Session and audit trail.
kind: User
metadata:
  name: nas
spec:
  type: WORKLOAD
  groups:
    - serving
A local model. A self-hosted OpenAI-compatible server is fronted the same way a hosted provider is.
kind: Service
metadata:
  name: ollama
spec:
  mode: LLM
  isPublic: true
  config:
    upstream:
      url: http://192.168.1.50:11434
      user: nas
    llm:
      protocol: OPENAI
Visibility and auditing

Real-time visibility at the application layer

OpenTelemetry-ready, application-layer aware, structured auditing and visibility emitted to your OpenTelemetry OTLP receivers, where they can be exported to your log management and SIEM tools.

Read about visibility and auditing
AccessLogOTLP
ALLOWlinus@acme.compg-prod.dbPOSTGRESquery: select id, email from users limit 50
ALLOWci-runnerprod-k8sKUBERNETESverb=list resource=pods namespace=production
DENYagent-07tools-mcpMCPtools/call name=transfer policy=mcp-tools
ALLOWjane@acme.combastionSSHsession recorded, upstream user=deploy
ALLOWagent-07openaiLLMCHAT_COMPLETIONS model=gpt-5-mini tokens=1284
octeliumctl
octeliumctl apply ./cluster
$ octeliumctl apply ./cluster
Secret: nas-key Updated
Secret: github-oauth2 Updated
IdentityProvider: github Created
Policy: household Created
Group: household Created
Group: guests Updated
Service: jellyfin Created
Service: blog Created
Service: pihole-dns Created
User: nas Created
Cluster Core resources successfully applied
 7 resources created
 3 resources updated

 ClusterConfig updated
Homelab needs

The things a homelab ends up needing, and what serves each

Most homelabs accumulate a tunnel, a reverse proxy, a certificate tool, a dynamic DNS client, an authentication portal and a pile of forwarded ports. These are the needs behind that, next to the mechanism in an Octelium Cluster that serves each one.

  1. 01

    Reaching things at home from anywhere

    A connected host serves the upstream over its own outbound tunnel, so nothing is port forwarded, no dynamic DNS is needed and the router configuration is untouched. That works for a NAS, a Raspberry Pi, a container or a laptop.

    Read more
  2. 02

    Publishing something to the internet

    The very same Service can be published over HTTPS on your own domain, either behind authentication or anonymously for a personal site or a public API, with the public DNS record and the TLS certificate managed by the Cluster.

    Read more
  3. 03

    Hosting the application itself

    There does not have to be a machine at home at all. Managed containers deploy, scale and serve a container image as the Service upstream, which covers a static site, a Next.js or Vite application or any small service.

    Read more
  4. 04

    Logging in without another password

    GitHub OAuth2 works as an identity provider out of the box, as does any OpenID Connect or SAML 2.0 provider, including a self-hosted Keycloak, Authentik or Dex that the Cluster can also serve.

    Read more
  5. 05

    Letting other people in, carefully

    Family, guests and your own automation can be separate Users in separate Groups with separate Policies, so sharing a media server does not also share the router, the NAS shell or the database.

    Read more
  6. 06

    Shell access to small devices

    The embedded SSH mode serves SSH from inside the octelium client itself, without a standalone SSH server on the host and without root privileges, which suits fleets of containers and small devices.

    Read more
  7. 07

    Your own DNS, reachable remotely

    A DNS Service puts a home resolver such as Pi-hole behind identity and can authorize on the question name and record type, so ad filtering follows you off the home network.

    Read more
  8. 08

    A remote development environment

    A code server or a remote IDE endpoint is just another Service, reachable in a browser or over the tunnel, with the upstream credential held by the Cluster rather than typed into a bookmark.

    Read more

The point is not that each of these is hard on its own. It is that they are usually six separate pieces of software with six configurations, and here they are fields on the same resource.

Questions

Frequently asked

What does it take to run this at home?
The quick installer provisions a complete single-node Cluster, including Kubernetes itself, on one fresh Linux VM with 2 vCPUs, 2 GB of RAM and a domain you own. That is enough for personal and homelab use. The Cluster itself is normally on a cheap cloud VM with a public address, while the resources it protects stay at home behind NAT.
Do I have to forward ports or run dynamic DNS?
No. A Service upstream can be an address that is only reachable from the side of a connected client. That client runs octelium connect with the --serve or --serve-all flag and serves the resource to the Cluster over its own outbound tunnel, so nothing inbound is opened on the home network and no dynamic DNS record has to track a changing address.
Can I host a public website with it?
Yes. Anonymous public access publishes an HTTP-based Service to the internet with authentication and authorization switched off, which makes the Cluster a hosting platform for a personal site or a public API. Anonymous authorization can then still be enabled so the Service filters on path, method, headers and body content while staying publicly reachable.
Is the enterprise package needed for personal use?
No. Octelium is free and open source and complete on its own. The enterprise package adds capabilities such as a web console, SCIM provisioning and secret encryption at rest, and it is free for personal, homelab and evaluation use.
Do I need to know Kubernetes?
No. An Octelium Cluster runs on top of Kubernetes, but you do not need Kubernetes experience to install, operate or use it. Day-to-day management is a set of YAML resources and a single octeliumctl apply, in the same shape as the examples on this page.
Can family members use it without installing anything?
Yes. HTTP-based resources can be published clientlessly, so a media server or a dashboard opens in an ordinary browser on a phone, a tablet or a television after a normal sign-in. The octelium client is only needed for protocols a browser cannot speak, such as SSH, databases and generic TCP and UDP.
Get started

Deploy Octelium on your own infrastructure in minutes

Free and open source. Self-hosted. No vendor lock-in.