feat: Dockerfile with all-in-one container
This commit is contained in:
+68
@@ -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"]
|
||||||
Executable
+149
@@ -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
|
||||||
Reference in New Issue
Block a user