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
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules/
dist/
*.db
*.db-shm
*.db-wal
.env
.env.*
.git/
.github/
assets/
docs/
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:20-alpine AS builder
RUN corepack enable
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm run build

FROM node:20-alpine AS runner
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

It is a security best practice to run Docker containers as a non-root user. The node image provides a built-in node user that can be used for this purpose. Ensure that the /app directory and any mounted volumes have the correct permissions for this user.

FROM node:20-alpine AS runner
RUN corepack enable
WORKDIR /app
USER node

RUN corepack enable
WORKDIR /app
COPY --from=builder /app/package.json /app/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod
COPY --from=builder /app/dist ./dist
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The application requires the drizzle folder to run database migrations at startup (as seen in src/server/cli.ts). Since the runner stage only copies the dist folder, the migrations will fail. You should copy the migrations folder from the builder stage.

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/drizzle ./drizzle


ENV PORT=3001
EXPOSE 3001
CMD ["node", "dist/server/cli.js"]
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ npx agentree --port 8080 --opencode-url http://localhost:6543
**DB location:** `~/.agentree/agentree.db`
Override with `DB_PATH=./agentree.db npx agentree`.

### Docker

**Already have opencode running:**

```bash
docker compose up agentree
```

**Need opencode too (full stack):**

```bash
docker compose --profile with-opencode up
```

Open http://localhost:3001 in your browser.

---

## How it works
Expand Down
47 changes: 47 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
services:
agentree:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

When using the with-opencode profile, the agentree service should wait for the opencode service to be healthy before starting. This prevents agentree from exiting immediately if it cannot connect to opencode during the initial boot sequence.

  agentree:
    build: .
    depends_on:
      opencode:
        condition: service_healthy
        required: false

build: .
ports:
- "${AGENTREE_PORT:-3001}:3001"
environment:
OPENCODE_API_URL: ${OPENCODE_API_URL:-http://opencode:6543}
OPENCODE_SERVER_USERNAME: ${OPENCODE_SERVER_USERNAME:-opencode}
OPENCODE_SERVER_PASSWORD: ${OPENCODE_SERVER_PASSWORD:-}
DB_PATH: /data/agentree.db
volumes:
- agentree_data:/data
restart: unless-stopped

opencode:
profiles: [with-opencode]
image: ${OPENCODE_IMAGE:-ghcr.io/anomalyco/opencode:latest}
environment:
HOME: /root
OPENCODE_CONFIG_DIR: /root/.config/opencode
OPENCODE_SERVER_PASSWORD: ${OPENCODE_SERVER_PASSWORD:-}
OPENCODE_SERVER_USERNAME: ${OPENCODE_SERVER_USERNAME:-opencode}
OPENCODE_DISABLE_AUTOUPDATE: ${OPENCODE_DISABLE_AUTOUPDATE:-1}
OPENCODE_DISABLE_LSP_DOWNLOAD: ${OPENCODE_DISABLE_LSP_DOWNLOAD:-0}
OPENCODE_EXPERIMENTAL: ${OPENCODE_EXPERIMENTAL:-0}
TZ: ${TZ:-UTC}
volumes:
- ${OPENCODE_WORKSPACE_DIR:-.}:/workspace
- ${OPENCODE_CONFIG_HOST_DIR:-opencode_config}:/root/.config/opencode
- ${OPENCODE_DATA_HOST_DIR:-opencode_data}:/root/.local/share/opencode
ports:
- "${OPENCODE_PORT:-6543}:6543"
working_dir: /workspace
restart: unless-stopped
init: true
command: ["serve", "--hostname", "0.0.0.0", "--port", "6543"]
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:6543/global/health >/dev/null 2>&1"]
interval: 20s
timeout: 5s
retries: 5
start_period: 20s

volumes:
agentree_data:
opencode_config:
opencode_data:
Loading