# Deploy Appsmith with the appsmith-internal-tools template

Source: https://docs.quake.ai/resources/deployments/deploy-appsmith-internal-tools-template
Markdown: https://docs.quake.ai/resources/deployments/deploy-appsmith-internal-tools-template.md

---

# Deploy Appsmith with the appsmith-internal-tools template

Stand up [Appsmith](https://www.appsmith.com) Community Edition, an open-source low-code platform for internal tools, on a single Quake AI instance using the [validated OpenTofu template](/docs/platform/validation#how-infrastructure-templates-are-checked) `appsmith-internal-tools`. You apply the template, sign up the first admin account, point a domain at the host and serve it over HTTPS, connect a datasource, build a minimal internal app, and invite a teammate.

Appsmith keeps your team's internal tools on infrastructure you own. You run it yourself; this is a self-hosted tool you operate, not a managed multi-tenant service.

<Figure size="md" caption="What you'll build: an Appsmith host on a single instance with the app server, embedded MongoDB, and embedded Redis bundled in one container, 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
  appsmith: Appsmith fat container {
    app: App server
    mongo: Embedded MongoDB
    redis: Embedded Redis
  }
  caddy -> appsmith.app: proxies 443 to 8080
}
db: Datasource\n(REST API or Postgres) {shape: cylinder}

user -> fip: HTTPS
fip -> instance.caddy
instance.appsmith.app -> db: queries
```

</Figure>

<PricingCompanion
  components={[
    { kind: "template", slug: "appsmith-internal-tools", 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 `appsmith-internal-tools` template directory from [the template reference page](/resources/iac-templates/appsmith-internal-tools).
- A domain you can point at the instance, for the HTTPS step.

## 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 `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` into `/opt/appsmith/.env`, and starts the fat container: no held-back service waits on manual configuration.

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

```bash
tofu output
```



`APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` in `/opt/appsmith/.env` encrypt every datasource credential Appsmith stores at rest. Losing them makes stored datasource credentials unrecoverable. Copy `/opt/appsmith/.env` to a secure location outside this instance now, before you connect any real datasource.



## Step 2: Sign up the first admin account

Open `app_url` from the previous step (`http://YOUR_FLOATING_IP:8080`). The raw app port is restricted to the private network by default; tunnel over SSH if you have not opened `app_allowed_cidr` to your workstation.

Sign up with an email and password. The first account to sign up becomes the workspace admin.

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

Serving Appsmith over a stable HTTPS domain is recommended before you invite teammates or connect production datasources.

1. Create a DNS **A record** for your domain (for example `tools.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 tools.example.com
```

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

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

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

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

4. Restart the stack:

```bash
cd /opt/appsmith
sudo docker compose up -d
```

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 4: Connect a datasource

1. Inside your workspace, select **New** > **Datasource**.
2. Choose **REST API** for the quickest connection, or point at a [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres) instance if you already run one: fill in the host, port, database name, and credentials.
3. Select **Test** to confirm the connection, then **Save**.

## Step 5: Build a minimal internal app

1. Create a new app and drag a **Table** widget onto the canvas.
2. Bind the table to a query against the datasource you connected (for example a `SELECT` query or a `GET` request).
3. Add a **Button** widget wired to a second query (for example an `UPDATE` or a `POST` request) that runs against the row selected in the table.
4. Select **Deploy** to publish the app to your workspace.

## Step 6: Invite a teammate

1. Go to **Settings** > **Members** > **Invite**.
2. Enter a teammate's email and assign them a role (**App Viewer**, **Developer**, or **Administrator**) scoped to what they need.
3. Appsmith emails an invite they accept with their own credentials, if you configured outbound email, or you share the workspace URL directly.

## What you built

- **Applied the `appsmith-internal-tools` template** to provision a network, security group, data volume, instance, and floating IP, with the fat container started automatically by cloud-init
- **Signed up the first admin account**
- **Served Appsmith over HTTPS** by pointing a domain at the floating IP and routing it through a Caddy reverse proxy
- **Connected a datasource** and **built a minimal internal app** with a table and one action
- **Backed up the encryption password and salt** before connecting any real datasource
- **Invited a teammate**

## Scope of this deployment

This template runs a single-VM Appsmith host, not a managed low-code cloud. The instance is CPU-only and runs in one region, and the app server, embedded MongoDB, and embedded Redis all run inside the same container. You operate the instance, Docker, Appsmith, and the data volume yourself: back up `/appsmith-stacks` (the encryption keys especially), patch the image, and watch resource use as concurrent users grow.

## Next steps

- [Appsmith internal-tools template](/resources/iac-templates/appsmith-internal-tools): the template reference, parameters, and resource map
- [Self-managed PostgreSQL template](/resources/iac-templates/self-managed-postgres): a datasource to pair with Appsmith for a database-backed internal app
- [Security hardening checklist](/docs/security/hardening-checklist): tighten SSH access and exposure before you connect production datasources

## 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 3, if you added one. Because Appsmith and all of its persistent state live on the instance and its attached volume, `tofu destroy` removes them along with the infrastructure. Export any apps you want to keep first: **Settings** > **Export application** writes an app definition to a local JSON file.
