Skip to main content

Development with Dev Containers

Dev Containers provide a consistent, reproducible development environment using Docker containers. With a single click, you can get started with a Gallery development environment on Mac, Linux, Windows, or in the cloud using GitHub Codespaces.

Get started fast!

Open in GitHub Codespaces

Learn more about Dev Containers

Prerequisites​

Before getting started, ensure you have:

  • Docker Desktop (latest version)
  • Visual Studio Code with the Dev Containers extension
  • Git for cloning the repository
  • At least 8GB of RAM (16GB recommended)
  • 20GB of free disk space
Alternative Development Environments

While this guide focuses on VS Code, you have many options for Dev Container development:

Local Editors:

Cloud-Based Solutions:

  • GitHub Codespaces - Fully integrated with GitHub, excellent devcontainer.json support
  • GitPod - SaaS platform with recent Dev Container support (historically used gitpod.yml)

Self-Hostable Options:

  • Coder - Enterprise-focused, requires Terraform knowledge, self-managed
  • DevPod - Client-only tool with excellent devcontainer.json support, works with any provider (local, cloud, or on-premise). Check quick-start guide

Dev Container Services​

The Dev Container environment consists of the following services:

ServiceContainer NameDescriptionPorts
Server & Webimmich-serverRuns both API server and web frontend in development mode2283 (API)
3000 (Web)
9230 (Workers Debug)
9231 (API Debug)
DatabasedatabasePostgreSQL database5432
CacheredisValkey cache server6379
Machine Learningimmich-machine-learningGallery ML model inference server3003

Getting Started​

Step 1: Clone the Repository​

git clone https://github.com/immich-app/immich.git
cd immich

Step 2: Configure Environment Variables​

The gallery dev containers read environment variables from your shell environment, not from .env files. This allows them to work in cloud environments without pre-configuration.

Configuration

When running locally, and if you want to create (or use an existing) DB and/or photo storage folder, you must set the UPLOAD_LOCATION variable in your shell environment before launching the Dev Container. This determines where uploaded files are stored and also where the DB stores it data.

# Set temporarily for current session
export UPLOAD_LOCATION=/opt/dev_upload_folder

# Or add to your shell profile for persistence
# (~/.bashrc, ~/.zshrc, ~/.bash_profile, etc.)
echo 'export UPLOAD_LOCATION=/opt/dev_upload_folder' >> ~/.bashrc
source ~/.bashrc

Step 3: Launch the Dev Container​

tip

Gallery development makes extensive use of specialized base images for its docker-compose based development. For this reason, you won't be able to use VSCode's Clone Repository in a Container Volume command.

Using VS Code UI:​

  1. Open the cloned repository in VS Code
  2. Press F1 or Ctrl/Cmd+Shift+P to open the command palette
  3. Type and select "Dev Containers: Rebuild and Reopen in Container"
  4. Select "Gallery - Backend, Frontend and ML" from the list
  5. Wait for the container to build and start (this may take several minutes on first run)

Using VS Code Quick Actions:​

  1. Open the repository in VS Code
  2. You should see a popup asking if you want to reopen in a container
  3. Click "Reopen in Container"

Using Command Line:​

# Using the DevContainer CLI
devcontainer up --workspace-folder .

Environment Variable Details​

How Dev Containers Handle Environment Variables​

Unlike the Gallery developer setup based on Docker Compose which uses .env files, Gallery Dev Containers read environment variables from your shell environment. This is configured in .devcontainer/devcontainer.json:

"remoteEnv": {
"UPLOAD_LOCATION": "${localEnv:UPLOAD_LOCATION:./Library}",
"DB_PASSWORD": "${localEnv:DB_PASSWORD:postgres}",
"DB_USERNAME": "${localEnv:DB_USERNAME:postgres}",
"DB_DATABASE_NAME": "${localEnv:DB_DATABASE_NAME:immich}"
}

The ${localEnv:VARIABLE:default} syntax reads from your shell environment with optional defaults.

Upload Location Path Resolution​

The UPLOAD_LOCATION environment variable controls where files are stored:

Default: ./Library (relative to the docker directory) Resolved to: <immich-root>/docker/Library

Bind Mounts Created:

# From .devcontainer/server/container-compose-overrides.yml
- ${UPLOAD_LOCATION-./Library}/photos:/workspaces/immich/server/upload
- ${UPLOAD_LOCATION-./Library}/postgres:/var/lib/postgresql/data

Database Configuration​

These variables have sensible defaults (for development) but can be customized:

VariableDefaultDescription
DB_PASSWORDpostgresPostgreSQL password
DB_USERNAMEpostgresPostgreSQL username
DB_DATABASE_NAMEimmichDatabase name

Setting Environment Variables​

Add these to your shell profile (~/.bashrc, ~/.zshrc, ~/.bash_profile, etc.):

# Required
export UPLOAD_LOCATION=./Library # or absolute path

# Optional (only if using non-default values)
export DB_PASSWORD=your_password
export DB_USERNAME=your_username
export DB_DATABASE_NAME=your_database

Remember to reload your shell configuration:

source ~/.bashrc # or ~/.zshrc, etc.

Git Configuration​

SSH Keys and Authentication​

To use your SSH keys for GitHub access inside the Dev Container:

  1. Start SSH Agent on your host machine:

    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_rsa # or your key path
  2. VS Code automatically forwards your SSH agent to the container

For detailed instructions, see the VS Code guide on sharing Git credentials.

Commit Signing​

To use your SSH key for commit signing, see the GitHub guide on SSH commit signing.

Development Workflow​

Automatic Setup​

When the Dev Container starts, it automatically:

  1. Runs post-create script (container-server-post-create.sh):

    • Adjusts file permissions for the node user
    • Installs dependencies: pnpm install in all packages
    • Builds TypeScript SDK: pnpm --filter @immich/sdk build
  2. Starts development servers via VS Code tasks:

    • Gallery API Server (Nest) - API server with hot-reloading on port 2283
    • Gallery Web Server (Vite) - Web frontend with hot-reloading on port 3000
    • Both servers watch for file changes and recompile automatically
  3. Configures port forwarding:

info

The Dev Container setup replaces the mise dev command from the traditional setup. All services start automatically when you open the container.

Accessing Services​

Once running, you can access:

ServiceURLDescription
Web UIhttp://localhost:3000Main web interface
APIhttp://localhost:2283REST API endpoints (Not used directly, web UI will expose this over http://localhost:3000/api)
Databaselocalhost:5432PostgreSQL (username: postgres) (Not used directly)

Connecting Mobile Apps​

To connect the mobile app to your Dev Container:

  1. Find your machine's IP address
  2. In the mobile app, use: http://YOUR_IP:3000/api
  3. Ensure your firewall allows connections on port 2283

Making Code Changes​

  • Server code (/server): Changes trigger automatic restart
  • Web code (/web): Changes trigger hot module replacement
  • Database migrations: Run mise //:sql
  • API changes: Regenerate TypeScript SDK with mise //:open-api

Testing​

Running Tests​

The Dev Container supports multiple ways to run tests:

# Server
mise //server:test # unit tests
mise //server:test-medium # medium / integration tests

# Web
mise //web:test # unit tests

# E2E
mise //e2e:test # API tests
mise //e2e:test-web # web UI tests (Playwright)

# Run all checks for a component
mise //server:checklist
mise //web:checklist

Additional Commands​

# API generation
mise //:open-api # Generate OpenAPI specs
mise //:open-api-typescript # Generate TypeScript SDK
mise //:open-api-dart # Generate Dart SDK

# Database
mise //server:sql # Sync database schema

Debugging​

The Dev Container is pre-configured for debugging:

  1. API Server Debugging:

    • Set breakpoints in VS Code
    • Press F5 or use "Run and Debug" panel
    • Select "Attach to Server" configuration
    • Debug port: 9231
  2. Worker Debugging:

    • Use "Attach to Workers" configuration
    • Debug port: 9230
  3. Web Debugging:

    • Use browser DevTools
    • VS Code debugger for Chrome/Edge extensions supported

Troubleshooting​

Common Issues​

Permission Errors​

Problem: EACCES or permission denied errors
Solution:

  • The Dev Container runs as the node user (UID 1000)
  • If your host UID differs, you may see permission issues
  • Try rebuilding the container: "Dev Containers: Rebuild Container"

Container Won't Start​

Problem: Dev Container fails to start or build
Solution:

  1. Check Docker is running: docker ps
  2. Clean Docker resources: docker system prune -a
  3. Check available disk space
  4. Review Docker Desktop resource limits

Port Already in Use​

Problem: "Port 3000/2283 is already in use"
Solution:

  1. Check for conflicting services: lsof -i :3000 (macOS/Linux)
  2. Stop conflicting services or change port mappings
  3. Restart Docker Desktop

Upload Location Not Set​

Problem: Errors about missing UPLOAD_LOCATION
Solution:

  1. Set the environment variable: export UPLOAD_LOCATION=./Library
  2. Add to your shell profile for persistence
  3. Restart your terminal and VS Code

Database Connection Failed​

Problem: Cannot connect to PostgreSQL
Solution:

  1. Ensure all containers are running: docker ps
  2. Check logs: "Dev Containers: Show Container Log"
  3. Verify database credentials match environment variables

Getting Help​

If you encounter issues:

  1. Check container logs: View → Output → Select "Dev Containers"
  2. Rebuild without cache: "Dev Containers: Rebuild Container Without Cache"
  3. Review common Docker issues
  4. Ask in Discord #contributing channel

Quick-start guide for DevPod with docker​

You will need DevPod CLI (check DevPod CLI installation guide) and Docker Desktop.

# Step 1: Clone the Repository
git clone https://github.com/immich-app/immich.git
cd immich

# Step 2: Prepare DevPod (if you haven't already)
devpod provider add docker
devpod provider use docker

# Step 3: Build 'immich-server-dev' docker image first manually
docker build -f server/Dockerfile.dev -t immich-server-dev .

# Step 4: Now you can start devcontainer
devpod up .

Mobile Development​

While the Dev Container focuses on server and web development, you can connect mobile apps for testing:

Connecting iOS/Android Apps​

  1. Ensure API is accessible:

    # Find your machine's IP
    # macOS
    ipconfig getifaddr en0
    # Linux
    hostname -I
    # Windows (in WSL2)
    ip addr show eth0
  2. Configure mobile app:

    • Server URL: http://YOUR_IP:2283/api
    • Ensure firewall allows port 2283
  3. For full mobile development, see the mobile development guide which covers:

    • Flutter setup
    • Running on simulators/devices
    • Mobile-specific debugging

Advanced Configuration​

Custom VS Code Extensions​

Add extensions to .devcontainer/devcontainer.json:

"customizations": {
"vscode": {
"extensions": [
"your.extension-id"
]
}
}

Additional Services​

To add services (e.g., Redis Commander), modify:

  1. /docker/docker-compose.dev.yml - Add service definition
  2. /.devcontainer/server/container-compose-overrides.yml - Add overrides if needed

Resource Limits​

Adjust Docker Desktop resources:

  • macOS/Windows: Docker Desktop → Settings → Resources
  • Linux: Modify Docker daemon configuration

Recommended minimums:

  • CPU: 4 cores
  • Memory: 8GB
  • Disk: 20GB

Next Steps​