-
Notifications
You must be signed in to change notification settings - Fork 490
feat: Add Docker containerization for secure, isolated execution #179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Docker containerization for secure, isolated execution #179
Conversation
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.
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughAdded 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–30 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
Comment |
Summary of ChangesHello @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
🧠 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 AssistThe 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
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 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
|
There was a problem hiding this 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.
There was a problem hiding this 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, andg++on line 8, but the web build usesnpm ci --ignore-scripts, which prevents postinstall scripts from running. Since the UI dependencies are pure JavaScript packages without native module requirements (optionalDependencies likelightningcssare precompiled binaries, andnpmRebuildis 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_URLis embedded into the client bundle at build time, so the hardcodedhttp://localhost:3008means 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 indocker-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
envsubstwith placeholder variables inindex.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-onlyThen 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:roto 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
📒 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.mdsince both README.md and DISCLAIMER.md are in the root directory. The previous../DISCLAIMER.mdwould 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 ciwithout--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_ORIGINdefaults 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.
- 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.
There was a problem hiding this 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-datainstead 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-datain yourdocker-compose.ymlfile.
🧹 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
HEALTHCHECKdirective 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
📒 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/ENVpattern allows overridingVITE_SERVER_URLat 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.conffile improves maintainability and readability compared to inline configuration. This addresses the previous review feedback.
|
this looks great, I will review soon, test, and merge if all seems ok |
|
@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 encountered an error —— View job 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.
Summary
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:
docker-compose up -dworkflow for easy setupTest plan
docker-compose up -dand verify containers start successfullydocker exec automaker-server ls /hostSummary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.