Deployment guide

How to Self-Host Infisical on a VPS

Deploy on a VPS Cloud →

Tutorial

Self-hosting

How to Self-Host Infisical on a VPS

Hardcoding secrets in .env files and rotating them manually across environments is a security incident waiting to happen. Infisical is an open-source secrets manager (MIT licence, 27,600 GitHub stars as of October 2026) that centralises every API key, database password and certificate in a single self-hosted vault — synced automatically to your apps, CI pipelines and team. Here is how to deploy it on a VPS in under 20 minutes, complete with RBAC, automatic rotation and CI/CD integrations.

9 min read6 steps
Contents· Why self-host your secrets manager1/10
  1. 01Why self-host your secrets manager
  2. 02What self-hosted Infisical gives you
  3. 03Infisical vs Vault vs Doppler vs Bitwarden Secrets
  4. 04Requirements
  5. 05Deploy Infisical with Docker Compose
  6. 06Advanced configuration: RBAC, secret policies and automatic rotation
  7. 07CI/CD integration: GitHub Actions, GitLab CI, Docker Compose
  8. 08Troubleshooting: common errors
  9. 09Backups and updates
  10. 10Lock down your Infisical instance immediately after setup

Why self-host your secrets manager

Storing secrets in a SaaS vault means your most sensitive credentials transit through a third-party server. Self-hosting Infisical keeps every secret on your own infrastructure, under your own access controls and audit logs. It also cuts a recurring SaaS subscription: Infisical is MIT-licensed, free to self-host, and a direct replacement for paid tools like Doppler ($6/dev/month) or the complexity of HashiCorp Vault. With a single VPS and a domain name, your entire team and every CI pipeline can pull secrets programmatically — no more .env files committed by accident.

What self-hosted Infisical gives you

  • Centralised vault for every environment (dev, staging, prod) with per-environment access policies.
  • Native SDKs for Node.js, Python, Go, Java, Ruby and more — inject secrets at runtime, not via .env files.
  • GitHub Actions, GitLab CI, CircleCI and Jenkins integrations: secrets synced automatically to your pipelines.
  • Role-based access control, service tokens and machine identities — no shared root credentials.
  • Full audit log: every read, write and rotation is recorded with user, IP and timestamp.
  • Secret rotation and versioning — roll back a secret in one click if a credential is compromised.

Infisical vs Vault vs Doppler vs Bitwarden Secrets

Scroll the table

ToolModelSelf-hostedIndicative priceStandout feature
**Infisical**Open source (MIT)Yes — Docker Compose, 4 GB RAMFree (self-hosted)Native RBAC, auto-rotation, multi-language SDKs
HashiCorp VaultBSL (source available)Yes — complex to operateFree (community)Advanced secret engines, PKI, transit encryption
DopplerProprietary SaaSNo$6/dev/monthPolished UX, CI/CD sync without a server
Bitwarden SecretsOpen source (AGPL)Yes — Bitwarden serverFree (self-hosted)Integrated with the Bitwarden password vault

Requirements

A VPS with at least 2 vCPU and 4 GB RAM running Ubuntu 22.04 — PostgreSQL and Node.js are memory-hungry under concurrent requests; below 4 GB, Infisical restarts under load. At least 20 GB of disk for long-term audit logs. Docker and Docker Compose installed (docker compose version should return v2.x). A domain name pointed at your VPS — Infisical requires a public URL for OAuth redirects, email invite links and the browser security model (SITE_URL is not optional). A DNS A or CNAME record already propagated before starting Caddy or nginx for Let's Encrypt certificate issuance.

Deploy Infisical with Docker Compose

  1. Generate secrets

    Infisical needs two independent secrets: an ENCRYPTION_KEY (16-byte hex: openssl rand -hex 16) for encrypting vault data at rest, and an AUTH_SECRET (random string: openssl rand -base64 32) for signing JWT tokens. Store both in a .env file alongside your Compose file — never commit this file to version control.

  2. Write the Compose file

    The stack has three services: postgres:14-alpine (the secrets store), redis:alpine (background jobs and session cache) and infisical/infisical:latest (the app, port 8080). Set DB_CONNECTION_URI, REDIS_URL, SITE_URL (your domain, https://secrets.yourdomain.com) and the two secrets. Bring the stack up with docker compose up -d.

    To pin a stable release instead of latest, check the GitHub releases page and use infisical/infisical:v0.91.1 (current version as of October 2026).

  3. Configure the reverse proxy with nginx or Caddy

    Infisical requires HTTPS — without a valid TLS certificate the browser blocks OAuth flows.

    Caddy (recommended): create /etc/caddy/Caddyfile with secrets.yourdomain.com { reverse_proxy localhost:8080 }. Caddy provisions a Let's Encrypt certificate automatically. Reload with systemctl reload caddy.

    nginx: create a vhost with proxy_pass http://127.0.0.1:8080;, then issue the certificate via Certbot (certbot --nginx -d secrets.yourdomain.com). Add proxy_set_header Host $host; and proxy_set_header X-Real-IP $remote_addr; so audit logs record the real client IP, not 127.0.0.1.

  4. Create the first admin account

    Open your domain in a browser and go to /admin/signup — this is the one-time wizard that creates the Super Admin account and your organisation. The first person to reach that screen becomes the instance administrator. Then create your first project (a logical namespace for related secrets), add environments (dev, staging, prod) and invite your team members.

  5. Integrate with your apps and CI

    Install the Infisical CLI (npm install -g @infisical/cli) or an SDK in your project. Run infisical run -- node server.js to inject secrets at runtime — your app reads process.env.MY_SECRET as if from a local .env, but the value comes from the vault. For GitHub Actions, install the official Infisical action and add a service token as a repository secret.

  6. Logging in for the first time

    Open the /admin/signup address of your instance right away: it is the one-time wizard that creates the Super Admin account and then your organisation. The first person to reach that screen becomes the administrator of the instance.

Advanced configuration: RBAC, secret policies and automatic rotation

Once the instance is running, three advanced features strengthen operational security.

RBAC (role-based access control): Infisical has four built-in roles — owner, admin, developer, viewer. Assign viewer to CI pipelines that only need to read, developer to developers and admin to project leads. Machine Identities let you bind a role directly to an application without a long-lived service token: they authenticate via AWS IAM, Azure AD or a Kubernetes token.

Secret policies: in Settings → Project → Secret Protection, enable change approvals before a production secret can be overwritten. A second admin must validate each change — useful for SOC 2 or ISO 27001 compliance.

Automatic rotation: Infisical ships native rotation templates for PostgreSQL, MySQL, AWS IAM and GitHub. In the Rotation tab of your project, create a rotation job with the desired frequency (e.g. every 30 days for a database password). Infisical generates the new value, pushes it to the vault and notifies applications via webhook — no manual intervention required.

CI/CD integration: GitHub Actions, GitLab CI, Docker Compose

GitHub Actions: add the official action to your workflow and pass a service token as a repository secret (INFISICAL_TOKEN). Secrets are injected as environment variables before each job.

- uses: Infisical/secrets-action@v1
  with:
    token: ${{ secrets.INFISICAL_TOKEN }}
    project-id: "<your-project-id>"
    environment: "prod"

GitLab CI: use the Infisical CLI in a before_script. Add INFISICAL_TOKEN in the repository CI/CD variables.

before_script:
  - infisical run --env prod -- env | grep MY_SECRET

Docker Compose (runtime): the Infisical CLI can generate a .env file on the fly before launching Compose, or inject directly via infisical run -- docker compose up -d. Avoid storing a generated .env inside an image — prefer runtime injection to never serialise a secret in a Docker layer.

Troubleshooting: common errors

Error: connect ECONNREFUSED 127.0.0.1:6379 (Redis) — Redis is not started or the infisical service starts before Redis is ready. Add depends_on: redis in your docker-compose.yml and check that the Redis container is healthy with docker compose ps. If Redis is running but the error persists, confirm that REDIS_URL is set to redis://redis:6379 (the Compose service name, not localhost).

Error: unable to verify the first certificate (TLS) — the Let's Encrypt certificate has not been issued yet (DNS propagation incomplete) or Caddy/nginx cannot reach the ACME challenge endpoint. Verify that port 80 is open in your firewall (ufw allow 80) — Caddy needs it for the HTTP-01 challenge on initial issuance. Then switch to a DNS-01 challenge if the IP is behind NAT.

docker compose up fails with Bind for 0.0.0.0:8080 failed: port is already allocated — another process is listening on port 8080. Change the port mapping in Compose (8081:8080) and update the reverse proxy config accordingly.

/admin/signup page inaccessible after first login — this is by design: the wizard only appears once. If you need to replay it (test instance), drop the Organization table and restart Infisical.

Secrets not injected in GitHub Actions — check that the environment passed to the action matches exactly the environment name created in Infisical (case-sensitive: prod ≠ Prod).

Backups and updates

PostgreSQL backups: encrypted secrets live in PostgreSQL. Schedule a daily pg_dump with docker exec infisical_postgres pg_dump -U infisical infisical > backup-$(date +%Y%m%d).sql. Encrypt the backup before transferring it off-site — it contains secrets encrypted at rest, but a database leak combined with an ENCRYPTION_KEY leak exposes the entire vault.

Upgrading Infisical: the infisical/infisical:latest image updates with each new tag. For a controlled upgrade, pin the version (v0.91.1), review the GitHub changelog before each update (some versions include database migrations), then follow this order:
1. docker compose pull to download the new image.
2. docker compose up -d — Docker Compose only recreates containers whose image changed.
3. Verify the login page responds and logs show no migration errors.

Monitoring: expose Infisical's /healthcheck endpoint in your monitoring tool (Uptime Kuma, Gatus) to be alerted on outages. An inaccessible secrets vault blocks every deployment that depends on it.

Lock down your Infisical instance immediately after setup

Before inviting your team, disable the public sign-up page in Settings → Authentication → Allow signups. Infisical then only accepts users invited by an admin. Also enable email verification and, if your team uses GitHub or Google OAuth, configure those providers in Settings → SSO — they are more secure than password-only login.

Deploy Infisical on your VPS in one click

Stop leaking secrets via .env files and Slack messages. ServOrbit provisions a ready-to-use Infisical instance on a VPS — PostgreSQL, Redis and HTTPS included.