convert-to-docker
Use Cautionnpx machina-cli add skill crypdick/pynchy/convert-to-docker --openclawConvert to Docker
This skill migrates NanoClaw from Apple Container (macOS-only) to Docker for cross-platform support (macOS and Linux).
What this changes:
- Container runtime: Apple Container → Docker
- Mount syntax:
--mount type=bind,...,readonly→-v path:path:ro - Startup check:
container system status→docker info - Build commands:
container build/run→docker build/run
What stays the same:
- Dockerfile (already Docker-compatible)
- Agent runner code
- Mount security/allowlist validation
- All other functionality
Prerequisites
Verify Docker is installed before starting:
docker --version && docker info >/dev/null 2>&1 && echo "Docker ready" || echo "Install Docker first"
If Docker is not installed:
- macOS: Download from https://docker.com/products/docker-desktop
- Linux:
curl -fsSL https://get.docker.com | sh && sudo systemctl start docker
1. Update Container Runner
Edit src/container-runner.ts:
1a. Update module comment (around line 3)
// Before:
* Spawns agent execution in Apple Container and handles IPC
// After:
* Spawns agent execution in Docker container and handles IPC
1b. Update directory mount comment (around line 88)
// Before:
// Apple Container only supports directory mounts, not file mounts
// After:
// Docker bind mounts work with both files and directories
1c. Update env workaround comment (around line 120)
// Before:
// Environment file directory (workaround for Apple Container -i env var bug)
// After:
// Environment file directory (keeps credentials out of process listings)
1d. Update buildContainerArgs function
Replace the entire function with Docker mount syntax:
function buildContainerArgs(mounts: VolumeMount[]): string[] {
const args: string[] = ['run', '-i', '--rm'];
// Docker: -v with :ro suffix for readonly
for (const mount of mounts) {
if (mount.readonly) {
args.push('-v', `${mount.hostPath}:${mount.containerPath}:ro`);
} else {
args.push('-v', `${mount.hostPath}:${mount.containerPath}`);
}
}
args.push(CONTAINER_IMAGE);
return args;
}
1e. Update spawn command (around line 204)
// Before:
const container = spawn('container', containerArgs, {
// After:
const container = spawn('docker', containerArgs, {
2. Update Startup Check
Edit src/index.ts:
2a. Replace the container system check function
Find ensureContainerSystemRunning() and replace entirely with:
function ensureDockerRunning(): void {
try {
execSync('docker info', { stdio: 'pipe', timeout: 10000 });
logger.debug('Docker daemon is running');
} catch {
logger.error('Docker daemon is not running');
console.error('\n╔════════════════════════════════════════════════════════════════╗');
console.error('║ FATAL: Docker is not running ║');
console.error('║ ║');
console.error('║ Agents cannot run without Docker. To fix: ║');
console.error('║ macOS: Start Docker Desktop ║');
console.error('║ Linux: sudo systemctl start docker ║');
console.error('║ ║');
console.error('║ Install from: https://docker.com/products/docker-desktop ║');
console.error('╚════════════════════════════════════════════════════════════════╝\n');
throw new Error('Docker is required but not running');
}
}
2b. Update the function call in main()
// Before:
ensureContainerSystemRunning();
// After:
ensureDockerRunning();
3. Update Build Script
Edit container/build.sh:
3a. Update build command (around line 15-16)
# Before:
# Build with Apple Container
container build -t "${IMAGE_NAME}:${TAG}" .
# After:
# Build with Docker
docker build -t "${IMAGE_NAME}:${TAG}" .
3b. Update test command (around line 23)
# Before:
echo " echo '{...}' | container run -i ${IMAGE_NAME}:${TAG}"
# After:
echo " echo '{...}' | docker run -i ${IMAGE_NAME}:${TAG}"
4. Update Documentation
Update references in documentation files:
| File | Find | Replace |
|---|---|---|
CLAUDE.md | "Apple Container (Linux VMs)" | "Docker containers" |
README.md | "Apple containers" | "Docker containers" |
README.md | "Apple Container" | "Docker" |
README.md | Requirements section | Update to show Docker instead |
docs/REQUIREMENTS.md | "Apple Container" | "Docker" |
docs/SPEC.md | "APPLE CONTAINER" | "DOCKER CONTAINER" |
docs/SPEC.md | All Apple Container references | Docker equivalents |
Key README.md updates:
Requirements section:
## Requirements
- macOS or Linux
- Node.js 20+
- [Claude Code](https://claude.ai/download)
- [Docker](https://docker.com/products/docker-desktop)
FAQ - "Why Docker?":
**Why Docker?**
Docker provides cross-platform support (macOS and Linux), a large ecosystem, and mature tooling. Docker Desktop on macOS uses a lightweight Linux VM similar to other container solutions.
FAQ - "Can I run this on Linux?":
**Can I run this on Linux?**
Yes. NanoClaw uses Docker, which works on both macOS and Linux. Just install Docker and run `/setup`.
5. Update Skills
5a. Update .claude/skills/setup/SKILL.md
Replace Section 2 "Install Apple Container" with Docker installation:
## 2. Install Docker
Check if Docker is installed and running:
\`\`\`bash
docker --version && docker info >/dev/null 2>&1 && echo "Docker is running" || echo "Docker not running or not installed"
\`\`\`
If not installed or not running, tell the user:
> Docker is required for running agents in isolated environments.
>
> **macOS:**
> 1. Download Docker Desktop from https://docker.com/products/docker-desktop
> 2. Install and start Docker Desktop
> 3. Wait for the whale icon in the menu bar to stop animating
>
> **Linux:**
> \`\`\`bash
> curl -fsSL https://get.docker.com | sh
> sudo systemctl start docker
> sudo usermod -aG docker $USER # Then log out and back in
> \`\`\`
>
> Let me know when you've completed these steps.
Wait for user confirmation, then verify:
\`\`\`bash
docker run --rm hello-world
\`\`\`
Update build verification:
Verify the build succeeded:
\`\`\`bash
docker images | grep nanoclaw-agent
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "Container OK" || echo "Container build failed"
\`\`\`
Update troubleshooting section to reference Docker commands.
5b. Update .claude/skills/debug/SKILL.md
Replace all container commands with docker equivalents:
| Before | After |
|---|---|
container run | docker run |
container system status | docker info |
container builder prune | docker builder prune |
container images | docker images |
--mount type=bind,source=...,readonly | -v ...:ro |
Update the architecture diagram header:
Host (macOS/Linux) Container (Docker)
6. Build and Verify
After making all changes:
# Compile TypeScript
npm run build
# Build Docker image
./container/build.sh
# Verify image exists
docker images | grep nanoclaw-agent
7. Test the Migration
7a. Test basic container execution
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "Container OK"
7b. Test readonly mounts
mkdir -p /tmp/test-ro && echo "test" > /tmp/test-ro/file.txt
docker run --rm --entrypoint /bin/bash -v /tmp/test-ro:/test:ro nanoclaw-agent:latest \
-c "cat /test/file.txt && touch /test/new.txt 2>&1 || echo 'Write blocked (expected)'"
rm -rf /tmp/test-ro
Expected: Read succeeds, write fails with "Read-only file system".
7c. Test read-write mounts
mkdir -p /tmp/test-rw
docker run --rm --entrypoint /bin/bash -v /tmp/test-rw:/test nanoclaw-agent:latest \
-c "echo 'test write' > /test/new.txt && cat /test/new.txt"
cat /tmp/test-rw/new.txt && rm -rf /tmp/test-rw
Expected: Both operations succeed.
7d. Full integration test
npm run dev
# Send @AssistantName hello via WhatsApp
# Verify response received
Troubleshooting
Docker not running:
- macOS: Start Docker Desktop from Applications
- Linux:
sudo systemctl start docker - Verify:
docker info
Permission denied on Docker socket (Linux):
sudo usermod -aG docker $USER
# Log out and back in
Image build fails:
# Clean rebuild
docker builder prune -af
./container/build.sh
Container can't write to mounted directories: Check directory permissions on the host. The container runs as uid 1000.
Summary of Changed Files
| File | Type of Change |
|---|---|
src/container-runner.ts | Mount syntax, spawn command, comments |
src/index.ts | Startup check function |
container/build.sh | Build and run commands |
CLAUDE.md | Quick context |
README.md | Requirements, FAQ |
docs/REQUIREMENTS.md | Architecture references |
docs/SPEC.md | Architecture diagram, tech stack |
.claude/skills/setup/SKILL.md | Installation instructions |
.claude/skills/debug/SKILL.md | Debug commands |
Source
git clone https://github.com/crypdick/pynchy/blob/main/docs/_archive/old-nanoclaw-skills/convert-to-docker/SKILL.mdView on GitHub Overview
Converts NanoClaw from Apple Container to Docker to enable cross-platform deployment and Linux support. It updates the container runtime, mount syntax, startup checks, and build/run commands while preserving Dockerfile compatibility and core functionality.
How This Skill Works
The migration replaces Apple Container usage with Docker across code paths, updating mounts from Apple-style binds to Docker -v binds with an optional :ro suffix, and switching startup and build/run logic to Docker. It also changes the startup check to verify Docker is running via docker info and updates the spawn command to invoke Docker instead of the Apple Container runtime.
When to Use It
- You need Linux support or cross-platform deployment for NanoClaw.
- You want to replace Apple Container with Docker in your development or CI/CD workflows.
- You're migrating from Apple Container to Docker to simplify tooling and environment parity.
- Your deployment environment standardizes on Docker for container runtimes.
- You want to preserve existing Dockerfile while enabling Docker-based execution for NanoClaw.
Quick Start
- Step 1: Ensure Docker is installed and Docker daemon is running on your host.
- Step 2: Update your codebase according to the migration notes (switch container-runner, mounts, and startup checks to Docker).
- Step 3: Run and validate NanoClaw inside Docker, confirming mounts, commands, and agent behavior are correct.
Best Practices
- Verify Docker is installed and accessible with docker --version and docker info before running migration steps.
- Review changes in src/container-runner.ts and src/index.ts to ensure mount and spawn logic reflect Docker usage.
- Test both file and directory mounts, using -v with :ro for readonly mounts as described in the migration notes.
- Keep Dockerfile and core agent runner logic intact to minimize behavioral drift.
- Document Docker prerequisites, startup checks, and migration steps for your team to follow.
Example Use Cases
- Deploy NanoClaw agents on Linux servers by migrating from Apple Container to Docker for cross-platform compatibility.
- In a multi-OS CI pipeline, replace Apple Container runs with Docker to standardize builds across macOS and Linux runners.
- Migrate an existing macOS-only workflow to Docker for easier cross-platform distribution.
- Set up a local Docker-based development environment for NanoClaw to mirror production behavior.
- Use docker build/run in your deployment scripts to replace container build/run commands.