___ ___ _ __ ___ _ __ __ _ _ __| |_ _ __ ___ ___ _ __ | |_
/ __|/ _ \| '_ ` _ \| '_ \ / _` | '__| __| '_ ` _ \ / _ \ '_ \| __|
| (__| (_) | | | | | | |_) | (_| | | | |_| | | | | | __/ | | | |_
\___|\___/|_| |_| |_| .__/ \__,_|_| \__|_| |_| |_|\___|_| |_|\__|
|_|
Run multiple local services in parallel without port conflicts. Perfect for multi-project development environments.
Spin up multiple versions of PostgreSQL, Redis, and other services simultaneously — each isolated by name and accessible via DNS.
Run multiple instances of the same service with different versions simultaneously.
Access services via unique DNS names, avoiding port conflicts entirely.
Data persists between container restarts with automatic volume management.
Requires Docker installed and running.
# macOS
brew tap lcmen/extra
brew install compartment
# Linux / Windows (WSL2)
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
URL=https://github.com/lcmen/compartment/releases/latest/download
curl -fsSL $URL/compartment-linux-$ARCH -o ~/.local/bin/compartment
chmod +x ~/.local/bin/compartment
# Verify installation
compartment check
Start the built-in DNS server so services are reachable by name:
compartment start devdns
On WSL2, port 53 is owned by systemd-resolved — use a different host port, then restart the resolver so it picks up the running devdns (complete the WSL2 resolver setup below first):
compartment -e DNS_PORT=5353 start devdns
sudo systemctl restart systemd-resolved
The custom resolver allows you to route all .container requests to your DNS server running inside the devdns container.
Create /etc/resolver/container:
nameserver 127.0.0.1
Not needed for OrbStack — it handles DNS resolution automatically.
Configure systemd-resolved to forward *.container queries to devdns:
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/devdns.conf << 'EOF'
[Resolve]
DNS=127.0.0.1
Domains=~container
EOF
sudo systemctl restart systemd-resolved
WSL overwrites /etc/resolv.conf on startup, bypassing systemd-resolved. Fix this first (run once):
# Stop WSL from overwriting resolv.conf
echo -e "[network]\ngenerateResolvConf = false" | sudo tee -a /etc/wsl.conf
# Append systemd-resolved nameserver to resolv.conf
echo 'nameserver 127.0.0.53' | sudo tee -a /etc/resolv.conf
# Restart WSL from PowerShell to apply wsl.conf changes
wsl.exe --shutdown
All existing DNS continues to work — internet, VPN, and local hostnames resolve through the Windows DNS fallback as before.
Fully reversible: remove the [network] block from /etc/wsl.conf and restart WSL to restore automatic DNS management.
Configure systemd-resolved to forward *.container queries to devdns and Windows DNS as fallback:
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/devdns.conf << 'EOF'
[Resolve]
DNS=127.0.0.1:5353 10.255.255.254
Domains=~container ~.
EOF
sudo systemctl restart systemd-resolved
# Start PostgreSQL 15 for legacy project
compartment -n legacy.db start postgresql 15
# Start PostgreSQL 17 for new project
compartment -n newapp.db start postgresql 17
# Add Redis for caching
compartment -n newapp.cache start redis 8
# Check what's running
compartment status legacy.db
compartment status newapp.db
# Access via DNS (with devdns)
psql -h legacy.db.container -U postgres
psql -h newapp.db.container -U postgres
Image: postgres:<version>
| Variable | Default |
|---|---|
POSTGRES_USER | postgres |
POSTGRES_PASSWORD | postgres |
POSTGRES_DB | postgres |
Image: redis:<version>
No environment variables.