Before You Start
- Install the latest Docker Desktop (or Docker Engine with the Compose plugin) and reboot if prompted.
- Ensure at least 2 GB of free disk space for base images and seed data.
- Confirm your account has access to the repository in the organisation’s source control system.
Quick Setup
- Copy and unzip:
<dsp>andcd dsp. - Copy any provided
.envtemplates if custom credentials are required. - Bring the stack online with
docker-compose up --build. - Wait for the first run to import
db/niph_dsps.sqlinto MySQL automatically. - Visit each service to confirm connectivity (see table below).
Understanding the Data Ecosystem
The Docker stack wires the PHP/Apache portal, MySQL database, phpMyAdmin console, and R-enabled Jupyter service together. Shared bind mounts ensure uploaded datasets and vetted R scripts stay identical across runtime services.
Platform Architecture
dsp_appserves dashboards on port 8082 and talks to MySQL over the internal network.dsp_dbseeds fromdb/niph_dsps.sqlon first boot and exposes port 3307 for host access.dsp_phpmyadminanddsp_jupyterconnect to the same database/files so admins can troubleshoot or run reproducible analytics.
Data Lifecycle & Governance
dsps_tbl_datasourcebinds each dataset to its owner (fkisp_id_of), type, category, filenames, and publication state.dsps_tbl_datasource_permissionlogs read/download/analyze approvals whiledsps_tbl_datasource_usedtracks downstream usage.ist_tbl_peopleandist_tbl_usersprovide identity, roles, and theisu_can_run_rcapability flag for analytics features.
Diagram Reference
Service Endpoints
| Service | URL | Notes |
|---|---|---|
| PHP Application | http://localhost:8082 |
Uses credentials defined in docker-compose.yml. |
| phpMyAdmin | http://localhost:8081 |
Login with dsp_user/dsp_pass or MySQL root credentials. |
| Jupyter (R) | http://localhost:8888 |
Authenticate with token dsp-token. |
| MySQL (host access) | localhost:3307 |
Database niph_dsps, user dsp_user/dsp_pass. |
Configuration Checklist
Update the following environment variables in docker-compose.yml (or host environment) to match your deployment:
| Variable | Description | Default |
|---|---|---|
DB_HOST |
Database hostname reachable from the PHP container. | mysql |
DB_PORT |
MySQL port exposed inside the container. | 3306 |
DB_NAME |
Name of the primary DSP database. | niph_dsps |
DB_USER |
Application database username. | dsp_user |
DB_PASS |
Application database password. | dsp_pass |
RSCRIPT_PATH |
Override if Rscript is not located at the system default. |
/usr/bin/Rscript |
JUPYTER_EXTERNAL_URL |
Base URL embedded in the portal when exposing Jupyter on a custom host or domain. | https://localhost |
JUPYTERHUB_PORT |
Published host port for the JupyterHub ingress. | 443 |
JUPYTER_TOKEN |
Legacy token for standalone Jupyter deployments. | (empty) |
DSP_APP_ORIGINS |
Space-separated origins allowed to call Jupyter APIs (CORS). | http://localhost:8082 http://127.0.0.1:8082 |
DSP_FRAME_ANCESTORS |
Space-separated origins permitted to embed Jupyter in an iframe. | http://localhost:8082 http://127.0.0.1:8082 |
R in JupyterHub Service
The dsp_jupyterhub service launches per-user JupyterLab containers through JupyterHub.
These defaults mirror the values exposed in the in-app JupyterHub Service Reference so you can verify overrides in .env or infrastructure tooling.
| Setting | Default | How to Override |
|---|---|---|
| Notebook Base URL | https://localhost |
Set JUPYTER_EXTERNAL_URL (or configure your reverse proxy) when publishing under a different host or scheme. |
| Published Port | 443 |
Update the ${JUPYTERHUB_PORT:-443}:8000 mapping in docker-compose.yml or export JUPYTERHUB_PORT in your .env. |
| Authentication Token | (managed by OAuth) |
OAuth replaces static tokens; keep JUPYTER_TOKEN empty when using JupyterHub. |
| Workspace Mount | datasources/user_{person_id} |
Mounted from ./uploads/jupyter_workspace; adjust the volume in docker-compose.yml if you relocate storage. |
Environment Override Guidance
| Variable | Purpose | Notes |
|---|---|---|
JUPYTER_EXTERNAL_URL |
Overrides the base URL surfaced in the portal and iframe embeds. | Leave empty to fall back to the detected hostname and JUPYTERHUB_PORT. |
JUPYTERHUB_PORT |
Sets the host port used when constructing external URLs. | Must align with the published port mapping in docker-compose.yml (fallback to JUPYTER_PORT for legacy deployments). |
DSP_APP_ORIGINS |
Extends the CORS allow list for DSP web origins calling notebook APIs. | Include every host that loads the embedded notebook via XHR. |
DSP_FRAME_ANCESTORS |
Controls the Content-Security-Policy frame-ancestors directive for notebook iframes. |
Match the origins defined in DSP_APP_ORIGINS (and any admin hostnames). |
JUPYTERHUB_USERNAME_TEMPLATE |
Pattern used to map DSP accounts to JupyterHub usernames. | Defaults to user_{person_id}. Placeholders: {person_id}, {username}, {email}. Only used when JUPYTERHUB_USER_PATH is set. |
JUPYTERHUB_USER_PATH |
Template for the per-user notebook route served by JupyterHub. | When empty, DSP assumes a single JupyterLab instance and embeds the base URL. Set (for example) to user/{username}/lab in JupyterHub deployments. |
DSP_OAUTH_CLIENT_ID |
Client identifier issued to JupyterHub. | Matches the record created in dsp_oauth_clients. |
DSP_OAUTH_CLIENT_SECRET |
Confidential secret shared with JupyterHub. | Store securely (prefer Docker secrets or vault tooling). |
DSP_OAUTH_AUTHORIZE_URL |
Endpoint JupyterHub uses for the OAuth authorization code flow. | Typically https://portal.example.com/oauth/authorize. |
DSP_OAUTH_TOKEN_URL |
Token exchange endpoint exposed by DSP. | Typically https://portal.example.com/oauth/token. |
DSP_OAUTH_USERINFO_URL |
Endpoint returning user profile details for JupyterHub. | Typically https://portal.example.com/oauth/userinfo. |
JUPYTERHUB_OAUTH_CALLBACK |
Callback URL the hub advertises to DSP. | Should match the hub’s public URL (e.g., https://hub.example.com/hub/oauth_callback). |
- Seeded R scripts live under
r_scripts/and appear in the notebook atwork/r_scriptsfor quick demos. - When tightening security headers, keep
DSP_APP_ORIGINSandDSP_FRAME_ANCESTORSaligned with your published host so the embedded notebook continues to load.
Current Runtime Snapshot
| Setting | Value (detected) | Notes |
|---|---|---|
| Notebook Base URL | = htmlspecialchars($resolvedBaseUrl, ENT_QUOTES, 'UTF-8') ?> |
Derived from JUPYTER_EXTERNAL_URL or the active host/port. |
| Published Port | = htmlspecialchars($resolvedPort, ENT_QUOTES, 'UTF-8') ?> |
Matches JUPYTERHUB_PORT (or legacy JUPYTER_PORT) when set, otherwise the compose default. |
| Authentication Token | = htmlspecialchars($resolvedToken, ENT_QUOTES, 'UTF-8') ?> |
Leave blank when OAuth is enabled via JupyterHub. |
| Workspace Mount | = htmlspecialchars($workspaceBaseMessage, ENT_QUOTES, 'UTF-8') ?> |
Reflects the root folder synced into notebooks for the active account. |
Active Environment Overrides
-
$value): ?>
= htmlspecialchars($variable, ENT_QUOTES, 'UTF-8') ?>:= htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ?>
No overrides detected; defaults from docker-compose.yml are currently active.
Maintenance Commands
# Stop and remove containers, keep database volume
docker-compose down
# Stop containers and remove database volume (fresh start)
docker-compose down -v
# Tail logs from all services
docker-compose logs -f
Troubleshooting
- Database state stuck? Remove the
mysql_datavolume withdocker-compose down -vto trigger a fresh import. - Rscript not found? Rebuild the PHP image (
docker-compose build) or setRSCRIPT_PATHto the correct binary. - Port already in use? Adjust published ports (
8081,8082,8888,3307) indocker-compose.yml. - Permission denied on uploads? Run
chmod -R 775 uploads(or update group ownership) on the host machine.