# eLabFTW — Cloudron Package

[eLabFTW](https://www.elabftw.net/) is an open-source electronic lab
notebook (ELN) and inventory manager for research teams: experiments with
revisions, resources database, scheduler, MFA / API keys, timestamping and
PDF export pipelines. Packaged as an **official-image wrapper** around the
upstream `elabftw/elabimg:5.6.12` image (nginx + php-fpm + s6-overlay,
digest pinned).

- **Upstream:** https://github.com/elabftw/elabftw (AGPL-3.0)
- **Ticket:** [#669](https://projects.knownelement.com/issues/669)
- **Category:** Business-Apps · **Pattern:** official-image wrapper +
  `start.sh` env mapping

## Authentication (auth gate verdict: ⚠️ LDAP — auth-risk flag)

eLabFTW 5.x auth methods are **local, SAML and LDAP — there is no OIDC
support** (verified in `src/Enums/AuthMethod.php`; no OIDC client anywhere
upstream). Per the AGENTS.md policy this package ships with the
**LDAP path** and carries the auth-risk flag:

1. The manifest enables the Cloudron **`ldap`** addon, so the container
   holds `CLOUDRON_LDAP_*` credentials (inspect them with
   `cloudron exec env | grep LDAP` in the app terminal).
2. Log in once as the sysadmin account created during first-run setup.
3. Open **Sysconfig → Server → LDAP** and map the panel to the Cloudron
   directory:

| eLabFTW LDAP panel | Cloudron value |
|--------------------|----------------|
| Toggle LDAP login | on |
| Scheme | `ldap` |
| Host | `CLOUDRON_LDAP_HOST` |
| Port | `CLOUDRON_LDAP_PORT` (3002) |
| Use TLS | off (plain LDAP on the box) |
| Base DN | `CLOUDRON_LDAP_USERS_BASE_DN` |
| Username (bind DN) | `CLOUDRON_LDAP_BIND_DN` |
| Password | `CLOUDRON_LDAP_BIND_PASSWORD` |
| Search attr | `mail` (or `username`) |
| Email attribute | `mail` |
| Firstname / Lastname | `givenname` / `sn` |

**auth-risk: LDAP** — this must be validated on the live Cloudron before
production use (see STATUS.md). SAML remains available as an alternative
against an external IdP, but the Cloudron platform provider is OIDC-only,
so LDAP is the only platform-integrated SSO path today.

## Addons & ports

| Concern | Cloudron wiring |
|---------|-----------------|
| Database | `mysql` addon → `DB_*` (schema auto-installed / auto-updated) |
| Files | `localstorage`: `/app/data/uploads`, `/app/data/exports` |
| SSO directory | `ldap` addon (`CLOUDRON_LDAP_*`, see above) |
| Web | single HTTP port `443` (`DISABLE_HTTPS=true`; TLS at the proxy) |

## Runtime layout

- `start.sh` waits for MySQL, maps `CLOUDRON_MYSQL_*` → elabimg `DB_*`,
  sets `SITE_URL` from `CLOUDRON_APP_ORIGIN`, and hands over to the
  upstream s6 `/init`, which applies config and runs
  `bin/init db:install` / `bin/console db:update` (`AUTO_DB_INIT` /
  `AUTO_DB_UPDATE`).
- The `SECRET_KEY` (encrypts SMTP / timestamping passwords) is generated
  once and persisted at `/app/data/.secret_key` — hex, because the image
  entrypoint injects it via unescaped `sed`.
- First boot: open the app URL and complete the initial setup (create the
  sysadmin + first team); afterwards do the LDAP wiring above.

## Environment knobs (.env.example)

| Variable | Default | Purpose |
|----------|---------|---------|
| `ELABFTW_TZ` | `UTC` | PHP / container timezone |
| `ELABFTW_MAX_UPLOAD_SIZE` | `100M` | nginx + PHP upload limit |
| `ELABFTW_PHP_MAX_CHILDREN` | `15` | php-fpm workers (tuned for 1536 MB) |
| `ELABFTW_MAX_PHP_MEMORY` | `512M` | per-worker PHP memory limit |
| `ELABFTW_AUTO_DB_INIT` | `true` | run `db:install` at boot |
| `ELABFTW_AUTO_DB_UPDATE` | `true` | run `db:update` at boot |

## Build & install

```bash
docker build --cgroup-parent ukrrs-batch.slice -t elabftw-cloudron:test \
  Package-Workspace/Business-Apps/elabftw/
```

`cloudron build && cloudron install` on the Cloudron VPS for real
deployment. First start waits for MySQL, installs the schema and serves
the setup wizard on the app domain.
