Skip to main content

Docker Installation

The official SENAITE Docker image provides a fast way to run SENAITE without setting up a Python environment or running Buildout. It is well suited for evaluation, development and production deployments.

The image is published on Docker Hub under senaite/senaite.

Prerequisites

Quick Start

Pull the latest image and start a container:

docker run --rm --name senaite -p 8080:8080 senaite/senaite:latest

Open http://localhost:8080 in a browser and log in with admin:admin. Press Install SENAITE LIMS to complete the site setup.

The --rm flag removes the container when it stops. Data is not persisted between runs with this command — see the section below for persistent storage.

Start in foreground (debug) mode to see log output:

docker run --rm --name senaite -p 8080:8080 senaite/senaite:latest fg

Persistent Storage

By default, the database lives inside the container and is lost when the container is removed. Mount a host directory to persist data across restarts:

docker run -d \
--name senaite \
-p 8080:8080 \
-v senaite-data:/data \
senaite/senaite:latest

The named volume senaite-data is managed by Docker and survives container removal.

Docker Compose

A Compose file is the recommended way to manage SENAITE in production. Create a compose.yml file:

services:
senaite:
image: senaite/senaite:latest
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- senaite-data:/data
environment:
- SITE=senaite
- PASSWORD=changeme

volumes:
senaite-data:

Start the service:

docker compose up -d

Check the logs:

docker compose logs -f senaite

Stop and remove the containers (data volume is preserved):

docker compose down

ZEO Cluster

For production setups with multiple clients behind a load balancer, use the ZEO configuration. ZEO stores the database in a dedicated server container and allows several client instances to serve requests simultaneously.

services:
zeo:
image: senaite/senaite:latest
restart: unless-stopped
command: zeo
volumes:
- senaite-data:/data

instance1:
image: senaite/senaite:latest
restart: unless-stopped
ports:
- "8081:8080"
environment:
- ZEO_ADDRESS=zeo:8080
depends_on:
- zeo

instance2:
image: senaite/senaite:latest
restart: unless-stopped
ports:
- "8082:8080"
environment:
- ZEO_ADDRESS=zeo:8080
depends_on:
- zeo

volumes:
senaite-data:

Place a reverse proxy (nginx, Traefik, Caddy) in front of the instances to distribute traffic and handle TLS termination.

Environment Variables

VariableDescription
SITECreate and install a SENAITE site with this ID on first start
PASSWORDPassword for the admin user (default: admin)
ADDONSSpace-separated list of additional add-ons to install, e.g. senaite.storage
ZEO_ADDRESShost:port of the ZEO server — starts the image as a ZEO client
ZEO_READ_ONLYRun as a read-only ZEO client (off by default)
ZEO_SHARED_BLOB_DIRSet to on if ZEO server and client share the same blob directory
DEVELOPPath to a local add-on to mount and develop inside the container

Installing Add-ons

Pass add-on package names via the ADDONS variable. Pin a specific version with ==:

docker run --rm -p 8080:8080 \
-e ADDONS="senaite.storage==1.0.0 senaite.patient" \
senaite/senaite:latest

Pinning a Specific Version

Replace latest with a version tag from Docker Hub:

docker run --rm -p 8080:8080 senaite/senaite:v2.6.0

Available tags: v2.6.0, v2.5.0, v2.4.1, v2.4.0, latest.

Further Reading