Compose Environments
Compose environments use podman-compose for multi-container orchestration.
Unlike the single-container container type, compose environments support sidecar containers for network filtering and future MCP server integration.
Compose environments are project-local.
All generated orchestration files live in a .cc-deck/ subdirectory within the project directory.
The project directory is bind-mounted at /workspace by default, providing immediate bidirectional file synchronization.
Walkthrough: Your First Compose Environment
This walkthrough takes you from an empty project directory to a running, network-filtered Claude Code session in about two minutes.
Step 2: Create the environment
cc-deck env create dev --type compose --gitignore
You will see output similar to:
WARNING: no image specified, using default quay.io/cc-deck/cc-deck-demo:latest Environment "dev" created (type: compose)
The --gitignore flag automatically adds .cc-deck/ to your .gitignore so the generated files stay out of version control.
Take a look at what was generated:
ls -la .cc-deck/
# compose.yaml .env
The compose.yaml defines the session container with your project directory mounted at /workspace.
The .env file contains any auto-detected credentials from your host.
Step 3: Attach to the session
cc-deck env attach dev
This opens a Zellij session inside the container with the cc-deck sidebar plugin loaded. Your project files are immediately available:
# Inside the container:
ls /workspace
# go.mod main.go internal/ README.md
Edit a file on either side (host or container) and the change appears instantly on the other side.
Step 4: Add network filtering
If you want to restrict which domains the session container can access, delete and recreate with filtering:
# Detach from Zellij first (Ctrl+o d)
cc-deck env delete dev --force
cc-deck env create dev --type compose \
--allowed-domains anthropic,github \
--gitignore
Now the environment includes a tinyproxy sidecar. Attach and verify filtering works:
cc-deck env attach dev
# Inside the container:
curl -s https://api.anthropic.com -o /dev/null -w "%{http_code}"
# 200 (or 401 without valid key, but the connection succeeds)
curl -s https://example.com -o /dev/null -w "%{http_code}"
# Connection refused (blocked by proxy)
Step 5: Manage the lifecycle
# Detach from Zellij (Ctrl+o d)
# Check status
cc-deck env status dev
# Stop to free resources
cc-deck env stop dev
# Start again later
cc-deck env start dev
# Re-attach
cc-deck env attach dev
# Your files and Zellij session state are preserved.
Step 6: Clean up
cc-deck env delete dev
# Environment "dev" deleted
This removes all containers, the .cc-deck/ directory, and the state records.
Your project files are untouched.
What you built
~/projects/my-api/ <-- your project (untouched)
.cc-deck/ <-- generated, gitignored
compose.yaml <-- container orchestration
.env <-- credentials
proxy/ <-- only with --allowed-domains
tinyproxy.conf
whitelist
The session container runs your project at /workspace with full Claude Code tooling.
The optional proxy sidecar enforces a domain allowlist for network security.
Creating a Compose Environment
cd ~/projects/my-api
cc-deck env create mydev --type compose
This command performs several steps automatically:
-
Detects the compose runtime (
podman-composeordocker compose). -
Generates orchestration files in
.cc-deck/(compose.yaml, .env, optional proxy config). -
Detects host credentials and writes them to
.cc-deck/.env. -
Starts the compose project with
podman-compose up -d. -
Records the environment in both the definition and state stores.
Network Filtering
The --allowed-domains flag adds a tinyproxy sidecar container that filters outbound network traffic.
The session container can only reach domains in the allowlist.
cc-deck env create filtered --type compose --allowed-domains anthropic,github,npm
Domain groups are expanded using the built-in domain resolver.
You can specify built-in groups (e.g., anthropic, github), user-defined groups, or literal domain patterns.
When filtering is active:
-
The session container has no direct internet access.
-
All outbound traffic routes through the proxy sidecar.
-
Requests to allowed domains succeed normally.
-
Requests to unlisted domains are blocked.
Credential Passthrough
Compose environments auto-detect host credentials and inject them into the session container. The detection logic matches the container environment type.
Supported credential sources:
-
ANTHROPIC_API_KEYfor direct API access -
Google Vertex AI credentials (environment variables and ADC file)
-
Amazon Bedrock credentials (access keys, session token, profile)
-
Explicit credentials via
--credential KEY=VALUE
Environment variable credentials are written to .cc-deck/.env.
File-based credentials (like the Google ADC file) are copied to .cc-deck/secrets/ and mounted at /run/secrets/ inside the container.
Lifecycle Management
All standard environment lifecycle commands work with compose environments.
# Stop the environment (frees resources, preserves state)
cc-deck env stop mydev
# Start a stopped environment
cc-deck env start mydev
# Delete the environment and all artifacts
cc-deck env delete mydev
# Force-delete a running environment
cc-deck env delete mydev --force
Stopping and starting preserves all files in the project directory (bind mount mode) and in the named volume (if used).
Deleting an environment removes all containers, cleans up secrets, and removes the .cc-deck/ directory from the project.
Project Hygiene
When creating a compose environment in a git-tracked project, the system warns if .cc-deck/ is not in .gitignore.
Use the --gitignore flag to add it automatically.
cc-deck env create mydev --type compose --gitignore
The .cc-deck/ directory contains only generated artifacts.
It should not be committed to version control.
Command Reference
# Create with all options
cc-deck env create mydev --type compose \
--image quay.io/cc-deck/cc-deck-demo:latest \
--allowed-domains anthropic,github \
--port 8080:8080 \
--path /path/to/project \
--credential KEY=VALUE \
--auth auto \
--gitignore
# Attach to the environment
cc-deck env attach mydev
# Run a command inside the session container
cc-deck env exec mydev -- ls /workspace
# Check status
cc-deck env status mydev