claude-code-stack/claude-agents-ui-Dockerfile
2026-04-04 14:32:22 -04:00

92 lines
2.1 KiB
Text

FROM node:20-alpine AS builder
WORKDIR /app
# Install build dependencies
RUN apk add --no-cache git bun
# Clone the Claude Code Agents UI repository
RUN git clone --depth 1 https://github.com/Ngxba/claude-code-agents-ui.git . || true
# Install dependencies using bun or npm
RUN if [ -f bun.lockb ]; then \
bun install --frozen-lockfile; \
else \
npm install; \
fi
# Build the Nuxt application
RUN npm run build || bun run build
# Production stage
FROM node:20-alpine
WORKDIR /app
# Install runtime dependencies including Claude Code and utilities
RUN apk add --no-cache \
python3 py3-pip \
git git-lfs \
curl wget \
bash zsh \
vim nano \
build-base \
openssh-client \
ca-certificates \
tini
# Install Claude Code CLI
RUN npm install -g @anthropic-ai/claude-code
# Install Python tools for agent execution
RUN pip3 install --no-cache-dir \
requests \
python-dotenv \
pydantic \
fastapi \
uvicorn
# Copy built application from builder
COPY --from=builder /app/.output /app/.output
COPY --from=builder /app/package.json /app/package.json
COPY --from=builder /app/node_modules /app/node_modules
# Create non-root user for security
RUN addgroup -g 1000 claude && \
adduser -D -u 1000 -G claude claude
# Create necessary directories
RUN mkdir -p /workspace /root/.claude && \
chown -R claude:claude /workspace /root/.claude
# Set permissions
RUN chown -R claude:claude /app
# Create entrypoint script that starts both services
RUN cat > /entrypoint.sh << 'EOF'
#!/bin/sh
set -e
# Start Claude Code in the background if specified
if [ "$RUN_CLAUDE_CODE" = "true" ]; then
echo "Starting Claude Code daemon..."
claude serve &
CLAUDE_PID=$!
fi
# Start the Nuxt application
echo "Starting Claude Code Agents UI..."
exec node /app/.output/server/index.mjs
EOF
RUN chmod +x /entrypoint.sh
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1
EXPOSE 3000
# Use tini to handle signals properly
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/entrypoint.sh"]