Web service that converts between molecule formats using OpenBabel.
The service ships a React frontend at / to convert structures interactively
(text input or structure editor), the Swagger API documentation at
/documentation, and the REST API under /v1.
The service is distributed as a Docker image at ghcr.io/cheminfo/openbabel.
The deployment mode is selected with the COMPOSE_FILE variable in .env
(with none set, docker compose uses compose.yaml, which publishes the port
on the host).
git clone https://github.com/cheminfo/openbabel.git
cd openbabel
cp .env.example .env
# Run the released image:
docker compose pull && docker compose up -d
# Or rebuild from the current checkout:
docker compose up -d --buildThe default port is 20808. Change it by editing PORT in .env.
Open http://localhost:20808/ to access the converter
frontend, or http://localhost:20808/documentation
for the Swagger UI.
For a publicly-reachable deployment behind Cloudflare Tunnel (no host port published),
uncomment the following line in .env:
COMPOSE_FILE=compose.cloudflared.yamlIn the Cloudflare dashboard (https://dash.cloudflare.com):
- Navigate to Networking → Tunnels → Create a tunnel → Cloudflared connector.
- Copy the generated token into
.envasTUNNEL_TOKEN=.... - Open the tunnel, go to the Published applications tab, and add an application with:
- Public hostname:
openbabel.lactame.com(or another domain you control) - Service type: HTTP
- Service URL:
openbabel:20808(matchPORTfrom.env)
- Public hostname:
Then start the stack:
docker compose up -dFor a host that already runs a Traefik reverse proxy on
an external Docker network named traefik (with a websecure entrypoint and
a letsencrypt cert resolver), uncomment the following line in .env and start
the stack:
COMPOSE_FILE=compose.traefik.yamldocker compose up -dEdit the Host(...) label in compose.traefik.yaml to point at the public
hostname you have configured for this service (default openbabel.cheminfo.org).
npm install
npm run dev # backend API on :20808
npm run dev-frontend # frontend dev server on :5173 (proxies /v1 to :20808)The frontend lives in the frontend/ npm workspace (React + Vite). In
production the backend serves the built frontend at /; build it locally with
npm run build.
PORT and BABEL are read from the environment (with .env auto-loaded via
node --env-file-if-exists=.env). By default BABEL is auto-detected from
/opt/homebrew/bin/obabel and /usr/bin/obabel.
At most MAX_PARALLEL_CONVERSIONS (default 4) obabel processes run in
parallel; further requests wait in a queue of at most MAX_QUEUED_CONVERSIONS
(default 32) entries, beyond which the API replies 503. A conversion running
longer than CONVERSION_TIMEOUT_MS (default 2000) is killed and the response
log explains the timeout. See .env.example for all variables.
Run the full check (tests + eslint + prettier):
npm testRun the Playwright end-to-end tests (they start the backend and the frontend
dev server automatically; run npx playwright install chromium once in
frontend/ first):
npm run test-e2eOpenBabel is subject to its own license.