> ## Documentation Index
> Fetch the complete documentation index at: https://libops-renovate-github-com-libops-sitectl-isle-0-x.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Traefik service commands

> Core sitectl Traefik ingress operations for TLS modes, BYO certificates, and bot mitigation.

export const Compose = () => <Tooltip headline="Compose" tip={<>
        Docker Compose is Docker's tool for defining and running multi-container applications.{" "}
        <a href="https://docs.docker.com/compose/">https://docs.docker.com/compose/</a>.
      </>}>
    <>
      <Icon icon="docker" />
      {" "}
      Compose
    </>
  </Tooltip>;

All application stacks use Traefik for ingress. Traefik is therefore a core `sitectl` service namespace rather than an app-specific helper.

## Status

Check the Traefik container or ingress settings:

```bash theme={null}
sitectl traefik status
sitectl traefik ingress-status
```

## TLS Modes

Switch the active context between supported TLS modes:

```bash theme={null}
sitectl traefik tls http
sitectl traefik tls mkcert --domain local.example.test
sitectl traefik tls letsencrypt --email ops@example.org
sitectl traefik tls self-managed --cert-file ./cert.pem --key-file ./privkey.pem
```

| Mode           | Use when                                                                                       |
| -------------- | ---------------------------------------------------------------------------------------------- |
| `http`         | Local development or internal traffic should run without HTTPS.                                |
| `mkcert`       | Local development should use locally trusted certificates generated by mkcert.                 |
| `letsencrypt`  | Public HTTP traffic can reach Traefik and it should request certificates through ACME HTTP-01. |
| `self-managed` | Certificate and key material are mounted or managed outside sitectl.                           |

The command updates the shared ingress env contract:

* `URI_SCHEME`
* `TLS_PROVIDER`
* `TRAEFIK_TLS_ENABLED`
* `ACME_EMAIL` and `ACME_URL` when provided for Let's Encrypt

For `mkcert`, sitectl generates `certs/cert.pem` and `certs/privkey.pem`. For `self-managed`, sitectl installs the provided certificate and key to the same standard paths.

When a `docker-compose.tls.yml` override exists and the context is named, sitectl adds or removes that override from the context's compose file list as the TLS mode changes. Application templates can use the shared env values to set app-specific HTTPS behavior, but TLS mode selection belongs to the Traefik service command.

### Let's Encrypt

Use `letsencrypt` when the public domain points at this Traefik instance and inbound HTTP traffic can reach port 80 for the ACME HTTP-01 challenge:

```bash theme={null}
sitectl traefik tls letsencrypt --email ops@example.org
```

Set `--acme-url` when you need a specific ACME directory, such as a staging endpoint while testing:

```bash theme={null}
sitectl traefik tls letsencrypt --email ops@example.org --acme-url https://acme-staging-v02.api.letsencrypt.org/directory
```

## Bot Mitigation

Switch bot mitigation on or off:

```bash theme={null}
sitectl traefik bot-mitigation on --turnstile-site-key "$TURNSTILE_SITE_KEY" --turnstile-secret-key "$TURNSTILE_SECRET_KEY"
sitectl traefik bot-mitigation off
```

The command writes `BOT_MITIGATION`, `TRAEFIK_BOT_MITIGATION`, and optional Turnstile values to the context env file. Application route templates attach those settings to app-specific middleware.

Templates can use Cloudflare Turnstile test keys for local validation:

```yaml theme={null}
TURNSTILE_SITE_KEY: ${TURNSTILE_SITE_KEY:-1x00000000000000000000AA}
TURNSTILE_SECRET_KEY: ${TURNSTILE_SECRET_KEY:-1x0000000000000000000000000000000AA}
```

These keys are only for testing. For a real site, create Turnstile keys in Cloudflare and set `TURNSTILE_SITE_KEY` and `TURNSTILE_SECRET_KEY` in the site's environment before deploying bot mitigation.

Traefik's normal plugin setup can download plugin assets when the container starts. LibOps templates avoid that production-time network dependency by mounting local captcha-protect plugin source into Traefik when bot mitigation is enabled. The site repository carries the plugin source and challenge template Traefik needs, so recreating Traefik does not require a remote plugin download.

For app-level component toggles, plugins should use the core Traefik helper instead of carrying their own captcha-protect implementation. The plugin supplies its router name, route config path, and any app-specific middleware values:

```go theme={null}
opts := coretraefik.BotMitigationOptions{
  RouterName:       "ojs",
  RouterConfigPath: "conf/traefik/ojs.yml",
  Middleware: coretraefik.CaptchaProtectMiddlewareOptions{
    ProtectRoutes: "^/(issues|articles)",
  },
}

def := coretraefik.BotMitigation(opts)
err := coretraefik.ApplyBotMitigation(projectDir, coretraefik.BotMitigationStateOn, opts)
```

ISLE uses this path for the Drupal router. Other app plugins can set values such as `ProtectRoutes`, `ExcludeRoutes`, `GoodBots`, or `ChallengeURL` while still reusing the same local plugin install, Turnstile environment defaults, and Traefik middleware rendering.

Disabling bot mitigation removes the Traefik command, mounts, Turnstile environment defaults, and app router middleware entry. It does not need to delete an existing local plugin source directory or challenge template from the checkout.

Standalone Traefik Compose projects may still exist, but the shared command surface belongs to core `sitectl`, not to a dedicated Traefik CLI plugin.

## Reference

### `tls`

Switch Traefik TLS mode: http, mkcert, letsencrypt, or self-managed

```bash theme={null}
sitectl traefik tls MODE
```

| Flag                 | Default                  | Description                                                                 |
| -------------------- | ------------------------ | --------------------------------------------------------------------------- |
| `--acme-url`         |                          | ACME directory URL to set when using letsencrypt                            |
| `--cert-file`        |                          | Public certificate file to install for self-managed TLS                     |
| `--domain`           |                          | Domain to use for mkcert; defaults to DOMAIN from the env file or localhost |
| `--email`            |                          | ACME email to set when using letsencrypt                                    |
| `--env-file`         |                          | Env file to update; defaults to the first context env-file or .env          |
| `--key-file`         |                          | Private key file to install for self-managed TLS                            |
| `--tls-compose-file` | `docker-compose.tls.yml` | TLS compose override to add/remove from the context when it exists          |

### `bot-mitigation`

Switch Traefik bot mitigation on or off

```bash theme={null}
sitectl traefik bot-mitigation STATE
```

| Flag                     | Default | Description                                                        |
| ------------------------ | ------- | ------------------------------------------------------------------ |
| `--env-file`             |         | Env file to update; defaults to the first context env-file or .env |
| `--turnstile-secret-key` |         | Cloudflare Turnstile secret key to write to the env file           |
| `--turnstile-site-key`   |         | Cloudflare Turnstile site key to write to the env file             |

### `status`

Show the compose service container status

```bash theme={null}
sitectl traefik status
```

| Flag        | Default   | Description          |
| ----------- | --------- | -------------------- |
| `--service` | `traefik` | Compose service name |

### `ingress-status`

Show Traefik ingress TLS and bot-mitigation settings

```bash theme={null}
sitectl traefik ingress-status
```

| Flag         | Default | Description                                                        |
| ------------ | ------- | ------------------------------------------------------------------ |
| `--env-file` |         | Env file to update; defaults to the first context env-file or .env |
