feat: Dockerfile with all-in-one container

This commit is contained in:
Ken
2026-05-26 18:41:33 +00:00
parent 9103b3ecf5
commit 2838cff67c
2 changed files with 217 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
FROM python:3.13-slim
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
xvfb \
x11vnc \
websockify \
novnc \
curl \
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
libgbm1 \
libpango-1.0-0 \
libcairo2 \
libasound2 \
libxshmfence1 \
libgtk-3-0 \
fonts-liberation \
&& rm -rf /var/lib/apt/lists/*
# Install Node.js 22.x from nodesource.com
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# Install @anthropic-ai/playwright-cli globally via npm
RUN npm install -g @anthropic-ai/playwright-cli
# Install uv via pip
RUN pip install uv
# Copy backend dependency files and install Python dependencies
COPY backend/pyproject.toml backend/uv.lock /app/backend/
WORKDIR /app/backend
RUN uv sync --frozen
# Install Playwright chromium
RUN uv run playwright install chromium
# Install amplifierd
RUN uv pip install amplifierd
# Copy application files
COPY backend/*.py /app/backend/
COPY bundle/ /app/bundle/
COPY frontend/dist/ /app/frontend/dist/
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Create artifacts directory
RUN mkdir -p /app/artifacts
WORKDIR /app
EXPOSE 8080 6080
ENV DISPLAY=:99
ENV AMPLIFIERD_URL=http://localhost:8410
ENV BUNDLE_NAME=research-workbench
ENTRYPOINT ["/entrypoint.sh"]
+149
View File
@@ -0,0 +1,149 @@
#!/bin/bash
# test_dockerfile.sh - Verify Dockerfile matches spec for task-7-dockerfile
# RED: Run before Dockerfile exists (should fail)
# GREEN: Run after Dockerfile is created (should pass)
REPO=/home/ken/workspace/research-workbench
DOCKERFILE="$REPO/Dockerfile"
PASS=0
FAIL=0
check_file() {
if [ -f "$1" ]; then
echo "PASS: file '$1' exists"
((PASS++))
else
echo "FAIL: file '$1' should exist but is missing"
((FAIL++))
fi
}
check_contains() {
local pattern="$1"
local label="$2"
if grep -qF -- "$pattern" "$DOCKERFILE" 2>/dev/null; then
echo "PASS: Dockerfile contains $label"
((PASS++))
else
echo "FAIL: Dockerfile missing $label"
((FAIL++))
fi
}
check_regex() {
local pattern="$1"
local label="$2"
if grep -qE "$pattern" "$DOCKERFILE" 2>/dev/null; then
echo "PASS: Dockerfile contains $label"
((PASS++))
else
echo "FAIL: Dockerfile missing $label"
((FAIL++))
fi
}
echo "=== Checking Dockerfile exists ==="
check_file "$DOCKERFILE"
echo ""
echo "=== Checking base image ==="
check_contains "FROM python:3.13-slim" "FROM python:3.13-slim"
echo ""
echo "=== Checking system dependencies ==="
check_contains "xvfb" "xvfb"
check_contains "x11vnc" "x11vnc"
check_contains "websockify" "websockify"
check_contains "novnc" "novnc"
check_contains "curl" "curl"
check_contains "libnss3" "libnss3"
check_contains "libatk1.0-0" "libatk1.0-0"
check_contains "libatk-bridge2.0-0" "libatk-bridge2.0-0"
check_contains "libcups2" "libcups2"
check_contains "libdrm2" "libdrm2"
check_contains "libxkbcommon0" "libxkbcommon0"
check_contains "libxcomposite1" "libxcomposite1"
check_contains "libxdamage1" "libxdamage1"
check_contains "libxrandr2" "libxrandr2"
check_contains "libgbm1" "libgbm1"
check_contains "libpango-1.0-0" "libpango-1.0-0"
check_contains "libcairo2" "libcairo2"
check_contains "libasound2" "libasound2"
check_contains "libxshmfence1" "libxshmfence1"
check_contains "libgtk-3-0" "libgtk-3-0"
check_contains "fonts-liberation" "fonts-liberation"
check_contains "--no-install-recommends" "--no-install-recommends"
check_contains "rm -rf /var/lib/apt/lists/*" "rm /var/lib/apt/lists/*"
echo ""
echo "=== Checking Node.js setup ==="
check_contains "nodesource" "Node.js nodesource setup"
check_regex "22\.x" "Node.js 22.x"
check_contains "nodejs" "nodejs package"
echo ""
echo "=== Checking npm global packages ==="
check_contains "@anthropic-ai/playwright-cli" "@anthropic-ai/playwright-cli"
check_contains "npm install -g" "npm install -g"
echo ""
echo "=== Checking uv installation ==="
check_contains "pip install uv" "uv via pip"
echo ""
echo "=== Checking backend setup ==="
check_contains "COPY backend/pyproject.toml" "COPY backend/pyproject.toml"
check_contains "backend/uv.lock" "backend/uv.lock"
check_contains "/app/backend/" "destination /app/backend/"
check_contains "WORKDIR /app/backend" "WORKDIR /app/backend"
check_contains "uv sync --frozen" "uv sync --frozen"
echo ""
echo "=== Checking Playwright chromium ==="
check_contains "uv run playwright install chromium" "playwright install chromium"
echo ""
echo "=== Checking amplifierd ==="
check_contains "uv pip install amplifierd" "uv pip install amplifierd"
echo ""
echo "=== Checking COPY instructions ==="
check_regex "COPY backend/\*\.py" "COPY backend/*.py"
check_contains "COPY bundle/" "COPY bundle/"
check_contains "/app/bundle" "destination /app/bundle"
check_contains "COPY frontend/dist/" "COPY frontend/dist/"
check_contains "/app/frontend/dist" "destination /app/frontend/dist"
check_contains "COPY entrypoint.sh" "COPY entrypoint.sh"
check_contains "/entrypoint.sh" "destination /entrypoint.sh"
check_contains "chmod +x /entrypoint.sh" "chmod +x entrypoint.sh"
echo ""
echo "=== Checking /app/artifacts directory ==="
check_contains "/app/artifacts" "/app/artifacts"
echo ""
echo "=== Checking WORKDIR /app ==="
check_regex "^WORKDIR /app$" "WORKDIR /app"
echo ""
echo "=== Checking EXPOSE ports ==="
check_contains "EXPOSE 8080" "EXPOSE 8080"
check_contains "6080" "EXPOSE 6080"
echo ""
echo "=== Checking ENV variables ==="
check_contains "DISPLAY=:99" "DISPLAY=:99"
check_contains "AMPLIFIERD_URL=http://localhost:8410" "AMPLIFIERD_URL"
check_contains "BUNDLE_NAME=research-workbench" "BUNDLE_NAME"
echo ""
echo "=== Checking ENTRYPOINT ==="
check_contains "ENTRYPOINT" "ENTRYPOINT directive"
check_contains "/entrypoint.sh" "/entrypoint.sh in ENTRYPOINT"
echo ""
echo "=============================="
echo "Results: $PASS passed, $FAIL failed"
echo "=============================="
[ $FAIL -eq 0 ] && exit 0 || exit 1