selfhost.directory

The index of self-hostable projects — ranked, categorized and served with live updates.
Own your data and stop giving it to big tech.

Zealot logo

Self-host Zealot

6.2.2

Beta app distribution for iOS, Android, macOS and more

ReleaseOpen SourceMIT
Updatedlast week
LanguageRuby
Setup difficultyModerate
ThemeDark mode
Stars
1 366
CPU
1 cores
RAM
512MB
Storage
at least 5-10 GB (for the PostgreSQL server); app storage depends on uploaded apps
Port
80 (Zealot web UI and API inside the container (example compose maps 80:80))
Requires
PostgreSQL
Docker
ghcr.io/tryzealot/zealot
Install with Docker Compose
Zealot dashboard preview

What is Zealot?

Zealot is a Rails-based server for teams that ship their own mobile and desktop software: you upload iOS, Android, macOS, Windows or Linux builds and testers get install and version pages per app channel. It parses application and provisioning-profile metadata, syncs iOS test-device UDIDs and can register them with an Apple developer account, and pushes customizable webhooks to notification services such as Slack, Discord, Feishu/Lark, DingTalk or WeCom. Developers automate uploads and releases through a REST API, iOS/Android SDKs and a fastlane plugin. Sign-in uses a built-in account system or third-party providers (GitHub, GitLab, Gitea, Google, Feishu, LDAP, OIDC). For deployment it ships amd64/arm64 containers and a one-click Docker Compose script; the only supported backend database is PostgreSQL, and HTTPS is effectively mandatory for iOS installs. It is MIT-licensed and offers light, dark and auto appearance modes.

Should you self-host Zealot?

Zealot scores 55/100 on selfhost.directory (how scoring works) and ranks #17 of 28 in CI/CD. It has 1 366 GitHub stars.

It shipped 3 stable releases in the past year. The latest, 6.2.2, came out on 25 July 2026. New versions land roughly every 4 months.

Setup is moderate: expect some configuration beyond a single command. An official Docker image is available. It is MIT-licensed and written mostly in Ruby.

Its closest alternative on selfhost.directory is jenkins (82/100, 26 704 stars). It scores higher overall, so compare the two before you pick. See Zealot vs jenkins side by side.

Features

  • App metadata analysis
  • Beta install / share pages
  • Debug file management
  • Developer kit (REST API, SDKs, fastlane plugin)
  • GraphQL APIDocs state it is still being developed gradually.
  • iOS test device management
  • Multi-channel app management
  • Multi-platform app hosting
  • Notification webhooks
  • REST API
  • Team and permission management

Zealot README

How to install Zealot

Install Zealot with Docker Compose

Environment variables
ZEALOT_DOMAIN, ZEALOT_CERT_EMAIL, ZEALOT_ADMIN_EMAIL, ZEALOT_REGISTER_ENABLED

Configure a .env file, generate or write a docker-compose.yml with the zealot, postgres (and optional web) services, then:

docker-compose pull docker-compose run --rm zealot run_upgrade docker-compose up -d

Step-by-step guide with a complete compose example; images on GHCR and Docker Hub.

How to configure Zealot

  • ACTION_MAILER_DEFAULT_FROMDefault sender address for notification emails.

    Default sender address for notification emails.

  • ACTION_MAILER_DEFAULT_TODefault recipient address for notification emails.

    Default recipient address for notification emails.

  • CLARITY_ANALYTICS_IDMicrosoft Clarity analytics ID.

    Microsoft Clarity analytics ID.

  • DEFAULT_LOCALEzh-CNDefault language.

    Default language.

    values: zh-CN | en

  • FEISHU_ENABLEDEnable Feishu (Lark) login.

    Enable Feishu (Lark) login.

    values: true | false

  • GITEA_ENABLEDEnable Gitea OAuth2 login.

    Enable Gitea OAuth2 login.

    values: true | false

  • GITHUB_ENABLEDEnable GitHub OAuth login.

    Enable GitHub OAuth login.

    values: true | false

  • GITHUB_REQUIRED_ORGRestrict GitHub login to organization members (requires read:org scope).

    Restrict GitHub login to organization members (requires read:org scope).

  • GITLAB_ENABLEDEnable GitLab login.

    Enable GitLab login.

    values: true | false

  • GOOGLE_ANALYTICS_IDGoogle Analytics tracking ID (Universal Analytics only, not GA4).

    Google Analytics tracking ID (Universal Analytics only, not GA4).

  • GOOGLE_OAUTH_ENABLEDEnable Google OAuth login.

    Enable Google OAuth login.

    values: true | false

  • LDAP_ENABLEDEnable LDAP login.

    Enable LDAP login.

    values: true | false

  • OIDC_ENABLEDEnable OpenID Connect login.

    Enable OpenID Connect login.

    values: true | false

  • OIDC_ISSUER_URLOIDC issuer URL; with OIDC_DISCOVERY=true the .well-known/openid-configuration is fetched automatically.

    OIDC issuer URL; with OIDC_DISCOVERY=true the .well-known/openid-configuration is fetched automatically.

  • SMTP_ADDRESSSMTP server address.

    SMTP server address.

  • SMTP_AUTH_METHODSMTP authentication method.

    SMTP authentication method.

  • SMTP_DOMAINSMTP setting for the email notification service.

    SMTP setting for the email notification service.

  • SMTP_ENABLE_STARTTLSEnable STARTTLS for SMTP.

    Enable STARTTLS for SMTP.

    values: true | false

  • SMTP_PASSWORDSMTP password or app password.

    SMTP password or app password.

  • SMTP_PORTSMTP server port.

    SMTP server port.

  • SMTP_USERNAMESMTP username.

    SMTP username.

  • UMAMI_SCRIPT_URLUmami analytics script URL.

    Umami analytics script URL.

  • UMAMI_WEBSITE_IDUmami website ID.

    Umami website ID.

  • ZEALOT_ADMIN_EMAILadmin@zealot.comEmail of the default administrator account.

    Email of the default administrator account.

  • ZEALOT_ADMIN_PASSWORDPassword of the default administrator account.

    Password of the default administrator account.

  • ZEALOT_APPEARANCElightDefault appearance/theme.

    Default appearance/theme.

    values: light | dark | auto

  • ZEALOT_CERTSelf-signed certificate file name (cannot be set together with ZEALOT_CERT_EMAIL).

    Self-signed certificate file name (cannot be set together with ZEALOT_CERT_EMAIL).

  • ZEALOT_CERT_EMAILEmail used for the Let's Encrypt free SSL certificate.

    Email used for the Let's Encrypt free SSL certificate.

  • ZEALOT_CERT_KEYSelf-signed certificate key file name.

    Self-signed certificate key file name.

  • ZEALOT_DATABASE_URLPostgres connection in URL format.

    Postgres connection in URL format.

  • ZEALOT_DOMAINSite domain without http:// or https://; must be configured or downloads and static resources break.

    Site domain without http:// or https://; must be configured or downloads and static resources break.

  • ZEALOT_GUEST_MODEEnable guest mode allowing app view, download and install.

    Enable guest mode allowing app view, download and install.

    values: true | false

  • ZEALOT_LOG_FORMATkeyvalueLog output format (lograge-based).

    Log output format (lograge-based).

    values: rails | json | graylog2 | ltsv | keyvalue

  • ZEALOT_LOGIN_ENABLEDEnable or disable login via the built-in authentication system (since 6.1.0).

    Enable or disable login via the built-in authentication system (since 6.1.0).

    values: true | false

  • ZEALOT_PASSWORDLESS_LOGIN_ENABLEDfalseEnable passwordless login via email links (since 6.2.0).

    Enable passwordless login via email links (since 6.2.0).

    values: true | false

  • ZEALOT_PASSWORDLESS_TOKEN_EXPIRY_MINUTESEmail link token expiry time in minutes.

    Email link token expiry time in minutes.

  • ZEALOT_POSTGRES_DB_NAMEPostgres database name.

    Postgres database name.

  • ZEALOT_POSTGRES_HOSTPostgres host (individual variable alternative to the URL form).

    Postgres host (individual variable alternative to the URL form).

  • ZEALOT_POSTGRES_PASSWORDPostgres password.

    Postgres password.

  • ZEALOT_POSTGRES_PORTPostgres port.

    Postgres port.

  • ZEALOT_POSTGRES_SSLMODEPostgres SSL mode.

    Postgres SSL mode.

    values: disable/allow/prefer/verify-ca/verify-full

  • ZEALOT_POSTGRES_USERNAMEPostgres username.

    Postgres username.

  • ZEALOT_REGISTER_ENABLEDEnable or disable new user registration.

    Enable or disable new user registration.

    values: true | false

Zealot releases & version history

FAQ

CPU or memory resources surge after running the service for a while — how to solve it?

The cause is unknown for the individual case reported; a workaround is to limit CPU and memory via deploy.resources limits in the docker-compose.yml.

Is there a sharing page for applications like FIR or Pgyer?

Yes: each app channel has a detail page and each uploaded version has a release page, and an empty version ID redirects to the latest release so the channel releases URL can be shared directly.

Is Kubernetes deployment supported?

Yes, Kubernetes deployment is supported, but scaling is not, because application uploads go to local storage inside the container and cloud object storage like S3 is not supported.

Is an external Postgres connection supported?

Yes; configure it via the Postgres environment variables described in the environment-variables docs.

When using a load balancer, downloads switch from https to http — why?

The load balancer terminates HTTPS while the internal service still uses HTTP; set the forwarded protocol header (X-Forwarded-Proto) to https on the balancer so the service inherits it.

Why can't I install iOS applications with self-signed certificates?

Every iOS device must manually install the self-signed certificate before apps can be downloaded and installed, which is complicated, so self-signed certificates are discouraged.

Why can't I use HTTP for the deployment service?

iOS download services depend on SSL/TLS certificates, so an authorized certificate is recommended; the project suggests free Let's Encrypt certificates.

More in Testing

Rate this project

Click to rate — no account needed.

0 comments

Posting as guest
Loading comments…