Skip to content

Conversation

@illia1f
Copy link
Contributor

@illia1f illia1f commented Dec 20, 2025

Summary

  • Add Docker Compose configuration for running Automaker in a fully isolated container with no access to host filesystem
  • Create multi-stage Dockerfiles for both UI (nginx) and server (Node.js) with security best practices (non-root user, health checks)
  • Add comprehensive documentation explaining isolation benefits, usage, and security verification steps

Problem

Automaker uses AI-powered agents that can read, write, delete files, and execute commands on the operating system. Running it directly on a user's local machine poses significant security risks, as the AI could potentially access sensitive files or cause unintended damage to the system.

Solution

This PR introduces a Docker-based deployment option that:

  • Completely isolates the container from the host filesystem (no volume mounts to host directories)
  • Uses named Docker volumes for data persistence, which are container-managed
  • Runs the server as a non-root user for additional security
  • Provides a simple docker-compose up -d workflow for easy setup
  • Documents how to optionally mount specific project directories when needed (with read-only options)

Test plan

  • Run docker-compose up -d and verify containers start successfully
  • Access UI at http://localhost:3007 and API at http://localhost:3008/api/health
  • Verify container cannot access host files via docker exec automaker-server ls /host
  • Test creating a project inside the container to confirm persistence works
  • Stop and restart containers to verify data persists in Docker volumes

Summary by CodeRabbit

  • New Features

    • UI is containerized and served via nginx; new isolated Docker-based deployment option with a dedicated UI service.
  • Documentation

    • Added full guide for running in a fully isolated Docker container with quick start, troubleshooting, security notes and sandboxing guidance.
    • README link updated to reference the included disclaimer.
  • Chores

    • Build environment and container orchestration enhancements to support native build steps, production packaging, and isolated persistent storage.

✏️ Tip: You can customize this high-level summary in your review settings.

Provide Docker Compose configuration allowing users to run Automaker
in complete isolation from their host filesystem, addressing security
concerns about AI agents having direct system access.
@coderabbitai
Copy link

coderabbitai bot commented Dec 20, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Added full isolated-Docker deployment artifacts and docs: new UI Dockerfile + nginx config, updated server Dockerfile, docker-compose changes to enforce container-only volumes, new docker-isolation docs and DISCLAIMER instructions, and a README link fix.

Changes

Cohort / File(s) Summary
Documentation & Disclaimers
DISCLAIMER.md, README.md, docs/docker-isolation.md
Added "Running in Isolated Docker Container" guidance to DISCLAIMER.md, corrected README link to ./DISCLAIMER.md, and added docs/docker-isolation.md with quick-start, isolation properties, troubleshooting, and optional per-project mount instructions.
Docker Orchestration & Isolation
docker-compose.yml, docker-compose.override.yml.example, .gitignore
Added ui service (build from apps/ui/Dockerfile), updated server service to use container-only automaker-data:/data volume, added automaker-data named volume, environment keys (ALLOWED_PROJECT_DIRS, DATA_DIR), removed host-mounted projects by default; added example override that mounts host /projects; added docker-compose.override.yml to .gitignore.
Server Dockerfile changes
apps/server/Dockerfile
In builder stage, installed native build deps (python3, make, g++) and extended COPY to include scripts/ alongside package*.json, preparing for postinstall/build scripts while keeping npm ci.
UI Dockerfile & Nginx
apps/ui/Dockerfile, apps/ui/nginx.conf
New multi-stage UI Dockerfile: build stage (node:20-alpine, installs build deps, npm ci, builds with VITE env vars) and production stage (nginx:alpine serving built assets). Added apps/ui/nginx.conf with SPA fallback to index.html.
Misc config / examples
docker-compose.override.yml.example
Example override shows mounting host workspace at /projects with env vars WORKSPACE_DIR and ALLOWED_PROJECT_DIRS for developers who opt into host mounts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Check server assumptions about host-mounted /projects vs named volume automaker-data and any code paths that read host paths.
  • Verify environment variable wiring (ANTHROPIC_API_KEY, AUTOMAKER_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY, ALLOWED_PROJECT_DIRS, DATA_DIR) in runtime and UI build (VITE_SERVER_URL).
  • Confirm added build deps in apps/server/Dockerfile are minimal and necessary.
  • Validate nginx config and asset path copying in apps/ui/Dockerfile.

Possibly related PRs

Poem

🐰 In a snug container I hop and play,

No host to nibble, volumes keep hay,
UI bakes bright, server hums on cue,
Secrets tucked safe in a Docker pew,
A rabbit applauds the isolated view! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective of adding Docker containerization for secure, isolated execution, which aligns with all major changes in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c01706 and e65c4ae.

📒 Files selected for processing (2)
  • .gitignore (1 hunks)
  • docker-compose.override.yml.example (1 hunks)

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @illia1f, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the security posture of Automaker by introducing a robust Docker-based containerization strategy. It provides a fully isolated environment for running the application, preventing AI agents from accessing or modifying the host filesystem, thereby addressing critical security concerns and making the tool safer for users.

Highlights

  • Docker Compose Configuration: Added a docker-compose.yml setup for isolated execution of Automaker, including a new UI service.
  • Secure Dockerfiles: Introduced multi-stage Dockerfiles for both the UI (Nginx) and server (Node.js), incorporating security best practices like non-root users and necessary build dependencies.
  • Comprehensive Documentation: Provided detailed documentation (docs/docker-isolation.md) explaining the benefits of isolation, usage instructions, and security verification steps.
  • Enhanced Security: Implemented complete isolation from the host filesystem using named Docker volumes, running services as non-root users, and removing host directory mounts to mitigate security risks posed by AI agents.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant security enhancement, introducing Docker containerization to run the application in a secure, isolated environment. The use of multi-stage Dockerfiles, non-root users, and a well-documented docker-compose setup demonstrates a strong adherence to best practices. My review focuses on minor improvements to enhance the flexibility, readability, and robustness of the new Docker configuration. Overall, this is an excellent and well-executed feature.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
apps/ui/Dockerfile (4)

31-45: Consider nginx security hardening.

The nginx configuration is functional but lacks security hardening. The nginx:alpine image runs as root by default, and no security headers are configured.

🔎 Suggested security improvements
 # Production stage - serve with nginx
 FROM nginx:alpine
 
+# Create nginx user for non-root execution
+RUN chown -R nginx:nginx /var/cache/nginx && \
+    chown -R nginx:nginx /var/log/nginx && \
+    touch /var/run/nginx.pid && \
+    chown -R nginx:nginx /var/run/nginx.pid
+
 # Copy built files
 COPY --from=builder /app/apps/ui/dist /usr/share/nginx/html
+RUN chown -R nginx:nginx /usr/share/nginx/html
 
 # Copy nginx config for SPA routing
 RUN echo 'server { \
     listen 80; \
     server_name localhost; \
     root /usr/share/nginx/html; \
     index index.html; \
+    server_tokens off; \
+    add_header X-Frame-Options "SAMEORIGIN" always; \
+    add_header X-Content-Type-Options "nosniff" always; \
+    add_header X-XSS-Protection "1; mode=block" always; \
     location / { \
         try_files $uri $uri/ /index.html; \
     } \
 }' > /etc/nginx/conf.d/default.conf
 
+USER nginx
+
 EXPOSE 80
 
 CMD ["nginx", "-g", "daemon off;"]

47-49: Add health check for better container orchestration.

The UI container lacks a health check, while the server container includes one. Adding a health check helps Docker Compose and orchestration tools determine when the service is ready.

🔎 Add HEALTHCHECK
 EXPOSE 80
 
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+    CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1
+
 CMD ["nginx", "-g", "daemon off;"]

7-8: Remove unnecessary build dependencies from the web Docker build.

The Dockerfile installs python3, make, and g++ on line 8, but the web build uses npm ci --ignore-scripts, which prevents postinstall scripts from running. Since the UI dependencies are pure JavaScript packages without native module requirements (optionalDependencies like lightningcss are precompiled binaries, and npmRebuild is set to false), these build tools are unused and can be safely removed to reduce image size and build time.


24-28: Document the localhost hardcoding limitation for remote deployments.

The VITE_SERVER_URL is embedded into the client bundle at build time, so the hardcoded http://localhost:3008 means the app only works when both the UI and server are accessible via localhost on the same machine. This setup is appropriate for the local development environment shown in docker-compose.yml, but would fail if someone attempts to deploy this to a remote server or access from a different machine on the network.

For local development use, clarify this limitation in a comment or documentation. If remote deployment becomes a use case, implement runtime configuration using a template substitution pattern (e.g., Nginx envsubst with placeholder variables in index.html).

docs/docker-isolation.md (2)

41-59: Clarify security implications of host mounts.

The section demonstrates mounting host directories with the :ro (read-only) flag but doesn't fully explain the security trade-off. Even with :ro, the AI agents gain read access to the mounted directory, which could expose sensitive files (credentials, SSH keys, etc.).

Consider adding a warning about what files the AI can read in mounted directories.

🔎 Suggested documentation enhancement
 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:

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

-Tip: Use :ro (read-only) when possible for extra safety.
+Security Note:
+- Even with :ro (read-only), AI agents can read all files in the mounted directory.
+- Ensure the mounted directory doesn't contain sensitive files (SSH keys, credentials, etc.).
+- Use :ro to prevent writes, but understand that read access is still granted.

</details>

---

`60-66`: **Consider Windows-compatible troubleshooting commands.**

Line 65 uses `docker ps | grep automaker`, which works on Linux/Mac and Windows Git Bash, but not on Windows Command Prompt or PowerShell without additional setup. Consider providing Windows PowerShell alternatives.



<details>
<summary>🔎 Windows-compatible alternatives</summary>

```diff
 | 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`                                         |
+| Can't access web UI   | Verify container is running with `docker ps \| grep automaker` (Linux/Mac) or `docker ps` and look for automaker (Windows) |
 | Need a fresh start    | Run `docker-compose down && docker volume rm automaker_automaker-data && docker-compose up -d --build` |
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d104a24 and abc55cf.

📒 Files selected for processing (6)
  • DISCLAIMER.md (1 hunks)
  • README.md (1 hunks)
  • apps/server/Dockerfile (1 hunks)
  • apps/ui/Dockerfile (1 hunks)
  • docker-compose.yml (3 hunks)
  • docs/docker-isolation.md (1 hunks)
🔇 Additional comments (9)
docs/docker-isolation.md (1)

5-29: LGTM! Clear and platform-specific instructions.

The Quick Start section provides clear, platform-specific commands for setting up the API key and running the containers. The Windows PowerShell alternative is particularly helpful.

README.md (1)

82-82: LGTM! Correct relative path fix.

The hyperlink has been correctly updated to ./DISCLAIMER.md since both README.md and DISCLAIMER.md are in the root directory. The previous ../DISCLAIMER.md would have been an incorrect path.

apps/server/Dockerfile (2)

7-8: LGTM! Build dependencies are necessary for native modules.

The build dependencies (python3, make, g++) are required for compiling native modules like node-pty. The comment clearly explains this, and since line 18 runs npm ci without --ignore-scripts, these tools will be used during the build.


12-15: LGTM! Scripts directory needed for build process.

Adding the scripts directory copy is appropriate for a monorepo setup where postinstall or build scripts may be referenced by package.json. This aligns with the build process that runs npm ci and build commands.

DISCLAIMER.md (1)

33-52: LGTM! Clear Docker isolation guidance.

The new section provides clear, step-by-step instructions for running Automaker in an isolated Docker container. The commands are correct for both Linux/Mac and Windows platforms, and the description accurately reflects the isolation guarantees provided by the default docker-compose.yml configuration.

docker-compose.yml (4)

1-23: LGTM! Clear documentation and proper UI service configuration.

The header comments accurately describe the isolation guarantees, and the UI service is properly configured with:

  • Correct build context and Dockerfile path
  • Appropriate restart policy
  • Correct port mapping (3007:80)
  • Proper dependency on the server service

24-52: Environment variables configured correctly.

The server service environment variables are well-documented with clear comments indicating container-only paths. The configuration appropriately separates required (ANTHROPIC_API_KEY) from optional variables.

Note: CORS_ORIGIN defaults to * (allow all origins), which is appropriate for local development but would need restriction for production deployments. Since this PR focuses on local isolated Docker execution, this is acceptable.

Consider documenting the CORS behavior in docs/docker-isolation.md if users plan to expose the service beyond localhost.


53-65: LGTM! Volumes configured for proper isolation.

The volumes configuration correctly uses only Docker-managed named volumes without any host directory bind mounts, achieving the isolation goals stated in the PR objectives. The extensive comments clearly explain the isolation guarantees and provide guidance for users who need to work on host projects.


67-69: LGTM! Proper named volume for isolation.

The named volume is correctly defined and the comment accurately describes its isolation from the host filesystem. This configuration ensures data persists between container restarts while maintaining isolation.

@Shironex Shironex added Enhancement Improvements to existing functionality or UI. Testers-Requested Request for others to test an enhancement or bug fix/etc. labels Dec 20, 2025
- Modified docker-compose.yml to clarify that the server runs as a non-root user.
- Updated Dockerfile to use ARG for VITE_SERVER_URL, allowing build-time overrides.
- Replaced inline Nginx configuration with a separate nginx.conf file for better maintainability.
- Adjusted documentation to reflect changes in Docker setup and troubleshooting steps.
@Shironex Shironex added the Do Not Merge Use this label if something should not be merged. label Dec 20, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
docs/docker-isolation.md (1)

66-66: Use explicit volume name for clarity.

The troubleshooting command should use the explicit volume name automaker-data instead of relying on Docker's auto-generated naming. This makes the command more reliable and consistent with the docker-compose configuration.

🔎 Proposed fix
-| Need a fresh start    | Run `docker-compose down && docker volume rm automaker-data && docker-compose up -d --build` |
+| Need a fresh start    | Run `docker-compose down && docker volume rm automaker-data && docker-compose up -d --build` |

Note: Verify that the volume is actually named automaker-data in your docker-compose.yml file.

🧹 Nitpick comments (2)
apps/ui/nginx.conf (1)

1-10: Consider adding security headers and performance optimizations.

The configuration is functional for a SPA, but production deployments typically benefit from:

  • Security headers (X-Frame-Options, X-Content-Type-Options, Content-Security-Policy)
  • Gzip compression for text assets
  • Caching headers for static assets (js, css, images)
🔎 Proposed enhancements
 server {
     listen 80;
     server_name localhost;
     root /usr/share/nginx/html;
     index index.html;
+
+    # Security headers
+    add_header X-Frame-Options "SAMEORIGIN" always;
+    add_header X-Content-Type-Options "nosniff" always;
+    add_header X-XSS-Protection "1; mode=block" always;
+
+    # Enable gzip compression
+    gzip on;
+    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+    gzip_min_length 256;
+
+    # Cache static assets
+    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
+        expires 1y;
+        add_header Cache-Control "public, immutable";
+    }
 
     location / {
         try_files $uri $uri/ /index.html;
     }
 }
apps/ui/Dockerfile (1)

33-43: Consider running nginx as non-root and adding a health check.

The current production stage uses nginx:alpine, which runs as root by default. For improved security posture:

  • Run nginx as a non-root user (requires permissions adjustments)
  • Add a HEALTHCHECK directive for container health monitoring
🔎 Proposed security enhancements
 # Production stage - serve with nginx
 FROM nginx:alpine
 
+# Create non-root user and adjust permissions
+RUN addgroup -g 101 -S nginx-custom && \
+    adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx-custom -g nginx-custom nginx-custom && \
+    chown -R nginx-custom:nginx-custom /usr/share/nginx/html /var/cache/nginx /var/log/nginx /etc/nginx/conf.d && \
+    touch /var/run/nginx.pid && \
+    chown -R nginx-custom:nginx-custom /var/run/nginx.pid
+
 # 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
 
+# Health check
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+    CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1
+
+USER nginx-custom
+
 CMD ["nginx", "-g", "daemon off;"]

Note: Running nginx as non-root requires additional configuration and may need adjustments to listen on port 80 (you might need to use port 8080 instead and update the docker-compose port mapping).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abc55cf and 5c01706.

📒 Files selected for processing (4)
  • apps/ui/Dockerfile (1 hunks)
  • apps/ui/nginx.conf (1 hunks)
  • docker-compose.yml (3 hunks)
  • docs/docker-isolation.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker-compose.yml
🔇 Additional comments (3)
docs/docker-isolation.md (1)

31-37: LGTM - Past review comment addressed.

The documentation now correctly specifies "Server runs as a non-root user" instead of the ambiguous "Runs as a non-root user." This clarification addresses the previous review feedback.

apps/ui/Dockerfile (2)

27-29: LGTM - ARG pattern implemented correctly.

The ARG/ENV pattern allows overriding VITE_SERVER_URL at build time while maintaining a sensible default. This addresses the previous review feedback about build-time flexibility.


39-39: LGTM - Using separate nginx.conf file.

Using a separate nginx.conf file improves maintainability and readability compared to inline configuration. This addresses the previous review feedback.

@webdevcody
Copy link
Collaborator

this looks great, I will review soon, test, and merge if all seems ok

@webdevcody
Copy link
Collaborator

@claude when running locally, how would I volume mount a local directory with projects into the docker-compose setup so that automaker can modify existing projects

@claude
Copy link

claude bot commented Dec 20, 2025

Claude encountered an error —— View job

Command failed: git fetch origin --depth=20 feature/isolated-docker-compose

I'll analyze this and get back to you.

- Added docker-compose.override.yml to .gitignore to prevent it from being tracked.
- Introduced a new example configuration file for docker-compose.override.yml to guide users in setting up their local development environment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Use this label if something should not be merged. Enhancement Improvements to existing functionality or UI. Testers-Requested Request for others to test an enhancement or bug fix/etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants