Skip to content

Commit 10f2ee0

Browse files
feat(devenv): Add support for dev container (#832)
1 parent 80dd075 commit 10f2ee0

File tree

5 files changed

+247
-0
lines changed

5 files changed

+247
-0
lines changed

.devcontainer/Dockerfile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Development container for Sourcebot
2+
# Based on Node.js 24 with TypeScript support
3+
FROM mcr.microsoft.com/devcontainers/typescript-node:24
4+
5+
ARG GO_VERSION=1.23.4
6+
ARG CTAGS_VERSION=v6.1.0
7+
8+
# Install system dependencies
9+
RUN apt-get update && apt-get install -y --no-install-recommends \
10+
# Build tools for universal-ctags
11+
autoconf \
12+
automake \
13+
pkg-config \
14+
make \
15+
gcc \
16+
g++ \
17+
libjansson-dev \
18+
libyaml-dev \
19+
libseccomp-dev \
20+
libxml2-dev \
21+
# PostgreSQL client tools (for debugging)
22+
postgresql-client \
23+
# Redis CLI tools (for debugging)
24+
redis-tools \
25+
# Other utilities
26+
curl \
27+
git \
28+
&& rm -rf /var/lib/apt/lists/*
29+
30+
# Install Go (detect architecture automatically)
31+
RUN ARCH=$(dpkg --print-architecture) && \
32+
if [ "$ARCH" = "arm64" ]; then GOARCH="arm64"; else GOARCH="amd64"; fi && \
33+
curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GOARCH}.tar.gz" | tar -C /usr/local -xzf -
34+
ENV PATH="/usr/local/go/bin:${PATH}"
35+
ENV GOPATH="/home/node/go"
36+
ENV PATH="${GOPATH}/bin:${PATH}"
37+
38+
# Build and install universal-ctags from source
39+
RUN git clone --depth 1 --branch "${CTAGS_VERSION}" https://github.com/universal-ctags/ctags.git /tmp/ctags \
40+
&& cd /tmp/ctags \
41+
&& ./autogen.sh \
42+
&& ./configure \
43+
&& make -j$(nproc) \
44+
&& make install \
45+
&& rm -rf /tmp/ctags
46+
47+
# Enable corepack for Yarn and disable download prompts
48+
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
49+
RUN corepack enable
50+
51+
# Create directories that will be mounted as volumes with correct ownership
52+
# This ensures the node user can write to them when volumes are mounted
53+
RUN mkdir -p /home/node/go /home/node/.yarn/berry/cache \
54+
&& chown -R node:node /home/node/go /home/node/.yarn
55+
56+
# Set working directory
57+
WORKDIR /workspaces/sourcebot
58+
59+
# Switch to non-root user
60+
USER node
61+
62+
# Install Claude CLI (native binary)
63+
RUN curl -fsSL https://claude.ai/install.sh | bash
64+
ENV PATH="/home/node/.claude/bin:${PATH}"

.devcontainer/devcontainer.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "Sourcebot Development",
3+
"dockerComposeFile": "docker-compose.yml",
4+
"service": "devcontainer",
5+
"workspaceFolder": "/workspaces/sourcebot",
6+
7+
"features": {
8+
"ghcr.io/devcontainers/features/git:1": {},
9+
"ghcr.io/devcontainers/features/github-cli:1": {}
10+
},
11+
12+
"forwardPorts": [3000],
13+
"portsAttributes": {
14+
"3000": { "label": "Web App", "onAutoForward": "notify" }
15+
},
16+
17+
"initializeCommand": "git submodule update --init --recursive",
18+
"postCreateCommand": "bash .devcontainer/scripts/post-create.sh",
19+
"postStartCommand": "bash .devcontainer/scripts/post-start.sh",
20+
21+
"customizations": {
22+
"vscode": {
23+
"extensions": [
24+
"dbaeumer.vscode-eslint",
25+
"bradlc.vscode-tailwindcss",
26+
"Prisma.prisma",
27+
"esbenp.prettier-vscode",
28+
"golang.go",
29+
"ms-azuretools.vscode-docker",
30+
"mikestead.dotenv",
31+
"eamodio.gitlens"
32+
],
33+
"settings": {
34+
"editor.formatOnSave": true,
35+
"editor.defaultFormatter": "esbenp.prettier-vscode",
36+
"[typescript]": {
37+
"editor.defaultFormatter": "esbenp.prettier-vscode"
38+
},
39+
"[typescriptreact]": {
40+
"editor.defaultFormatter": "esbenp.prettier-vscode"
41+
},
42+
"[prisma]": {
43+
"editor.defaultFormatter": "Prisma.prisma"
44+
}
45+
}
46+
}
47+
},
48+
49+
"remoteUser": "node"
50+
}

.devcontainer/docker-compose.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
version: '3.8'
2+
3+
services:
4+
devcontainer:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
volumes:
9+
- ..:/workspaces/sourcebot:cached
10+
- go-modules:/home/node/go
11+
- yarn-cache:/home/node/.yarn/berry/cache
12+
command: sleep infinity
13+
ports:
14+
- "3000:3000"
15+
environment:
16+
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
17+
REDIS_URL: redis://redis:6379
18+
ZOEKT_WEBSERVER_URL: http://localhost:6070
19+
CTAGS_COMMAND: ctags
20+
AUTH_SECRET: "00000000000000000000000000000000000000000000"
21+
AUTH_URL: http://localhost:3000
22+
DATA_CACHE_DIR: /workspaces/sourcebot/.sourcebot
23+
SOURCEBOT_ENCRYPTION_KEY: "00000000000000000000000000000000"
24+
NODE_ENV: development
25+
SOURCEBOT_LOG_LEVEL: debug
26+
SOURCEBOT_TELEMETRY_DISABLED: "true"
27+
REVIEW_AGENT_LOGGING_ENABLED: "true"
28+
REVIEW_AGENT_AUTO_REVIEW_ENABLED: "false"
29+
REVIEW_AGENT_REVIEW_COMMAND: review
30+
depends_on:
31+
- postgres
32+
- redis
33+
34+
postgres:
35+
image: postgres:16-alpine
36+
volumes:
37+
- postgres-data:/var/lib/postgresql/data
38+
environment:
39+
POSTGRES_DB: postgres
40+
POSTGRES_USER: postgres
41+
POSTGRES_PASSWORD: postgres
42+
restart: unless-stopped
43+
44+
redis:
45+
image: redis:7-alpine
46+
volumes:
47+
- redis-data:/data
48+
restart: unless-stopped
49+
50+
volumes:
51+
go-modules:
52+
yarn-cache:
53+
postgres-data:
54+
redis-data:
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
# post-create.sh - One-time setup after container creation
3+
set -e
4+
5+
echo "=========================================="
6+
echo "Sourcebot Dev Container: Post-Create Setup"
7+
echo "=========================================="
8+
9+
cd /workspaces/sourcebot
10+
11+
# 1. Initialize git submodules (in case initializeCommand didn't run)
12+
echo ""
13+
echo "[1/2] Initializing git submodules..."
14+
git submodule update --init --recursive
15+
16+
# 2. Build Zoekt and install dependencies (uses Makefile)
17+
echo ""
18+
echo "[2/2] Building Zoekt and installing dependencies..."
19+
make
20+
21+
echo ""
22+
echo "=========================================="
23+
echo "Post-create setup complete!"
24+
echo ""
25+
echo "To start the development server, run:"
26+
echo " yarn dev"
27+
echo ""
28+
echo "Services will be available at:"
29+
echo " - Web App: http://localhost:3000"
30+
echo " - Zoekt: http://localhost:6070"
31+
echo "=========================================="
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
# post-start.sh - Runs each time the container starts
3+
set -e
4+
5+
echo "=========================================="
6+
echo "Sourcebot Dev Container: Post-Start Check"
7+
echo "=========================================="
8+
9+
cd /workspaces/sourcebot
10+
11+
# 1. Wait for PostgreSQL to be ready
12+
echo ""
13+
echo "[1/2] Checking PostgreSQL connection..."
14+
timeout=30
15+
counter=0
16+
until pg_isready -h postgres -p 5432 -U postgres > /dev/null 2>&1; do
17+
counter=$((counter + 1))
18+
if [ $counter -ge $timeout ]; then
19+
echo "ERROR: PostgreSQL did not become ready within ${timeout} seconds"
20+
exit 1
21+
fi
22+
echo " Waiting for PostgreSQL... ($counter/$timeout)"
23+
sleep 1
24+
done
25+
echo "PostgreSQL is ready!"
26+
27+
# 2. Wait for Redis to be ready
28+
echo ""
29+
echo "[2/2] Checking Redis connection..."
30+
counter=0
31+
until redis-cli -h redis -p 6379 ping > /dev/null 2>&1; do
32+
counter=$((counter + 1))
33+
if [ $counter -ge $timeout ]; then
34+
echo "ERROR: Redis did not become ready within ${timeout} seconds"
35+
exit 1
36+
fi
37+
echo " Waiting for Redis... ($counter/$timeout)"
38+
sleep 1
39+
done
40+
echo "Redis is ready!"
41+
42+
echo ""
43+
echo "=========================================="
44+
echo "Dev container is ready!"
45+
echo ""
46+
echo "To start development, run:"
47+
echo " yarn dev"
48+
echo "=========================================="

0 commit comments

Comments
 (0)