ANTIGRAVITY LABJP
Articles/Tips & Best Practices
Tips & Best Practices/2026-04-26Intermediate

Antigravity DevContainer Setup — Killing 'Works on My Machine' for Team Development

Once Antigravity goes multi-user, someone always says 'doesn't work on my setup.' Adding DevContainers solves this surprisingly cleanly. Here's the configuration I run and the gotchas to know.

Antigravity267DevContainer3Docker3Team Development2Reproducibility

I'm primarily a solo developer, but in the last few months I've been working with external freelancers in Antigravity more often. What happened in week one: daily messages of "doesn't work on my end."

The causes were mundane — Node.js version mismatches, Python virtualenv differences, linter config load order, shell-induced PATH variations. Things I never noticed when only I touched the environment surfaced all at once in collaboration.

To fix this structurally, I adopted DevContainers in my Antigravity projects. The result: "open Antigravity, everyone develops inside the exact same Docker container." Environment-divergence troubles plummeted. Here's the configuration and operational notes.

What DevContainers Are and Why They Click With Antigravity

DevContainers grew up in the VS Code ecosystem. You declare a container in .devcontainer/devcontainer.json and the editor runs your development inside that container. Antigravity is a VS Code-family editor, so the mechanism just works.

"Couldn't you just use Docker?" — yes, but DevContainers' real value is that the editor handles container setup, launch, mount points, and extension installation for you. Team members do "clone the repo, open in Antigravity" and get the same environment with zero setup.

This pays off for solo developers using multiple machines too. I work across desktop, MacBook, and a home Mac mini — keeping Node.js, Python, and friends in sync on three machines was honestly tedious. After containerizing, any machine with Docker just works.

Minimal devcontainer.json

Start minimal. Create .devcontainer/devcontainer.json at project root.

{
  "name": "My Antigravity Project",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:20",
  "postCreateCommand": "npm install",
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode"
      ]
    }
  }
}

That's it. Open the project in Antigravity and a "Reopen in Container?" dialog appears. Yes, and Antigravity rebuilds and runs inside the container. npm install runs automatically and the ESLint and Prettier extensions are auto-installed.

The image field references a Microsoft-published standard image. For TypeScript + Node.js the one above is convenient. Python: mcr.microsoft.com/devcontainers/python:3.12. Go: mcr.microsoft.com/devcontainers/go:1.22.

This alone guarantees "everyone uses the same Node.js version." That single guarantee resolved half the disputes I was having.

Practical Setup — Multi-Service

Real projects need a database, Redis, etc. Add a docker-compose.yml.

.devcontainer/docker-compose.yml:

services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspaces/${localWorkspaceFolderBasename}:cached
    command: sleep infinity
    environment:
      - DATABASE_URL=postgres://dev:dev@db:5432/devdb
      - REDIS_URL=redis://redis:6379
 
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: devdb
    volumes:
      - postgres-data:/var/lib/postgresql/data
 
  redis:
    image: redis:7-alpine
    restart: unless-stopped
 
volumes:
  postgres-data:

.devcontainer/Dockerfile:

FROM mcr.microsoft.com/devcontainers/typescript-node:20
 
RUN apt-get update && apt-get install -y \
    postgresql-client \
    redis-tools \
    && rm -rf /var/lib/apt/lists/*
 
USER node

.devcontainer/devcontainer.json:

{
  "name": "My Antigravity Project",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
  "postCreateCommand": "npm install && npm run db:migrate",
  "forwardPorts": [3000, 5432, 6379],
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "ckolkman.vscode-postgres"
      ]
    }
  }
}

Now opening Antigravity launches the app container, PostgreSQL, and Redis simultaneously. The app reaches PostgreSQL at hostname db and Redis at hostname redis.

postCreateCommand runs migrations automatically, so a new teammate cloning the repo and opening Antigravity gets "deps installed → DB up → migrations done" for free. This is genuinely powerful.

Gotcha 1: File Ownership

The first wall after adopting DevContainers: file ownership. Container user (often node or vscode) and host user have different UIDs, so files created inside the container show up "readable but not writable" on the host.

Fix: align the container user's UID to the host. Inside the Dockerfile:

ARG USER_UID=1000
ARG USER_GID=1000
 
RUN if [ "$USER_UID" != "1000" ]; then \
    usermod -u $USER_UID node && \
    groupmod -g $USER_GID node; \
    fi

Pass UID/GID via build.args in devcontainer.json:

{
  "build": {
    "dockerfile": "Dockerfile",
    "args": {
      "USER_UID": "${localEnv:UID}",
      "USER_GID": "${localEnv:GID}"
    }
  }
}

This avoids ownership issues on Linux hosts. On macOS, Docker Desktop handles UID mapping nicely so you rarely hit this.

Gotcha 2: Antigravity Extensions — Server-Side vs Client-Side

In DevContainers, some extensions run on the container side and some on the local side. Antigravity's AI features run locally; language tools like linters run in the container.

The problem: some Antigravity-bundled plugins might "install on container side when they should be local-side" or vice versa. Features stop working or double-run.

Fix: in customizations.vscode.extensions, list only the things that should run in the container. Skip AI-side plugins and Antigravity-specific UI extensions. Stick to language servers, formatters, linters — anything tied to the project's language.

Gotcha 3: File Watch Limits

Heavy file-watching tasks (webpack-dev-server, Vite HMR) inside DevContainers can hit the Linux host's inotify ceiling. The error reads ENOSPC: System limit for number of file watchers reached.

Fix: relax the limit via Dockerfile or devcontainer.json.

{
  "containerEnv": {
    "CHOKIDAR_USEPOLLING": "false"
  },
  "runArgs": [
    "--sysctl", "fs.inotify.max_user_watches=524288"
  ]
}

CHOKIDAR_USEPOLLING=true switches to polling and avoids inotify, but burns CPU — not recommended. Raising the cap via runArgs is cleaner.

Team Operation Best Practices

Operational notes from running this with teams:

Always discuss .devcontainer/ changes via PR. Casual edits trigger a 20-minute container rebuild for everyone next time they open the project. The team needs a shared sense of how expensive these changes are.

Make postCreateCommand idempotent. npm install is idempotent so it's fine, but commands with side effects like migrations need "skip if already done" logic. Or use postCreateCommand (runs only on container creation) instead of postStartCommand to limit blast radius.

Tell the team about "Rebuild Container." When the container goes weird, the Antigravity command palette has "Rebuild Container" — rebuild from scratch. Just knowing this exists shaves hours off recovery time.

When Not to Use DevContainers

Honestly, not every project benefits.

Short-lived prototypes and solo-only tools — the setup overhead isn't worth it. Container startup is also a couple of minutes, and that latency may not be worth losing for the convenience tradeoff.

Native GUI development (Electron apps, mobile dev with simulators) is also a bad fit. X11 forwarding is possible but adds significant complexity.

My personal rule: containerize if any of these hold — "3+ people will touch it," "lifespan of 6+ months," "uses peripheral services like a DB or queue."

Tomorrow's Steps

Smallest path to try tomorrow:

Create .devcontainer/devcontainer.json at the root of an existing Antigravity project; paste in the minimal example. Install Docker Desktop (or Docker Engine on Linux). Restart Antigravity or pick "Reopen in Container" from the command palette — the container builds and launches.

That's 30 minutes to an hour, though the first launch downloads images so brew coffee and wait. Subsequent launches take seconds.

The relief of "works on my machine" disappearing is bigger than I expected. Collaboration friction drops, new-member onboarding shrinks from half a day to five minutes. Once you taste it, projects without DevContainers start to feel old-fashioned.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Antigravity2026-04-25
Running Antigravity in a DevContainer: A Setup Your Whole Team Can Share
Wrapping Antigravity in a DevContainer eliminates the 'works on my machine' problem. This guide walks through a minimal Dockerfile / devcontainer.json, GPU passthrough for agent workloads, and safe handling of credentials.
Editor View2026-04-25
Antigravity DevContainer: A Complete Setup Guide for Reproducible AI Development
An end-to-end guide to running Antigravity inside a DevContainer — Docker setup, Ollama integration, secrets, volume persistence, team distribution, and CI parity.
Tips2026-06-22
Strip Secrets Out of the Agent Logs You Keep: Designing a Redaction Layer
Once you start keeping logs from unattended agents, a token or API key eventually lands in them in plaintext. Rotating the key doesn't unmake the leaked log. This designs a redaction layer that reliably drops secrets right before the write, going beyond regex to register known secrets and mask them for certain, with working Python and field notes.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →