Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,5 @@ blob-report/

# Misc
*.pem

docker-compose.override.yml
20 changes: 20 additions & 0 deletions DISCLAIMER.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ Before running Automaker, we strongly recommend reviewing the source code yourse
- **Virtual Machine**: Use a VM (such as VirtualBox, VMware, or Parallels) to create an isolated environment
- **Cloud Development Environment**: Use a cloud-based development environment that provides isolation

#### Running in Isolated Docker Container

For maximum security, run Automaker in an isolated Docker container that **cannot access your laptop's files**:

```bash
# 1. Set your API key (bash/Linux/Mac - creates UTF-8 file)
echo "ANTHROPIC_API_KEY=your-api-key-here" > .env

# On Windows PowerShell, use instead:
Set-Content -Path .env -Value "ANTHROPIC_API_KEY=your-api-key-here" -Encoding UTF8

# 2. Build and run isolated container
docker-compose up -d

# 3. Access the UI at http://localhost:3007
# API at http://localhost:3008/api/health
```

The container uses only Docker-managed volumes and has no access to your host filesystem. See [docker-isolation.md](docs/docker-isolation.md) for full documentation.

### 3. Limit Access

If you must run locally:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The future of software development is **agentic coding**—where developers beco
>
> **We do not recommend running Automaker directly on your local computer** due to the risk of AI agents having access to your entire file system. Please sandbox this application using Docker or a virtual machine.
>
> **[Read the full disclaimer](../DISCLAIMER.md)**
> **[Read the full disclaimer](./DISCLAIMER.md)**

---

Expand Down
6 changes: 5 additions & 1 deletion apps/server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
# Build stage
FROM node:20-alpine AS builder

# Install build dependencies for native modules (node-pty)
RUN apk add --no-cache python3 make g++

WORKDIR /app

# Copy package files
# Copy package files and scripts needed for postinstall
COPY package*.json ./
COPY apps/server/package*.json ./apps/server/
COPY scripts ./scripts

# Install dependencies
RUN npm ci --workspace=apps/server
Expand Down
43 changes: 43 additions & 0 deletions apps/ui/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Automaker UI
# Multi-stage build for minimal production image

# Build stage
FROM node:20-alpine AS builder

# Install build dependencies
RUN apk add --no-cache python3 make g++

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY apps/ui/package*.json ./apps/ui/
COPY scripts ./scripts

# Install dependencies (skip electron postinstall)
RUN npm ci --workspace=apps/ui --ignore-scripts

# Copy source
COPY apps/ui ./apps/ui

# Build for web (skip electron)
# VITE_SERVER_URL tells the UI where to find the API server
# Using localhost:3008 since both containers expose ports to the host
# Use ARG to allow overriding at build time: --build-arg VITE_SERVER_URL=http://api.example.com
ARG VITE_SERVER_URL=http://localhost:3008
ENV VITE_SKIP_ELECTRON=true
ENV VITE_SERVER_URL=${VITE_SERVER_URL}
RUN npm run build --workspace=apps/ui

# Production stage - serve with nginx
FROM nginx:alpine

# Copy built files
COPY --from=builder /app/apps/ui/dist /usr/share/nginx/html

# Copy nginx config for SPA routing
COPY apps/ui/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
10 changes: 10 additions & 0 deletions apps/ui/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}
}
10 changes: 10 additions & 0 deletions docker-compose.override.yml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
server:
volumes:
# Mount your workspace directory to /projects inside the container
- /Users/webdevcody/Workspace/automaker-workspace:/projects:rw
environment:
# Set workspace directory so the UI can discover projects
- WORKSPACE_DIR=/projects
# Ensure /projects is in allowed directories
- ALLOWED_PROJECT_DIRS=/projects
42 changes: 36 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
# Automaker Docker Compose
# For self-hosting the Automaker backend server
# Runs Automaker in complete isolation from your host filesystem.
# The container cannot access any files on your laptop - only Docker-managed volumes.
#
# Usage:
# docker-compose up -d
# Then open http://localhost:3007
#
# See docs/docker-isolation.md for full documentation.

services:
# Frontend UI
ui:
build:
context: .
dockerfile: apps/ui/Dockerfile
container_name: automaker-ui
restart: unless-stopped
ports:
- "3007:80"
depends_on:
- server

# Backend API Server
server:
build:
context: .
Expand All @@ -17,10 +37,11 @@ services:
# Optional - authentication (leave empty to disable)
- AUTOMAKER_API_KEY=${AUTOMAKER_API_KEY:-}

# Optional - restrict to specific directories (comma-separated)
# Optional - restrict to specific directories within container only
# These paths are INSIDE the container, not on your host
- ALLOWED_PROJECT_DIRS=${ALLOWED_PROJECT_DIRS:-/projects}

# Optional - data directory for sessions, etc.
# Optional - data directory for sessions, etc. (container-only)
- DATA_DIR=/data

# Optional - CORS origin (default allows all)
Expand All @@ -30,11 +51,20 @@ services:
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- GOOGLE_API_KEY=${GOOGLE_API_KEY:-}
volumes:
# Persist data between restarts
# ONLY named volumes - these are isolated from your host filesystem
# This volume persists data between restarts but is container-managed
- automaker-data:/data

# Mount your projects directory (read-write access)
- ${PROJECTS_DIR:-./projects}:/projects
# NO host directory mounts - container cannot access your laptop files
# If you need to work on a project, create it INSIDE the container
# or use a separate docker-compose override file

# Security: Server runs as non-root user (already set in Dockerfile)
# Security: No privileged mode
# Security: No host network access
# Security: No host filesystem mounts

volumes:
automaker-data:
name: automaker-data
# Named volume - completely isolated from host filesystem
66 changes: 66 additions & 0 deletions docs/docker-isolation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Docker Isolation Guide

This guide covers running Automaker in a fully isolated Docker container. For background on why isolation matters, see the [Security Disclaimer](../DISCLAIMER.md).

## Quick Start

1. **Set your API key** (create a `.env` file in the project root):

```bash
# Linux/Mac
echo "ANTHROPIC_API_KEY=your-api-key-here" > .env

# Windows PowerShell
Set-Content -Path .env -Value "ANTHROPIC_API_KEY=your-api-key-here" -Encoding UTF8
```

2. **Build and run**:

```bash
docker-compose up -d
```

3. **Access Automaker** at `http://localhost:3007`

4. **Stop**:

```bash
docker-compose down
```

## How Isolation Works

The default `docker-compose.yml` configuration:

- Uses only Docker-managed volumes (no host filesystem access)
- Server runs as a non-root user
- Has no privileged access to your system

Projects created in the UI are stored inside the container at `/projects` and persist across restarts via Docker volumes.

## Mounting a Specific Project

If you need to work on a host project, create `docker-compose.project.yml`:

```yaml
services:
server:
volumes:
- ./my-project:/projects/my-project:ro # :ro = read-only
```

Then run:

```bash
docker-compose -f docker-compose.yml -f docker-compose.project.yml up -d
```

**Tip**: Use `:ro` (read-only) when possible for extra safety.

## Troubleshooting

| Problem | Solution |
| --------------------- | -------------------------------------------------------------------------------------------- |
| Container won't start | Check `.env` has `ANTHROPIC_API_KEY` set. Run `docker-compose logs` for errors. |
| Can't access web UI | Verify container is running with `docker ps \| grep automaker` |
| Need a fresh start | Run `docker-compose down && docker volume rm automaker-data && docker-compose up -d --build` |