Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions docs/installation/advanced/custom-certificates.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ By default, Seatable uses Let's Encrypt to generate valid certificates for publi

!!! warning "Limitations of Self-Signed Certificates"

Self-signed certificates should only be used for testing purposes. Even if your clients or browsers trust the certificate, Docker containers do not trust each other by default.
As a result, the Python Runner will be unable to communicate with your Base data, and the Python Pipeline will not work with an **untrusted** self-signed certificate.
Self-signed certificates should only be used for testing purposes. Even if your clients or browsers trust the certificate, Docker containers do not trust each other by default.

To avoid these issues, use a valid (standard or wildcard) certificate issued by a recognized certificate authority.
For SeaTable Server and the Python Pipeline (scheduler and starter), the trust can be established by adding the certificate to their truststore (see below). The `python-runner` is started on demand by the `python-starter` and requires a separate setup (see [Custom CA for the python-runner](#custom-ca-for-the-python-runner)).

To avoid these issues entirely, use a valid (standard or wildcard) certificate issued by a recognized certificate authority.

## Make certificates available to caddy

Expand Down Expand Up @@ -83,6 +84,43 @@ You can mount multiple certificates by adding additional volume mounts. Every `.

Make sure that `REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt` is set in your environment variables. This tells all Python libraries (requests, pysaml2, etc.) to use the system trust store instead of their own bundled certificates. This variable is included by default since version 5.0 in the [seatable-server.yml](https://github.com/seatable/seatable-release/blob/main/compose/seatable-server.yml).

## Custom CA for the python-runner

The truststore setup described above covers the long-running `python-scheduler` and `python-starter` containers, but **not** the `python-runner`. The runner is an ephemeral container that the starter launches via `docker run` for every script execution. It is based on Alpine, runs as a non-root user, never executes `update-ca-certificates`, and has no certificate mounted into it. As a result, scripts that call `base.auth()` (or any other HTTPS endpoint with your custom CA) will fail with an SSL error — even though `print("hello world")` works fine.

To fix this, you need to do two things at the same time, both via [`PYTHON_RUNNER_OTHER_OPTIONS`](python-pipeline-configuration.md#mounting-additional-directories):

1. Mount the trusted CA bundle from the host into the runner.
2. Set `REQUESTS_CA_BUNDLE` inside the runner so that Python's `requests` library uses it (without this, `requests` falls back to the `certifi` bundle and ignores `/etc/ssl/certs/`).

### Build a merged CA bundle on the host

If you only mount your own certificate, the runner will no longer trust any public CAs, which can break scripts that call third-party APIs. The cleanest solution is to merge the host's public CA bundle with your custom certificate:

```bash
cat /etc/ssl/certs/ca-certificates.crt /opt/caddy/certs/cert.pem \
> /opt/seatable-compose/runner-ca-bundle.crt
```

The bundle is placed next to your compose files and `.env` so that it is co-located with the configuration that references it. Repeat this step whenever your custom certificate is renewed.

### Configure the python-starter

Add the following to your `custom-python-pipeline.yml` (create it if it does not exist) and reference the file in the `COMPOSE_FILE` variable of your `.env`:

```yaml
services:
python-starter:
environment:
- PYTHON_RUNNER_OTHER_OPTIONS=["--volume=/opt/seatable-compose/runner-ca-bundle.crt:/etc/ssl/certs/runner-ca-bundle.crt:ro","--env=REQUESTS_CA_BUNDLE=/etc/ssl/certs/runner-ca-bundle.crt"]
```

!!! info "Syntax of PYTHON_RUNNER_OTHER_OPTIONS"

The value must be a valid Python list literal (parsed via `ast.literal_eval`). Each item is appended verbatim to the `docker run` command, so environment variables must use the `--env=KEY=VALUE` form — a bare `KEY=VALUE` would be interpreted as a positional argument and break the container start. Do not wrap the list in additional quotes.

Restart the `python-starter` with `docker compose up -d` afterwards. To verify, set `PYTHON_STARTER_LOG_LEVEL=DEBUG` and check `docker compose logs -f python-starter` — the full `docker run` command should now include both the volume mount and the `REQUESTS_CA_BUNDLE` environment variable.

## Self-signed certificates generated by Caddy

Even if it is not recommended, it is possible to ask Caddy to use auto generated self-signed certificates.
Expand Down
Loading