# Deploy Nextcloud with the nextcloud-files template

Source: https://docs.quake.ai/resources/deployments/deploy-nextcloud-files-template
Markdown: https://docs.quake.ai/resources/deployments/deploy-nextcloud-files-template.md

---

# Deploy Nextcloud with the nextcloud-files template

Stand up [Nextcloud](https://nextcloud.com), an open-source file-sync and collaboration platform, on a single Quake AI instance using the [validated OpenTofu template](/docs/platform/validation#how-infrastructure-templates-are-checked) `nextcloud-files`. You apply the template, serve it over HTTPS through Caddy, set the trusted domain and admin bootstrap credentials, log in, upload a file and create a share link, and invite a teammate.

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



Nextcloud's app server plus its bundled MariaDB and Redis need more headroom than a single-process tool. This deployment's default sizing (4 vCPU, 4 GiB RAM) suits a small team. The attached data volume defaults to 40 GiB, larger than the lighter ops-tools deployments in this library, because Nextcloud's entire purpose is storing user files: plan to grow the volume as your team's storage usage grows.



<Figure size="md" caption="What you'll build: a Nextcloud host on a single instance with bundled MariaDB and Redis, served 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
  nextcloud: Nextcloud\napp
  db: MariaDB
  redis: Redis
  caddy -> nextcloud: proxies 443 to 8080
  nextcloud -> db: files, users, shares
  nextcloud -> redis: file locking, caching
}

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

</Figure>

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

## 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 the MariaDB root/app passwords and the Redis password into `/opt/nextcloud/.env`, and starts only `db` and `redis`. Nextcloud rejects requests for hosts not on its trusted-domain list, so the app container waits until you finish configuration.

Read the outputs and record `floating_ip`:

```bash
tofu output
```

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

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

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

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

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

```yaml
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    network_mode: host
    volumes:
      - /opt/nextcloud/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 the trusted domain and start Nextcloud

Edit `/opt/nextcloud/.env` and uncomment and set:

```text
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=CHOOSE_A_STRONG_PASSWORD
NEXTCLOUD_TRUSTED_DOMAINS=files.example.com
OVERWRITEPROTOCOL=https
OVERWRITECLIURL=https://files.example.com
```

Start the full stack:

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

## Step 4: Log in with the admin account

Open `https://files.example.com` and log in with the `NEXTCLOUD_ADMIN_USER`/`NEXTCLOUD_ADMIN_PASSWORD` you set in step 3.

## Step 5: Upload a file and create a share link

1. Select **Upload**, choose a file from your machine, and confirm.
2. Hover the uploaded file, select **Share**, then **Create link**.
3. Copy the generated link.

## Step 6: Invite a teammate

1. Select the account menu in the top right and choose **Users**.
2. Select **New user**, enter a username and password for your teammate, and confirm.
3. Share the login URL and the credentials with your teammate directly.

## What you built

- **Applied the `nextcloud-files` template** to provision a network, security group, data volume, instance, and floating IP, with MariaDB and Redis started automatically by cloud-init
- **Served Nextcloud over HTTPS** by pointing a domain at the floating IP and routing it through a Caddy reverse proxy
- **Set the trusted domain and admin bootstrap credentials** and started the Nextcloud app container
- **Logged in with the admin account**
- **Uploaded a file, created a share link, and invited a teammate**

## Scope of this deployment

This template runs a single-VM Nextcloud host, not a managed multi-tenant file-storage service. The instance is CPU-only and runs in one region, and it bundles MariaDB and Redis as containers on the same host, sized for a small team. You operate the instance, Docker, Nextcloud, the database, and the data volume yourself: back them up, patch them, and grow the attached volume as your team's file storage usage grows.

## Next steps

- [Nextcloud files and collaboration template](/resources/iac-templates/nextcloud-files): the template reference, parameters, and resource map
- [Mattermost team-chat template](/resources/iac-templates/mattermost-team-chat): another ops-tools template with the same domain-first setup pattern
- [Security hardening checklist](/docs/security/hardening-checklist): tighten SSH access and exposure before you connect production traffic

## 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 Nextcloud and its database both live on the instance and its attached volume, `tofu destroy` removes them along with the infrastructure.
