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
| Tool | Model | Self-hosted | Indicative price | Standout feature |
|---|---|---|---|---|
| **Infisical** | Open source (MIT) | Yes — Docker Compose, 4 GB RAM | Free (self-hosted) | Native RBAC, auto-rotation, multi-language SDKs |
| HashiCorp Vault | BSL (source available) | Yes — complex to operate | Free (community) | Advanced secret engines, PKI, transit encryption |
| Doppler | Proprietary SaaS | No | $6/dev/month | Polished UX, CI/CD sync without a server |
| Bitwarden Secrets | Open source (AGPL) | Yes — Bitwarden server | Free (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
Generate secrets
Infisical needs two independent secrets: an
ENCRYPTION_KEY(16-byte hex:openssl rand -hex 16) for encrypting vault data at rest, and anAUTH_SECRET(random string:openssl rand -base64 32) for signing JWT tokens. Store both in a.envfile alongside your Compose file — never commit this file to version control.Write the Compose file
The stack has three services:
postgres:14-alpine(the secrets store),redis:alpine(background jobs and session cache) andinfisical/infisical:latest(the app, port 8080). SetDB_CONNECTION_URI,REDIS_URL,SITE_URL(your domain,https://secrets.yourdomain.com) and the two secrets. Bring the stack up withdocker compose up -d.To pin a stable release instead of
latest, check the GitHub releases page and useinfisical/infisical:v0.91.1(current version as of October 2026).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/Caddyfilewithsecrets.yourdomain.com { reverse_proxy localhost:8080 }. Caddy provisions a Let's Encrypt certificate automatically. Reload withsystemctl 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). Addproxy_set_header Host $host;andproxy_set_header X-Real-IP $remote_addr;so audit logs record the real client IP, not127.0.0.1.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.Integrate with your apps and CI
Install the Infisical CLI (
npm install -g @infisical/cli) or an SDK in your project. Runinfisical run -- node server.jsto inject secrets at runtime — your app readsprocess.env.MY_SECRETas 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.Logging in for the first time
Open the
/admin/signupaddress 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_SECRETDocker 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.