Nix Development Environment for CARE¶
This document describes how to set up and use the Nix-based development environment for the CARE project.
Prerequisites¶
Install Nix: Follow the installation instructions at nixos.org or use the Determinate Systems installer:
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
Note: The Determinate Systems installer is preferred as it provides a cleaner installation process and hassle-free uninstallation from user machines.
Enable Flakes: Nix flakes should be enabled automatically with modern installers. If not, add to
~/.config/nix/nix.conf:experimental-features = nix-command flakes
Optional - Install direnv: For automatic environment activation:
# On macOS with Homebrew brew install direnv # On Linux (varies by distribution) sudo apt install direnv # Ubuntu/Debian sudo dnf install direnv # Fedora
Automated Setup¶
For first-time setup, use the automated setup script:
./scripts/nix-dev-setup.sh
This script will:
Check if Nix is installed and flakes are enabled
Set up the Python virtual environment and install dependencies
Start required services (PostgreSQL, Redis, MinIO)
Run database migrations
Optionally load sample fixtures
Provide helpful guidance for next steps
The script includes safety checks and won’t run on NixOS systems (which should use NixOS-specific configurations).
Quick Setup (Manual)¶
For first-time setup without the script:
nix develop
setup-dev
start-services
rundev
This will:
Enter the development environment
Set up Python virtual environment and install dependencies
Start required services (PostgreSQL, Redis, MinIO)
Run database migrations and start the unified development server
Manual Setup¶
If you prefer manual setup or need to troubleshoot:
1. Enter Development Shell¶
nix develop
This will:
Install all required system packages from Nix store
Set up environment variables
Make development commands available
Show a helpful welcome message
2. Install Python Dependencies¶
setup-dev
3. Start Services¶
start-services
This starts:
PostgreSQL on port 5432
Redis on port 6379
MinIO on port 9100 (console on 9001)
4. Set Up Database¶
migrate
load-fixtures # Optional: load sample data
5. Start Complete Development Environment¶
Option A: Unified Start (Recommended)¶
rundev
This single command starts both the Django server and Celery worker together with proper migrations and setup.
Option B: Separate Services¶
# Terminal 1: Django server
runserver
# Terminal 2: Celery worker
celery
The Django server will be available at http://localhost:9000
Available Commands¶
Once in the development shell (nix develop), you have access to these commands:
Service Management¶
start-services- Start PostgreSQL, Redis, and MinIOstop-services- Stop background services onlykill-care- 🛑 Stop ALL development processes and servicesclean-data- 🗑️ Remove all local service data (requires confirmation)healthcheck- Check application health
Development Server¶
rundev- 🚀 Start both API server and Celery worker (RECOMMENDED)runserver- Start Django development server onlycelery- Start Celery worker with beat scheduler only
Database Operations¶
migrate- Run database migrationsmakemigrations [app]- Create new migrationsload-fixtures- Load sample datadump-db- Backup database tocare_db.dumpload-db- Restore database fromcare_db.dumpreset-db- Drop and recreate database
Django Management¶
manage <command>- Run any Django management commandmanage shell- Django shellmanage collectstatic- Collect static files
Testing¶
test [path]- Run tests (with database reuse)test-no-keep [path]- Run tests (fresh database)test-coverage- Run tests with coverage report
Code Quality¶
ruff- Check and fix staged filesruff-all- Check all Python filesruff-fix-all- Fix all Python files
Initial Setup¶
setup-dev- Install dependencies and set up environment
Environment Variables¶
The development environment sets these variables automatically:
Database¶
POSTGRES_USER=postgresPOSTGRES_PASSWORD=postgresPOSTGRES_HOST=localhostPOSTGRES_DB=carePOSTGRES_PORT=5432DATABASE_URL=postgres://postgres:postgres@localhost:5432/care
Redis¶
REDIS_URL=redis://localhost:6379CELERY_BROKER_URL=redis://localhost:6379/0
Django¶
DJANGO_DEBUG=trueATTACH_DEBUGGER=falseDJANGO_SETTINGS_MODULE=config.settings.local
MinIO/S3¶
BUCKET_REGION=ap-south-1BUCKET_KEY=minioadminBUCKET_SECRET=minioadminBUCKET_ENDPOINT=http://localhost:9100BUCKET_EXTERNAL_ENDPOINT=http://localhost:9100FILE_UPLOAD_BUCKET=patient-bucketFACILITY_S3_BUCKET=facility-bucket
HCX Configuration (for local testing)¶
HCX_AUTH_BASE_PATH=https://staging-hcx.swasth.app/auth/realms/swasth-health-claim-exchange/protocol/openid-connect/tokenHCX_ENCRYPTION_PRIVATE_KEY_URL=https://raw.githubusercontent.com/Swasth-Digital-Health-Foundation/hcx-platform/main/demo-app/server/resources/keys/x509-private-key.pemHCX_IG_URL=https://ig.hcxprotocol.io/v0.7.1HCX_PARTICIPANT_CODE=qwertyreboot.gmail@swasth-hcx-stagingHCX_PASSWORD=Opensaber@123HCX_PROTOCOL_BASE_PATH=http://staging-hcx.swasth.app/api/v0.7HCX_USERNAME=qwertyreboot@gmail.comHCX_CERT_URL=https://raw.githubusercontent.com/Swasth-Digital-Health-Foundation/hcx-platform/main/demo-app/server/resources/keys/x509-self-signed-certificate.pem
Service URLs¶
Django Application: http://localhost:9000
MinIO Console: http://localhost:9001 (admin: minioadmin/minioadmin)
PostgreSQL: localhost:5432 (postgres/postgres)
Redis: localhost:6379
Development Workflow¶
Daily Development¶
Quick Start (Recommended)¶
Start your session:
nix develop start-services # If not already running
Start the complete application:
rundev # Starts both Django server and Celery worker together
Manual Start (Advanced)¶
Start your session:
nix develop start-services # If not already running
Start services separately:
# Terminal 1: Django server runserver # Terminal 2: Celery worker celery
Make changes and test:
ruff-all # Check code style test # Run tests manage shell # Interactive Django shell
Stop when done:
kill-care # Stop all development processes
Working with Database¶
# Create and apply migrations
makemigrations
migrate
# Reset database if needed
stop-services
reset-db
start-services
migrate
load-fixtures
Debugging¶
Enable Django Debug Mode¶
Set ATTACH_DEBUGGER=true and use runserver to start with debugpy on port 9876.
Check Services¶
# Check if services are running
ps aux | grep -E 'postgres|redis|minio'
# View service logs (if using systemd)
journalctl --user -f
Database Connection Issues¶
# Check PostgreSQL status
pg_ctl status -D .nix-data/postgres
# Restart PostgreSQL
stop-services
start-services
Troubleshooting¶
Common Issues¶
“Permission denied” errors:
# Ensure directories are writable mkdir -p .nix-data/postgres .nix-data/redis .nix-data/minio
Services won’t start:
# Stop any conflicting processes stop-services # Check for processes using ports lsof -i :5432 # PostgreSQL lsof -i :6379 # Redis lsof -i :9100 # MinIO
Python dependencies issues:
# Stop everything first kill-care # Reinstall in clean environment rm -rf .venv setup-dev
Database connection refused:
# Wait for PostgreSQL to fully start sleep 5 # Or check if initialization is complete pg_ctl status -D .nix-data/postgres
Clean Reset¶
If you encounter persistent issues:
# Stop all processes and services
kill-care
# Clean up data directories (will prompt for confirmation)
clean-data
# Exit and re-enter development shell
exit
nix develop
# Restart setup
setup-dev
start-services
migrate
Data Storage¶
The Nix development environment stores all service data in the project-local .nix-data directory:
PostgreSQL data:
.nix-data/postgres/Redis data:
.nix-data/redis/MinIO data:
.nix-data/minio/
This directory is automatically added to .gitignore and provides isolation from system-wide services.
Differences from Docker Setup¶
Advantages of Nix¶
Faster startup: No container overhead
Native performance: Direct system execution
Reproducible: Same environment across different machines
Integrated tooling: All tools available in single shell
Easier debugging: Direct access to processes and files
Version pinning: All tools use specific versions from Nix store
Key Differences¶
Services run directly on host (not in containers)
Data stored in
.nix-data/instead of Docker volumesEnvironment variables set in shell instead of env files
All commands available directly (no
docker compose exec)Uses Python 3.13 and PostgreSQL 15 from Nix store
Integration with Existing Workflow¶
The Nix setup coexists with Docker setup:
Makefile commands still work when using Docker
Same Python dependencies and versions
Same database schema and migrations
Compatible with existing CI/CD pipelines
Available Tools¶
The development environment includes these tools from the Nix store:
Python 3.13: Base Python interpreter
PostgreSQL 15: Database server and client tools
Redis: In-memory data structure store
MinIO: S3-compatible object storage
Typst: Modern typesetting system
Pre-commit: Git hook framework
GCC & build tools: For compiling Python packages
Contributing¶
When adding new dependencies:
Python packages: Add to
Pipfileand runsetup-devSystem packages: Add to
flake.nixbuildInputsServices: Update service management scripts in
flake.nixEnvironment variables: Add to envVars in
flake.nix
Performance Tips¶
Use direnv: Automatically enter/exit development shell:
echo "use flake" > .envrc direnv allow
Keep services running: Services persist between shell sessions
Use test database reuse: Default
testcommand reuses database for speedParallel testing: Tests run in parallel by default
Clean shutdown: Use
kill-carecommand to properly stop all processes
Security Notes¶
Services bind to localhost only (not accessible externally)
Default credentials are for development only
MinIO uses development keys (minioadmin/minioadmin)
Database has no password (local development only)