Development Setup#
This guide walks you through setting up a local NexusLIMS-CDCS development environment with hot-reload, test data, and HTTPS support.
Prerequisites#
Docker Desktop or Docker Engine with Docker Compose
Git for cloning the repository
4GB RAM minimum available for Docker
Quick Start#
1. Clone the Repository#
git clone https://github.com/datasophos/NexusLIMS-CDCS.git
cd NexusLIMS-CDCS/deployment
2. Set Up Environment#
cp .env.dev .env
The development defaults work out of the box - no modifications needed.
3. Load Development Commands#
source dev-commands.sh
This loads convenient aliases for common development tasks (see Development Commands below).
4. Start the Environment#
dev-up
This command:
Extracts test data (preview images and sample records)
Builds the CDCS Docker image
Pulls supporting images (PostgreSQL, Redis, Caddy)
Starts all services
Initializes the database with a superuser and sample schema
5. Trust the Development CA Certificate#
The development environment uses a local Certificate Authority for HTTPS. To avoid browser warnings, trust the CA certificate once:
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain caddy/certs/ca.crt
sudo cp caddy/certs/ca.crt /usr/local/share/ca-certificates/nexuslims-dev-ca.crt
sudo update-ca-certificates
sudo cp caddy/certs/ca.crt /etc/pki/ca-trust/source/anchors/nexuslims-dev-ca.crt
sudo update-ca-trust
Open
certmgr.mscNavigate to “Trusted Root Certification Authorities” > “Certificates”
Right-click > “All Tasks” > “Import”
Select
caddy/certs/ca.crt
Alternative - Browser-specific import:
If you prefer not to trust the certificate system-wide:
Chrome/Edge: Settings > Privacy and security > Security > Manage certificates > Authorities > Import
Firefox: Settings > Privacy & Security > Certificates > View Certificates > Authorities > Import
6. Access the Application#
URL |
Purpose |
|---|---|
https://nexuslims-dev.localhost |
Main application |
https://files.nexuslims-dev.localhost/data/ |
Preview images and metadata |
https://files.nexuslims-dev.localhost/instrument-data/ |
Instrument data files |
Default credentials:
Superuser:
admin/adminRegular user:
user/user
Development Features#
Hot Reload#
Application code is mounted into the container. Changes to Python files automatically reload the application - no rebuild required.
Test Data#
The development environment includes sample microscopy data (~149MB extracted):
Preview images at
https://files.nexuslims-dev.localhost/data/Instrument data at
https://files.nexuslims-dev.localhost/instrument-data/Example XML records in the database
The test data contains only zero-data so it is highly compressible, meaning the preview images will appear to be all black or blank. This is expected.
Test data is automatically extracted by
dev-upand is gitignored.
Local HTTPS#
Caddy uses a local CA for secure HTTPS connections. After trusting the CA certificate (step 5), all browsers will show valid HTTPS.
Direct Database Access#
For debugging, PostgreSQL and Redis are exposed on host ports:
PostgreSQL:
localhost:5532Redis:
localhost:6479
Development Commands#
Load commands with source dev-commands.sh from the deployment/ directory.
Lifecycle#
Command |
Description |
|---|---|
|
Start all services (includes test data setup) |
|
Stop all services |
|
Restart CDCS application |
|
Stop and remove all data (clean slate) |
Viewing Logs#
Command |
Description |
|---|---|
|
View all service logs |
|
CDCS application logs only |
|
Caddy proxy logs |
Shell Access#
Command |
Description |
|---|---|
|
Bash shell in CDCS container |
|
Django Python shell |
|
PostgreSQL shell |
Database#
Command |
Description |
|---|---|
|
Run Django migrations |
|
Create new migrations |
NexusLIMS-Specific#
Command |
Description |
|---|---|
|
Update both XSLT stylesheets in database |
|
Update only detail_stylesheet.xsl |
|
Update only list_stylesheet.xsl |
Dependency Management#
The project uses UV for fast, reliable Python dependency management with lockfiles for reproducibility.
Command |
Description |
|---|---|
|
Regenerate |
|
Upgrade all dependencies (respecting version constraints) |
|
Sync local environment with lockfile (for local dev outside Docker) |
|
Show usage for adding new dependencies |
Note
After adding or updating dependencies, rebuild the Docker image with dev-build-clean to apply changes.
Key Files:
pyproject.toml- Single source of truth for all dependenciesuv.lock- Lockfile ensuring reproducible builds (must be committed).python-version- Required Python version (3.13)
Dependency Groups:
Main: Core application (celery, Django, django-redis)
core: 21 CDCS/MDCS packages pinned to
2.18.*server: Production servers (psycopg2-binary, uwsgi, gunicorn)
For detailed dependency workflows, see the repository’s CLAUDE.md and deployment/README.md.
Architecture#
The development stack uses Docker Compose with three configuration layers:
docker-compose.base.yml # Shared configuration (services, networks, volumes)
docker-compose.dev.yml # Development overrides (ports, mounts, commands)
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e3f2fd', 'primaryTextColor': '#000', 'primaryBorderColor': '#1976d2', 'lineColor': '#1976d2'}}}%%
flowchart TB
Browser([Browser]) -->|HTTPS :443| Caddy
subgraph Docker["Docker Compose"]
Caddy[Caddy<br/>Local CA Certs<br/>File Server]
Django[Django runserver<br/>Hot Reload]
Postgres[(PostgreSQL<br/>:5532)]
Redis[(Redis<br/>:6479)]
Caddy -->|:8000| Django
Django --> Postgres
Django --> Redis
end
subgraph Mounts["Mounted Directories"]
Code[Source Code<br/>./]
XSLT[XSLT Files<br/>xslt/]
TestData[Test Data<br/>test-data/]
end
Django -.- Code
Django -.- XSLT
Caddy -.- TestData
classDef browser fill:#fff3e0,stroke:#f57c00,stroke-width:2px
classDef service fill:#e1f5ff,stroke:#1976d2,stroke-width:2px
classDef mount fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
class Browser browser
class Caddy,Django,Postgres,Redis service
class Code,XSLT,TestData mount
Directory Structure#
deployment/
├── docker-compose.base.yml # Shared configuration
├── docker-compose.dev.yml # Development overrides
├── Dockerfile # Application image
├── docker-entrypoint.sh # Container startup script
│
├── .env # Active environment (copy from .env.dev)
├── .env.dev # Development defaults
│
├── caddy/
│ ├── Dockerfile # Custom Caddy with plugins
│ ├── Caddyfile.dev # Development reverse proxy
│ └── certs/ # CA certificate for HTTPS
│
├── scripts/
│ ├── init_environment.py # Superuser + schema + XSLT setup
│ ├── update-xslt.sh # Update XSLT in database
│ └── setup-test-data.sh # Extract test data
│
├── test-data/ # Test data (extracted, gitignored)
│
└── dev-commands.sh # Development helper aliases
XSLT Stylesheet Development#
Important
XSLT stylesheets are stored in the Django database, not just as files. Editing the .xsl file is not enough - you must update the database.
Update Process#
Edit the XSL file in
xslt/(at repository root)Update the database:
cd deployment
source dev-commands.sh
dev-update-xslt
Refresh your browser to see changes
URL Configuration#
The update script automatically patches URLs in the XSLT based on environment variables:
XSLT_DATASET_BASE_URL- Base URL for instrument data filesXSLT_PREVIEW_BASE_URL- Base URL for preview images
Development defaults:
XSLT_DATASET_BASE_URL=https://files.nexuslims-dev.localhost/instrument-data
XSLT_PREVIEW_BASE_URL=https://files.nexuslims-dev.localhost/data
Troubleshooting#
Certificate Warnings#
Trust the CA certificate (step 5 above). After trusting caddy/certs/ca.crt, all HTTPS connections work without warnings.
Port Conflicts#
Edit port mappings in .env:
POSTGRES_HOST_PORT=5532 # Change if 5532 is in use
REDIS_HOST_PORT=6479 # Change if 6479 is in use
Permission Errors#
Ensure scripts are executable:
chmod +x dev-commands.sh
chmod +x scripts/*.sh scripts/*.py
Test Data Not Loading#
Run extraction manually:
bash scripts/setup-test-data.sh
XSLT Changes Not Appearing#
Update the database and refresh:
dev-update-xslt
Database Connection Errors#
Wait for services to fully start. The Django container waits for PostgreSQL to be ready, but this can take a few seconds on first startup.
Next Steps#
Production Deployment - Deploy to production
Configuration - Detailed environment configuration
Local Test Deployment - Test production config locally with mkcert