Tutorial

Pocket ID: lightweight OIDC provider in one container

Security & Monitoring9 min read8 steps

Running a full Keycloak or Authentik instance for three or four self-hosted services means deploying a JVM or a multi-container orchestration to solve a problem that fits in a single Go binary. Pocket ID v2.18.0 (October 4, 2026) is a certified OpenID Connect provider that runs in a single container, stores its data in SQLite, and consumes less than 50 MB of RAM at idle — where Keycloak needs hundreds of megabytes. It does OIDC only, it accepts passkeys only, and that is precisely what makes it deployable in five minutes on any VPS.

Contents· Why self-host your OIDC provider1/10
  1. 01Why self-host your OIDC provider
  2. 02What you get with a self-hosted OIDC IdP
  3. 03Concrete prerequisites
  4. 04Installing Pocket ID
  5. 05Post-installation configuration
  6. 06Hardening the instance
  7. 07Troubleshooting
  8. 08Common errors and solutions
  9. 09Pocket ID, Authentik, Keycloak, Authelia: which to choose
  10. 10Conclusion

Why self-host your OIDC provider

Every self-hosted service that manages its own user base introduces a dependency you have to maintain: passwords to reset, accounts to revoke, sessions to invalidate. Multiplied across five or ten services, that becomes a real operational burden. An identity provider (IdP) centralises this work: a single source of identity, revocation that applies everywhere, a single MFA configuration point.

The question is not whether you need an IdP, but which one — and on what foundation you are willing to operate it.

What you get with a self-hosted OIDC IdP

  • Centralised identity — a single account for Gitea, Nextcloud, Grafana and all OIDC-compatible services.
  • Global revocation — disabling an account in Pocket ID cuts access to all connected applications at the next token renewal.
  • Passkey authentication — Touch ID, Face ID or a FIDO2 key as the sole factor, with no password to transmit.
  • No cloud dependency — your identities stay under your jurisdiction, with no per-user quota or per-action pricing.
  • Minimal footprint — Pocket ID consumes less than 50 MB of RAM at idle, versus 300–600 MB for Authentik and 1–2 GB for Keycloak.
  • Embedded SQLite — no external database engine to provision or back up separately.
  • Back-channel logout (v2.18.0) — when a user is disabled or revokes a client, Pocket ID notifies registered applications and invalidates their server-side sessions.
  • Single container — the entire service fits in a ~30 MB Docker image, with no Redis dependency and no separate worker.

Concrete prerequisites

Pocket ID is designed for small stacks. Its requirements are intentionally low:

- Docker 24+ and Docker Compose v2 — required by the official image.
- 512 MB RAM minimum on the VPS — Pocket ID runs under 50 MB at idle; the rest serves the OS and the reverse proxy.
- A domain and a TLS certificate — OIDC requires HTTPS without exception; without a publicly reachable domain (or an internal network with TLS), the installation cannot function.
- No external database — SQLite is embedded. If you prefer PostgreSQL for simpler backups, switching is done by changing a single environment variable.

Pocket ID does not handle SAML, LDAP, or directory federation. If your stack includes applications that only accept SAML, or if you need to federate an Active Directory, use Authentik or Keycloak instead. For a stack of modern web services that support OIDC, Pocket ID covers the need without the overhead.

Installing Pocket ID

  1. Prepare the VPS and domain

    Order a VPS running Ubuntu 22.04 or Debian 12 with at least 512 MB of RAM. Create a DNS A record pointing auth.your-domain.com to your VPS IP address. This subdomain is the public URL of your Pocket ID instance — it must be reachable before the first configuration, as OIDC redirects depend on it.

    Install Docker and the Compose plugin:

    curl -fsSL https://get.docker.com | sh
  2. Create the working directory

    On the server, create a dedicated directory:

    mkdir -p /opt/pocket-id && cd /opt/pocket-id
  3. Write the docker-compose.yml file

    Create /opt/pocket-id/docker-compose.yml:

    services:
      pocket-id:
        image: ghcr.io/pocket-id/pocket-id:v2.18.0
        container_name: pocket-id
        restart: unless-stopped
        ports:
          - "1411:1411"
        volumes:
          - ./data:/app/data
        environment:
          APP_URL: "https://auth.your-domain.com"
          TRUST_PROXY: "true"

    APP_URL must exactly match the public URL of your instance, including the https:// scheme. TRUST_PROXY: "true" tells Pocket ID to trust the X-Forwarded-* headers forwarded by the reverse proxy.

  4. Configure the nginx reverse proxy

    Create the nginx vhost for auth.your-domain.com. Pocket ID listens on HTTP on port 1411; the reverse proxy handles TLS.

    server {
        listen 443 ssl http2;
        server_name auth.your-domain.com;
    
        ssl_certificate     /etc/letsencrypt/live/auth.your-domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/auth.your-domain.com/privkey.pem;
    
        proxy_buffer_size   256k;
        proxy_buffers       4 512k;
        proxy_busy_buffers_size 512k;
    
        location / {
            proxy_pass         http://127.0.0.1:1411;
            proxy_set_header   Host              $host;
            proxy_set_header   X-Real-IP         $remote_addr;
            proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }

    Obtain the certificate with Certbot before reloading nginx:

    certbot certonly --nginx -d auth.your-domain.com
    nginx -t && systemctl reload nginx
  5. Start the container

    From /opt/pocket-id:

    docker compose up -d
    docker compose logs -f pocket-id

    The log line Starting Pocket ID on :1411 confirms the server is ready. Visit https://auth.your-domain.com to complete the initial setup.

  6. Create the admin account and register a passkey

    On the first visit, Pocket ID prompts you to create the administrator account. Enter your email, then immediately register a passkey: go to Settings → Passkeys → Add and follow your browser's prompt (Touch ID, Windows Hello, or a FIDO2 key). Once the passkey is registered, it is the only factor required for subsequent logins.

  7. Register your first OIDC application

    In the administration interface, open OIDC Clients → New client. Fill in:
    - Name: a readable identifier for the application (e.g. Gitea)
    - Callback URL: the redirect URL declared in the client application (e.g. https://git.your-domain.com/user/oauth2/pocket-id/callback)

    Pocket ID v2.18.0 automatically creates a client_secret at creation time — retrieve it immediately, as it will not be displayed in plain text again.

    Note the Client ID and the discovery URL https://auth.your-domain.com/.well-known/openid-configuration: these are the two values to enter in the client application.

  8. Test the flow from the client application

    In Gitea, go to Administration → Authentication Sources → Add → OAuth2. Select OpenID Connect as the provider, fill in the Client ID, Client Secret and the discovery URL. Trigger a test login: the browser should be redirected to auth.your-domain.com, prompt for the registered passkey, and then redirect back to Gitea with the user logged in.

Post-installation configuration

After the initial setup, a few settings improve the robustness of the instance.

Hardening the instance

Restrict registrations: by default, Pocket ID allows any visitor to create an account. In production, disable public registration under Settings → General → Allow registration and invite users individually.

Back up the data volume: all persistence (SQLite database, OIDC signing keys) lives in ./data. A daily rsync to an external storage is sufficient for a small instance. If you migrate to PostgreSQL, add DB_PROVIDER=postgresql and DB_CONNECTION_STRING=... to your Compose file.

Pin the image version: the example above explicitly uses v2.18.0. Do not leave latest in production — an automatic update can introduce a schema migration that your backup has not yet covered.

Limit network exposure: if Pocket ID only needs to be accessible from the VPS internal network, bind port 1411 to the loopback interface and let nginx communicate with the container via the internal Docker network.

Troubleshooting

The most common errors when setting up Pocket ID follow well-identified patterns.

Common errors and solutions

  • 502 Bad Gateway on all pages — most common cause: nginx buffers are too small for Pocket ID's OIDC response headers. Add proxy_buffer_size 256k, proxy_buffers 4 512k and proxy_busy_buffers_size 512k in your location / block and reload nginx.
  • redirect_uri_mismatch during login — the Callback URL declared in Pocket ID does not exactly match the one sent by the client application. Check for a trailing slash, http vs https scheme, and the port number. The match must be exact, character for character.
  • invalid_client at code exchange — the client_secret sent by the application does not match. In v2.18.0, Pocket ID creates a secret automatically at client creation; if you did not save it, regenerate one from the client record in the administration panel.
  • Passkey rejected: NotAllowedError — your browser cannot access WebAuthn APIs without HTTPS. Verify that APP_URL is set to https://... and that the TLS certificate is valid (not self-signed, not expired); Certbot must have issued a certificate for the correct domain.
  • Sessions are not invalidated after revocation — back-channel logout requires the client application to declare a Backchannel Logout URL in its OIDC record. Without this URL, Pocket ID cannot notify the application; existing sessions will expire at their natural lifetime. Verify the field is filled in and reachable from the Pocket ID container.

Pocket ID, Authentik, Keycloak, Authelia: which to choose

Scroll the table

CriterionPocket ID 2.18Authelia 4.39Authentik 2026.8Keycloak 26
IdP protocolsOIDC/OAuth2OIDC/OAuth2 (beta)OIDC, SAML 2.0, LDAP, SCIMOIDC, SAML 2.0, LDAP, Kerberos
AuthenticationPasskeys only (FIDO2)Password + MFA, passkeysPassword + MFA, passkeysPassword + MFA, OTP
RAM at idle< 50 MB~30 MB200–400 MB1–2 GB
DatabaseEmbedded SQLite (or PostgreSQL)YAML file (or external backend)PostgreSQL requiredPostgreSQL recommended
Number of containers113 (server, worker, PostgreSQL)2 (Keycloak + database)
User managementBuilt-in directory, email invitationYAML file or external providerBuilt-in directory, LDAP, social proxyBuilt-in directory, LDAP/AD federation
Best suited forLightweight stack, passkeys, simple IdPForward-auth layer in front of a proxyFull SSO, SAML, visual flowsEnterprise SSO, multi-tenant, compliance

Conclusion

Pocket ID v2.18.0 answers a specific need: centralising authentication for a self-hosted service stack without the operational cost of Keycloak or Authentik. One container, SQLite, passkeys, and under 50 MB of RAM at idle. Version 2.18.0 adds back-channel logout to invalidate application sessions as soon as an account is revoked, and restores automatic client secret creation to simplify application registration.

If your stack includes applications that only accept SAML, or if you need to federate an Active Directory, Authentik or Keycloak are better suited. For everything else — modern web services on a 1 or 2 GB VPS — Pocket ID leaves the RAM for other things.

See also our guides on Authentik and Keycloak to choose with full information.

Deploy your OIDC provider on VPS

A ServOrbit VPS with Docker 24+ is all you need to run Pocket ID in production. One container, a dedicated IPv4, and your applications secured without any cloud dependency.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab