Skip to content

Installation (Docker)

The instructions on this page assume that the user is familiar with Docker. You can read the Docker manuals here.

Image

Apleno Server is published on Docker Hub as pgmsolutions/apleno.

Tip

Pull a specific version tag (e.g. 2.11.0) for production rather than latest, so upgrades are a deliberate choice.

How to launch Apleno Server

Directly in command line

Here is an example command line to launch Apleno Server with Docker:

# docker run -d --name apleno -p 8080:8080 -e "ROOT=http://localhost:8080" -v apleno-data:/opt/apleno/data -v apleno-languages:/opt/languages --restart unless-stopped pgmsolutions/apleno

You can then:

  • Stop the instance with docker container stop apleno;
  • Start the instance with docker container start apleno;
  • Delete an instance with docker rm apleno.

With docker-compose

Here is an example docker-compose.yml file for Apleno Server:

services:
  apleno:
    image: pgmsolutions/apleno:latest
    environment:
      ROOT: http://localhost:8080
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - apleno-data:/opt/apleno/data
      - apleno-languages:/opt/languages

volumes:
  apleno-data:
  apleno-languages:

You can then:

  • Create and start Apleno Server with docker compose up -d;
  • Stop it with docker compose stop;
  • Start it again with docker compose start;
  • Stop and delete the instance with docker compose down.

Volumes

Apleno-related data (database, uploaded apps, app outputs, per-app package libraries) is stored in the container's /opt/apleno/data folder.

Warning

Without this folder mounted, everything (including the database) is lost the moment the container is recreated. Always mount it, even for a quick evaluation.

R and Python are not baked in as a single fixed version. They're managed by rig and uv, and installed under /opt/languages, which should also be mounted so any package or extra language version you install persists across updates.

For both folders, use a named volume (as in the examples above) rather than a bind mount to an empty host folder. A named volume gets seeded with the image's own content the first time it's used. A bind mount to an empty folder does not, and would start empty.

Configuration

Inside a container, Apleno Server is configured entirely with environment variables (the deprecated config.yml file isn't used under Docker). The full list of settings, with defaults, is on the configuration file page. A few you'll likely want to set:

  • ROOT: the public URL (required, see above).
  • TRUSTED_PROXIES: only relevant if you put a reverse proxy in front of the container, see behind a reverse proxy.
  • SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM; see configuring SMTP.
  • OIDC/OIDC_* or AZURE/AZURE_*: see single sign-on.
  • HTTPS, HTTPS_PORT, HTTPS_KEY, HTTPS_CERT: see Configuring HTTPS, though a reverse proxy in front of the container is generally simpler than terminating TLS in Apleno Server itself.

First-time setup

Once the container is running, continue with the first-time configuration wizard to enter your license key and create the administrator account.

R & Python versions

R and Python aren't pinned to a single version: the image ships with a curated set of recent versions of each, auto-detected at startup (admin Languages page).

To install another version without waiting for a new image release, run it directly inside the running container:

docker exec -it apleno rig add 4.4.2             # add an R version
docker exec -it apleno uv python install 3.13    # add a Python version

Then click Detect on the admin Languages page (or restart the container ; detection also runs at boot). Because /opt/languages is a named volume, anything installed this way survives container updates and recreation, just like the versions that shipped with the image.

Packages for a given R or Python version (whether installed through the admin Packages page, or by an app installing something itself at runtime) are stored alongside that version under /opt/languages, so they persist the same way and don't collide between versions.