#Caddy

If you already have a domain name and want to configure HTTPS as soon as possible, then `nb proxy caddy` is usually the most worry-free entry method.

Rather than maintaining Nginx's certificate configuration yourself, Caddy is more like the default shortcut to "run through the entry layer first".

## When is it more appropriate to use Caddy?

Generally speaking, Caddy is given priority in the following situations:

- You already have a domain name and want to access HTTPS as soon as possible
- You don’t want to maintain too many certificate and TLS details yourself
- All you need is a simple and stable entrance layer

If you have already used Nginx to manage many sites on the server, or you need to do more heavy caching, access control and customization rules later, then it will be more smooth to continue looking at [Nginx](./nginx.md).

## First follow these three commands.

If you just want to run the Caddy entry layer first, it is enough to remember these three commands by default:

```bash
nb proxy caddy use docker
nb proxy caddy generate --env test2 --host c.local.nocobase.com
nb proxy caddy reload
```

If Caddy has been installed locally, just change the first entry to `nb proxy caddy use local`.

In most scenarios, it is enough to execute `use` first, then `generate`, and finally `reload`. For other details and more commands, see the following chapters or the CLI reference.

## Step 1: Choose how to run Caddy yourself

If Caddy is already installed on the current machine, just use `use local`.

If you want to use the Docker version of Caddy, use `use docker`.

The `local` / `docker` here refers to the way **Caddy itself operates**.

Using the Docker version of Caddy:

```bash
nb proxy caddy use docker
```

Using a local installation of Caddy:

```bash
nb proxy caddy use local
```

If you forget which method is currently selected later, you can execute:

```bash
nb proxy caddy current
```

## Step 2: Execute `generate`

`generate` is used to generate Caddy configuration according to the specified env. The most common way to write it is:

```bash
nb proxy caddy generate --env test2 --host c.local.nocobase.com
```

If you also want to specify the entry port, you can also write it together:

```bash
nb proxy caddy generate --env test2 --host c.local.nocobase.com --port 8080
```

The meaning of the parameters here is:

- `--env`: Specify which CLI env to generate configuration for
- `--host`: Specify the domain name for external access
- `--port`: Specify the proxy entry port

For Caddy, `--host` is especially important. In a formal environment, try to pass a domain name that has been resolved to the current server by default, so that HTTPS access will be more natural.

If the command prompts that env is missing `appPort`, execute first:

```bash
nb env update test2 --app-port 56575
```

If you later change configurations such as `app-port` and `app-public-path` that will affect the proxy results, remember to re-execute `generate`.

## Step 3: Execute `reload`

After generating the configuration, execute directly:

```bash
nb proxy caddy reload
```

In most scenarios, just use this command directly. If it is not running yet, the startup will be processed internally first; if it is already running, it will be reloaded according to the latest configuration.

## What files will the CLI maintain?

Taking `test2` as an example, Caddy related commands usually maintain these files and directories:

| path | function |
| --- | --- |
| `NB_CLI_ROOT/.nocobase/proxy/caddy/test2/app.caddy` | Full site configuration generated by CLI |
| `NB_CLI_ROOT/.nocobase/proxy/caddy/nocobase.caddy` | Caddy general entry file, responsible for importing all env's `app.caddy` |
| `NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public/index-v1.html` | v1 SPA fallback page |
| `NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public/index-v2.html` | v2 SPA fallback page |
| `NB_CLI_ROOT/test2/storage/dist-client` | Currently used front-end build product directory |
| `NB_CLI_ROOT/test2/storage/uploads` | The upload directory of the current application |

in:

- `NB_CLI_ROOT/.nocobase/proxy/caddy/...` The following are agent auxiliary files maintained by CLI
- `NB_CLI_ROOT/test2/storage/...` The following are the application's own static resources and upload directories
- `nocobase.caddy` is a provider-level entry file and usually does not need to be modified manually.
- `app.caddy` is the complete Caddy site configuration of a certain env. Re-executing `generate` will overwrite the entire

:::warning note

If you want to make up for Caddy site-level configuration, such as additional headers, authentication, speed limiting or compression strategies, you can first adjust based on `app.caddy`; however, be aware that subsequent re-executions of `generate` will overwrite this file.

:::

## Handwritten configuration: what to do without CLI

If your application is not CLI hosted, or you explicitly want to maintain the complete Caddy configuration yourself, you can also write it by hand.

However, for NocoBase, the production environment entry is usually not just a simple `reverse_proxy`. In addition to forwarding API requests to the backend application, a complete and working Caddy configuration usually also needs to handle the upload directory, front-end static resources, `.well-known` routing, WebSocket, and SPA fallback page.

Taking `test2` as an example, key directories related to Caddy usually include:

- SPA fallback page directory: `NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public`
- Front-end build product directory: `NB_CLI_ROOT/test2/storage/dist-client`
- Upload directory: `NB_CLI_ROOT/test2/storage/uploads`

In other words, handwritten configuration usually needs to cover at least the following types of entries:

- `v`: Redirect `/v` to `/v/`
- `uploads`: Expose upload directory
- `dist`: Expose the front-end build product directory
- `oauth well-known`: Handle OAuth discovery paths
- `openid well-known`: Handle OpenID discovery paths
- `api`: forward `/api/` request to the backend application
- `ws`: forward WebSocket requests to the backend application
- `spa v2`: Provides front-end entry and return page for `/v/`
- `spa v1`: Provides front-end entry and return page for `/`

Therefore, a complete Caddy configuration is usually not just written in the following general way:

```text
your-domain.com {
  reverse_proxy 127.0.0.1:13000
}
```

For a CLI-hosted application like `test2`, a structure closer to a real deployment would usually look like this:

```text
c.local.nocobase.com {
    encode zstd gzip

    handle /v {
        redir * /v/ 302
    }

    handle_path /storage/uploads/* {
        root * NB_CLI_ROOT/test2/storage/uploads
        header Cache-Control public
        header X-Content-Type-Options nosniff
        file_server
    }

    handle_path /dist/* {
        root * NB_CLI_ROOT/test2/storage/dist-client
        header Cache-Control public
        file_server
    }

    @oauth path_regexp oauth ^/\\.well-known/oauth-authorization-server/(.+)$
    handle @oauth {
        rewrite * /{re.oauth.1}/.well-known/oauth-authorization-server
        reverse_proxy host.docker.internal:56575
    }

    @openid path_regexp openid ^/\\.well-known/openid-configuration/(.+)$
    handle @openid {
        rewrite * /{re.openid.1}/.well-known/openid-configuration
        reverse_proxy host.docker.internal:56575
    }

    handle /api/* {
        reverse_proxy host.docker.internal:56575
    }

    handle /ws {
        reverse_proxy host.docker.internal:56575
    }

    handle_path /v/* {
        root * NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public
        header Cache-Control "no-store, no-cache, must-revalidate"
        header X-Robots-Tag "noindex, nofollow"
        try_files {path} /index-v2.html
        file_server
    }

    handle_path /* {
        root * NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public
        header Cache-Control "no-store, no-cache, must-revalidate"
        header X-Robots-Tag "noindex, nofollow"
        try_files {path} /index-v1.html
        file_server
    }
}
```

There are also two key points here:

- `NB_CLI_ROOT/.nocobase/proxy/caddy/...` The following is the SPA rollback page directory maintained by CLI
- `NB_CLI_ROOT/test2/storage/...` The following is the use of your own build product directory and upload directory

If your application uses sub-path deployment, or the front-end resources, upload directory and entry layer are not in the same path perspective, handwritten configuration will be more error-prone. In this scenario, it is usually more recommended to execute:

```bash
nb proxy caddy generate --env test2 --host c.local.nocobase.com
```

Then make adjustments based on the generated results.

If you want to let the CLI help you run through the paths and routes first, then the generated structure will usually be:

```text
NB_CLI_ROOT/.nocobase/proxy/caddy/nocobase.caddy
NB_CLI_ROOT/.nocobase/proxy/caddy/test2/app.caddy
NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public/index-v1.html
NB_CLI_ROOT/.nocobase/proxy/caddy/test2/public/index-v2.html
NB_CLI_ROOT/test2/storage/dist-client
NB_CLI_ROOT/test2/storage/uploads
```

in:

- `nocobase.caddy` is responsible for unifying `import */app.caddy`
- `test2/app.caddy` is the complete site configuration of this env `test2`
- `public/index-v1.html` and `public/index-v2.html` are CLI generated SPA fallback pages

A more prudent approach is usually:

1. First let the CLI generate the Caddy configuration
2. Confirm the routing structure and actual path based on the generated results.
3. Then make manual adjustments according to your domain name, running mode and mounting path.

This is usually less likely to miss details related to WebSockets, static resources, upload directories, `.well-known` routes, or SPA fallback pages than handwriting a configuration from scratch.

## Check and reload configuration

If you write or manually adjust the Caddy configuration, verify it first after making the changes, and then reload:

```bash
caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy
```

If you are not using `systemd` to manage Caddy, you can use your own startup and reload methods instead.

If you manage the entry layer through `nb proxy caddy`, it is usually preferred to use:

```bash
nb proxy caddy reload
```

If you want to see the current driver, total entry file path, runtime root directory and container or local binary information, you can execute:

```bash
nb proxy caddy info
```

If you just want to quickly confirm whether it is running, you can execute:

```bash
nb proxy caddy status
```

## Common instructions

- `nb proxy caddy generate` is for applications installed by `nb init`
- If you already have a domain name that can be resolved to the server normally, Caddy is often the fastest way to get HTTPS.
- If you subsequently change configurations such as `app-port` and `app-public-path` that will affect the proxy results, remember to re-execute `generate`

## Related links

- [Production environment reverse proxy](./index.md)
- [Nginx](./nginx.md)
- [Install using CLI](../../installation/cli.md)
- [Application configuration with `.env`](../../installation/env.md)
- [`nb proxy caddy` Command Reference](../../../api/cli/proxy/caddy/index.md)
