# Deploy Infisical with the infisical-secrets template

Source: https://docs.quake.ai/resources/deployments/deploy-infisical-secrets-template
Markdown: https://docs.quake.ai/resources/deployments/deploy-infisical-secrets-template.md

---

# Deploy Infisical with the infisical-secrets template

Stand up [Infisical](https://infisical.com), an open-source secrets-management platform, on a single Quake AI instance using the [validated OpenTofu template](/docs/platform/validation#how-infrastructure-templates-are-checked) `infisical-secrets`. You apply the template, point a domain at the host and serve it over HTTPS, set the public URL and start the app, sign up the first admin account, create a project and a secret, and pull it with the Infisical CLI.

Infisical keeps your team's secrets on infrastructure you own. You run it yourself; this is a self-hosted tool you operate, not a managed service.

<Figure size="md" caption="What you'll build: an Infisical host on a single instance with bundled PostgreSQL and Redis, reached over HTTPS through a Caddy reverse proxy">

```d2
direction: right

user: Team member {shape: person}
fip: Floating IP
instance: Ubuntu instance {
  caddy: Caddy\nreverse proxy
  infisical: Infisical\napp
  db: PostgreSQL
  redis: Redis
  caddy -> infisical: proxies 443 to 8080
  infisical -> db: secrets (encrypted)
  infisical -> redis: jobs + cache
}

user -> fip: HTTPS
fip -> instance.caddy
```

</Figure>

<PricingCompanion
  components={[
    { kind: "template", slug: "infisical-secrets", required: true },
  ]}
/>

## Prerequisites

You need:

- OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
- Your OpenStack credentials sourced into the shell (`source openrc.sh`). See [the OpenStack CLI guide](/docs/tools/openstack-cli).
- An SSH keypair that already exists in your project. Record its name for the `key_name` variable.
- A copy of the `infisical-secrets` template directory from [the template reference page](/resources/iac-templates/infisical-secrets).
- A domain you can point at the instance. Infisical needs a stable public URL for auth callbacks and CLI/SDK access.
- The [Infisical CLI](https://infisical.com/docs/cli/overview) installed locally, to pull the secret you create in this walkthrough.

## Step 1: Apply the template

Copy the template's example variables file and set `key_name`:

```bash
cp terraform.tfvars.example terraform.tfvars
```

```hcl
key_name = "YOUR_KEY_NAME"
```

Initialize, preview, and apply:

```bash
tofu init
tofu plan
tofu apply
```

OpenTofu provisions a private network, a router, a security group, a block volume mounted at `/var/lib/docker`, an instance, and a floating IP. On first boot, cloud-init installs Docker Engine, generates `ENCRYPTION_KEY`, `AUTH_SECRET`, and the database password into `/opt/infisical/.env`, and starts PostgreSQL and Redis. Infisical itself starts after you finish configuration in the next steps.

Read the outputs and record `floating_ip` and `app_url`:

```bash
tofu output
```

## Step 2: Point a domain at the host and serve HTTPS with Caddy

Infisical builds absolute links and auth callbacks from its public URL, so it needs a domain with TLS before you sign up your first account.

1. Create a DNS **A record** for your domain (for example `secrets.example.com`) pointing at `YOUR_FLOATING_IP`. Follow [How to point a domain at a Quake AI resource](/docs/network/how-to/point-domain-to-quake-ai). Wait until it resolves:

```bash
dig +short secrets.example.com
```

2. SSH to the instance and create `/opt/infisical/Caddyfile`:

```text
secrets.example.com {
  reverse_proxy 127.0.0.1:8080
}
```

3. Add Caddy to `/opt/infisical/docker-compose.yml`:

```yaml
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    network_mode: host
    volumes:
      - /opt/infisical/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
volumes:
  caddy_data:
```

For background on certificates, see [How to issue and auto-renew a TLS certificate with Let's Encrypt](/docs/network/how-to/lets-encrypt-certificate).

## Step 3: Set SITE_URL and start Infisical

Edit `/opt/infisical/.env` on the instance and set the public URL:

```text
SITE_URL=https://secrets.example.com
```

Start the app:

```bash
cd /opt/infisical
sudo docker compose up -d
sudo docker compose ps
```

The `infisical` container joins the running PostgreSQL and Redis. Confirm it reports healthy.



`ENCRYPTION_KEY` in `/opt/infisical/.env` encrypts every secret Infisical stores at rest. Losing it makes every stored secret permanently unrecoverable; there is no recovery path. Copy `/opt/infisical/.env` to a secure location outside this instance now, before you store any real secrets.



## Step 4: Sign up and create your first project

1. Open `https://secrets.example.com`. Infisical has built-in email-and-password login, so you sign up directly: no external identity provider to configure first. The first account to sign up becomes the organization admin.
2. Create a **project** (for example `payments-service`). Infisical scaffolds `dev`, `staging`, and `prod` environments for the project.
3. Inside the `dev` environment, select **Add secret**, set the key to `STRIPE_API_KEY`, and give it a placeholder value. Infisical encrypts the value before it reaches PostgreSQL.

## Step 5: Pull the secret with the Infisical CLI

From your workstation, point the CLI at your self-hosted instance and authenticate:

```bash
export INFISICAL_DOMAIN="https://secrets.example.com"
infisical login
```

Initialize the project link in a local working directory, then list the secret you created:

```bash
infisical init
infisical secrets --env=dev
```

Run a local command with the secret injected as an environment variable, without ever writing it to a file:

```bash
infisical run --env=dev -- printenv STRIPE_API_KEY
```



The [`quake.yaml` launch manifest](/resources/ai-assisted-development/quake-yaml#secrets) declares secret **names** in its `secrets[]` array but never values; the manifest schema explicitly forbids putting a value in `quake.yaml`. Infisical is a natural runtime secret store to hold those values and inject them at deploy time, the same role `infisical run` plays in this step. The launch handoff does not yet call Infisical's API directly; until it does, run `infisical run` (or `infisical export`) as a step before your deploy command to populate the named secrets.



## Step 6: Invite a teammate

1. Go to **Organization Settings** > **Members** > **Invite member**.
2. Enter a teammate's email. Infisical sends an invite they accept with their own email and password (or you configure SSO later, separately from the steps above).
3. Add them to the `payments-service` project with a role scoped to the environments they need.

## What you built

- **Applied the `infisical-secrets` template** to provision a network, security group, data volume, instance, and floating IP, with PostgreSQL and Redis started by cloud-init
- **Served Infisical over HTTPS** by pointing a domain at the floating IP and routing it through a Caddy reverse proxy
- **Signed up the first admin account** using Infisical's built-in login
- **Created a project, an environment, and a secret**, then pulled it with the Infisical CLI
- **Backed up `ENCRYPTION_KEY`** before storing any real secrets
- **Invited a teammate**

## Scope of this deployment

This template runs a single-VM Infisical host, not a managed secrets cloud. The instance is CPU-only and runs in one region, and it bundles PostgreSQL and Redis as containers on the same host. You operate the instance, Docker, Infisical, the database, Redis, and the data volume yourself: back them up (`ENCRYPTION_KEY` especially), patch them, and snapshot the volume before you resize or rebuild. For a larger team, move PostgreSQL and Redis onto their own instances and size the app host up.

## Next steps

- [Infisical secrets-management template](/resources/iac-templates/infisical-secrets): the template reference, parameters, and resource map
- [Self-managed PostgreSQL template](/resources/iac-templates/self-managed-postgres): the database to point at when you outgrow the bundled one
- [quake.yaml reference: Secrets](/resources/ai-assisted-development/quake-yaml#secrets): the manifest field this template's secrets feed
- [How to store application secrets and inject them at runtime](/docs/security/how-to/inject-app-secrets): the broader pattern this deployment specializes
- [Security hardening checklist](/docs/security/hardening-checklist): tighten SSH access and exposure before you store real secrets

## Clean up

When you no longer need the deployment, destroy everything the template created:

```bash
tofu destroy
```

Then remove the DNS A record you created in step 2. Because Infisical, its database, and Redis all live on the instance and its attached volume, `tofu destroy` removes them along with the infrastructure. Export the secrets you want to keep first; the Infisical CLI's `infisical export` command writes a project's secrets to a local file in dotenv or YAML format.
