2. Deploying Opal for local use

Architecture at a glance

graph LR
  B["Browser<br/>http://localhost:8080"] -->|8080| O["Opal (8080)"]
  subgraph Profiles["docker network: opalnet"]
    O -->|R/DataSHIELD| R["Rock (8085)"]
    O -->|Auxiliary| MONGO["MongoDB (27017)"]
  end

  %% Define a lighter background for the subgraph
  classDef light fill:#f9f9f9,stroke:#aaa,stroke-width:1px;
  class Profiles light;

Services and roles

  • Opal (OBiBa):
    • Main DataSHIELD server and admin UI. Exposes HTTP on 8080.
    • Reads configuration via environment variables (e.g., OPAL_ADMINISTRATOR_PASSWORD, MONGO_*, ROCK_HOSTS) docs docs.
  • Rock (R server):
    • Executes R/DataSHIELD calls initiated by Opal, reachable as rock:8085 on the Docker network.
    • Ships with DataSHIELD packages; ideal for quick connectivity checks.
  • MongoDB (auxiliary store):
    • Used by Opal for auxiliary features; we pin to mongo:6.0 per Opal documentationreference.

Goal

Deploy Opal locally on your laptop using Docker Compose. This lets you try DataSHIELD quickly without DNS or cloud setup and is perfect for package development and smoke tests. See the prerequisites in @env_setup.qmd and the scope in @up_2_speed.qmd.

What we will deploy

  • Opal server (obiba/opal:latest) with admin password set
  • Rock R server (datashield/rock-base:latest) for DataSHIELD execution
  • MongoDB for auxiliary storage

References:

Files layout

Use this folder layout:

opal-local/
├── .env
├── docker-compose.yml
├── data/
│   ├── opal/
│   └── mongo/
└── logs/

1) Create a .env file

Keep secrets out of the compose file.

OPAL_ADMINISTRATOR_PASSWORD=ChangeMe123!
  • OPAL_ADMINISTRATOR_PASSWORD is required on first start of obiba/opal.
Note

Production note: For production deployments, the most correct way to handle sensitive information is through Docker secrets, Kubernetes secrets, or your platform’s native secrets management system. We use a .env file here for workshop simplicity, which also helps reduce the risk of password leaks when sharing docker-compose files to colleagues or collaborators.

We will explain briefly how to use Docker secrets to store the OPAL_ADMINISTRATOR_PASSWORD information in a secure way.

In order to create a Docker secret, you can run the following command:

echo -n "ChangeMe123!" | docker secret create opal_admin_password -

This will create a secret named opal_admin_password with the value ChangeMe123!.

To use the secret on the docker-compose.yml file, we have to modify it as follows:

services:
  opal:
    [...]
    environment:
      - MONGO_HOST=mongo
      - MONGO_PORT=27017
      - ROCK_HOSTS=rock:8085
    secrets:
      - opal_admin_password
    [...]
    entrypoint: >
      sh -c "export OPAL_ADMINISTRATOR_PASSWORD=$$(cat /run/secrets/opal_admin_password) &&
             exec /usr/local/bin/opal"

Note that secrets only work when we use Docker in swarm mode. We will have to run:

docker swarm init   # if not already done
docker stack deploy -c docker-compose.yml mystack

2) docker-compose.yml

Defines Opal, Rock, and MongoDB. Key env vars match Opal docs (MONGO_*, ROCK_HOSTS) opaldoc installation.

services:
  opal:
    image: obiba/opal:latest
    depends_on:
      - rock
      - mongo
    ports:
      - "8080:8080"
      - "8443:8443"
    environment:
      - OPAL_ADMINISTRATOR_PASSWORD=${OPAL_ADMINISTRATOR_PASSWORD}
      - MONGO_HOST=mongo
      - MONGO_PORT=27017
      - ROCK_HOSTS=rock:8085
    volumes:
      - ./data/opal:/srv
      - ./logs:/var/log/opal
  mongo:
    image: mongo:6.0
    volumes:
      - ./data/mongo:/data/db

  rock:
    image: datashield/rock-base:latest
    environment:
    - ROCK_ID=new-stack-rock

networks:
  default:
    name: opalnet

Highlights: - Opal sees Rock at rock:8085 and MongoDB via service names on the internal network. - Opal is directly accessible on port 8080 for simplicity. - All services run on the opalnet Docker network. - Data is persisted in local folders (./data/opal, ./data/mongo) instead of Docker volumes for easier management and portability.

3) Bring it up

From the directory containing docker-compose.yml and .env:

# Create data directories
mkdir -p data/opal data/mongo logs

# Start services
docker-compose up -d
# First start may take a minute while images are pulled.

# Check health
docker-compose ps
docker-compose logs

For clean restarts (recommended for development):

# Clean restart - ensures proper service registration
docker-compose down
docker-compose up -d
  • Open http://localhost:8080 in your browser.
  • Login with user administrator and the password you set in .env.

If you see the Opal UI and can navigate the Admin area, your stack is running.

4) Minimal DataSHIELD test (R)

Verify connectivity via DSOpal/DSI.

library(DSI)
library(DSOpal)
library(httr)
set_config(config(ssl_verifyhost = 0L, ssl_verifypeer = 0L))
library(dsBaseClient)


b <- DSI::newDSLoginBuilder()
b$append(
    server   = "local",
    url      = "http://localhost:8080",
    user     = "administrator",
    password = "ChangeMe123!",
    profile = "default"
)

logins <- b$build()
conns <- DSI::datashield.login(logins)
ds.ls()

Notes:

  • The Opal + Rock images are DataSHIELD‑ready by design. If a package appears missing, ensure Rock pulled the latest image or install required packages in Rock.
  • For real deployments, use HTTPS with proper certificates and omit the SSL verification overrides.

Troubleshooting

  • Opal not reachable: check if port 8080 is available locally.
  • Login fails: ensure OPAL_ADMINISTRATOR_PASSWORD was set at first start; to reset, run docker-compose down, remove the data/opal folder, and start again.
  • Mongo version: Opal expects MongoDB ≤ 6.0; using mongo:6.0 matches docs.
  • Rock connection issues: check that Rock container is running and healthy.
  • Profile registration issues: use docker-compose down && docker-compose up -d for clean restarts that ensure proper service registration.

Next steps

When ready to go live, add Nginx reverse proxy with TLS, DNS configuration, and hardening as we’ll cover in the later section. For now, you have a working local Opal + DataSHIELD lab.