This guide covers running the Baserow development environment using Docker. This is the recommended approach for most developers as it requires minimal local setup and ensures a consistent environment.
# macOS
brew install just
# Linux
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/.local/bin
See supported.md for minimum version requirements.
docker -v
docker compose version
git --version
just --version
# Clone the repository
git clone --branch develop https://github.com/baserow/baserow.git
cd baserow
# Build and start the dev environment
just dc-dev up -d
# View logs (Ctrl+C to stop following)
just dc-dev logs -f
Once started, access:
The Docker dev environment runs these services:
| Service | Description | Port |
|---|---|---|
web-frontend |
Nuxt.js frontend with hot reload | 3000 |
backend |
Django API server with hot reload | 8000 |
celery |
Background task worker | - |
celery-export-worker |
Export-specific worker | - |
celery-beat-worker |
Scheduled task runner | - |
db |
PostgreSQL database | 5432 |
redis |
Redis cache and message broker | 6379 |
caddy |
Reverse proxy for media files | 4000 |
mailhog |
Email testing UI | 8025 |
mjml-email-compiler |
MJML to HTML email compiler | 28101 |
otel-collector |
OpenTelemetry metrics | 4317 |
volume-permissions-fixer |
Fixes media file permissions on startup | - |
web-frontend-storybook |
Component development UI | 6006 |
celery-flower |
Celery task monitoring | 5555 |
docker-compose.yml - Base configuration (production-like)docker-compose.dev.yml - Development overrides (hot reload, volume mounts, dev settings)The just dc-dev command combines both files automatically.
Shortcuts: dcd = dc-dev, a = dc-attach, dct = dc-dev tabs
# Start all services (detached)
just dc-dev up -d # or: just dcd up -d
# Stop all services (preserves data)
just dc-dev stop
# Stop and remove containers (preserves volumes)
just dc-dev down
# Stop and remove everything including volumes (clean slate)
just dc-dev down -v
# All logs
just dc-dev logs
# Follow logs in real-time
just dc-dev logs -f
# Specific services
just dc-dev logs backend
just dc-dev logs web-frontend
just dc-dev logs celery
# Last 100 lines of backend
just dc-dev logs -n 100 backend
# Open a shell in a container
just a # Interactive container picker
just a backend # Direct shell into backend
just a celery # Interactive container picker, filtered
just dc-dev exec backend bash # Alternative
# Run Django management commands
just dc-dev exec backend python manage.py migrate
just dc-dev exec backend python manage.py createsuperuser
just dc-dev exec backend python manage.py shell_plus
# Run tests inside the container
just dc-dev exec backend just test
just dc-dev exec web-frontend yarn test
# Open terminal tabs for each service (like the old dev.sh)
just dc-dev tabs # or: just dct
# Start a tmux session with all services
just dc-dev tmux
# Build all images
just dc-dev build --parallel
# Build specific service
just dc-dev build backend
# Build without cache (when things go wrong)
just dc-dev build --no-cache --parallel
# Clear Docker builder cache completely
# WARNING: This clears ALL Docker builder cache, not just Baserow!
just prune
# Restart a specific service
just dc-dev restart backend
# Rebuild and restart (after Dockerfile changes)
just dc-dev up -d --build backend
# Force recreate containers
just dc-dev up -d --force-recreate
By default, all services including optional ones are started:
| Service | Description | Port |
|---|---|---|
web-frontend-storybook |
Component development UI | 6006 |
celery-flower |
Celery task monitoring | 5555 |
This is controlled by the COMPOSE_PROFILES variable in .env.docker-dev:
# Default: start all services including optional ones
COMPOSE_PROFILES=optional
# To disable optional services (save resources), set to empty:
COMPOSE_PROFILES=
After changing this setting, restart the services:
just dc-dev down
just dc-dev up -d
Both frontend and backend support hot reloading:
.vue, .js, .scss files trigger automatic browser refresh.py files trigger automatic server restartYou don’t need to restart containers when editing code.
You need to rebuild images when:
Dockerfile changespackage.json or yarn.lock changes (frontend)pyproject.toml or uv.lock changes (backend)just dc-dev build --parallel
just dc-dev up -d
just dc-dev exec backend python manage.py migrate
just dc-dev exec backend python manage.py createsuperuser
# PostgreSQL shell
just dc-dev exec db psql -U baserow
# From backend container
just dc-dev exec backend python manage.py dbshell
# Stop services, remove volumes, restart
just dc-dev down -v
just dc-dev up -d
The just dc-dev command uses .env.docker-dev to define the environment variables used by the dev containers.
This file is automatically created from .env.docker-dev.example if it doesn’t exist.
Look at Configuration to customize your .env.docker-dev.
The dev containers run as your host user to avoid permission issues with mounted files:
# These are set automatically by just dc-dev
UID=$(id -u)
GID=$(id -g)
# Check container status
just dc-dev ps
# View logs for failing service
just dc-dev logs backend
# Rebuild from scratch
just dc-dev down -v
just prune
just dc-dev build --no-cache --parallel
just dc-dev up -d
Docker on macOS can be slow with volume mounts. Try:
# Ensure db is running and healthy
just dc-dev ps db
# Wait for database to be ready
just dc-dev exec db pg_isready -U baserow
# Check database logs
just dc-dev logs db