Skip to content

Commit f93d8e0

Browse files
authored
Merge pull request #5 from co-browser/docker-publish
chore: dockerfile + github package registry action
2 parents 5e24855 + 9f102fb commit f93d8e0

File tree

4 files changed

+132
-3
lines changed

4 files changed

+132
-3
lines changed

.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
OPENAI_API_KEY=sk
1+
OPENAI_API_KEY=sk
2+
CHROME_PATH=/usr/bin/chromium

.github/workflows/ci.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ concurrency:
1212

1313
env:
1414
PYTHON_VERSION: "3.13"
15+
REGISTRY: ghcr.io
16+
IMAGE_NAME: ${{ github.repository }}
1517

1618
jobs:
1719
determine_changes:
@@ -69,3 +71,47 @@ jobs:
6971

7072
- name: "Validate project metadata"
7173
run: uvx --from 'validate-pyproject[all,store]' validate-pyproject pyproject.toml
74+
75+
build-and-publish:
76+
runs-on: ubuntu-latest
77+
78+
permissions:
79+
contents: read
80+
packages: write
81+
# attestations: write
82+
id-token: write
83+
84+
steps:
85+
- name: Checkout repository
86+
uses: actions/checkout@v4
87+
88+
- name: Log in to the Container registry
89+
uses: docker/login-action@v3
90+
with:
91+
registry: ${{ env.REGISTRY }}
92+
username: ${{ github.actor }}
93+
password: ${{ secrets.GITHUB_TOKEN }}
94+
95+
- name: Extract metadata (tags, labels) for Docker
96+
id: meta
97+
uses: docker/metadata-action@v5
98+
with:
99+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
100+
101+
- name: Set up Docker Buildx
102+
uses: docker/setup-buildx-action@v3
103+
104+
- name: Build and push Docker image
105+
id: push
106+
uses: docker/build-push-action@v6
107+
with:
108+
context: ./
109+
file: ./Dockerfile
110+
platforms: linux/amd64
111+
push: true
112+
tags: ${{ steps.meta.outputs.tags }}
113+
labels: ${{ steps.meta.outputs.labels }}
114+
build-args: |
115+
VNC_PASSWORD=${{ secrets.VNC_PASSWORD }}
116+
cache-from: type=gha
117+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
FROM ghcr.io/astral-sh/uv:bookworm-slim AS builder
2+
3+
ARG VNC_PASSWORD=browser-use
4+
5+
ENV UV_COMPILE_BYTECODE=1 \
6+
UV_LINK_MODE=copy \
7+
UV_PYTHON_INSTALL_DIR=/python \
8+
UV_PYTHON_PREFERENCE=only-managed
9+
10+
# Install build dependencies and clean up in the same layer
11+
RUN apt-get update -y && \
12+
apt-get install --no-install-recommends -y clang && \
13+
rm -rf /var/lib/apt/lists/*
14+
15+
# Install Python before the project for caching
16+
RUN uv python install 3.13
17+
18+
WORKDIR /app
19+
RUN --mount=type=cache,target=/root/.cache/uv \
20+
--mount=type=bind,source=uv.lock,target=uv.lock \
21+
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
22+
uv sync --frozen --no-install-project --no-dev
23+
ADD . /app
24+
RUN --mount=type=cache,target=/root/.cache/uv \
25+
uv sync --frozen --no-dev
26+
27+
FROM debian:bookworm-slim AS runtime
28+
29+
# Install required packages including Chromium and clean up in the same layer
30+
RUN apt-get update && \
31+
apt-get install --no-install-recommends -y \
32+
xfce4 \
33+
dbus-x11 \
34+
tigervnc-standalone-server \
35+
tigervnc-tools \
36+
nodejs \
37+
npm \
38+
chromium \
39+
chromium-driver \
40+
fonts-freefont-ttf \
41+
fonts-ipafont-gothic \
42+
fonts-wqy-zenhei \
43+
fonts-thai-tlwg \
44+
fonts-kacst \
45+
fonts-symbola \
46+
fonts-noto-color-emoji && \
47+
npm i -g proxy-login-automator && \
48+
apt-get clean && \
49+
rm -rf /var/lib/apt/lists/* && \
50+
rm -rf /var/cache/apt/*
51+
52+
# Copy only necessary files from builder
53+
COPY --from=builder --chown=python:python /python /python
54+
COPY --from=builder --chown=app:app /app /app
55+
56+
ENV PATH="/app/.venv/bin:$PATH" \
57+
DISPLAY=:0 \
58+
CHROME_BIN=/usr/bin/chromium \
59+
CHROMIUM_FLAGS="--no-sandbox --headless --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage"
60+
61+
# Combine VNC setup commands to reduce layers
62+
RUN mkdir -p ~/.vnc && \
63+
echo ${VNC_PASSWORD} | vncpasswd -f > /root/.vnc/passwd && \
64+
chmod 600 /root/.vnc/passwd && \
65+
printf '#!/bin/sh\nunset SESSION_MANAGER\nunset DBUS_SESSION_BUS_ADDRESS\nstartxfce4' > /root/.vnc/xstartup && \
66+
chmod +x /root/.vnc/xstartup && \
67+
printf '#!/bin/bash\nvncserver -depth 24 -geometry 1920x1080 -localhost no -PasswordFile /root/.vnc/passwd :0\nproxy-login-automator\npython /app/server --transport sse --port 8000' > /app/boot.sh && \
68+
chmod +x /app/boot.sh
69+
70+
ENTRYPOINT ["/bin/bash", "/app/boot.sh"]

server/server.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import os
12
import anyio
23
import click
34
import asyncio
45
import uuid
56
from datetime import datetime
67
from langchain_openai import ChatOpenAI
78
from browser_use import Agent
8-
from browser_use.browser.browser import Browser
9+
from browser_use.browser.browser import Browser, BrowserConfig
910
import mcp.types as types
1011
from mcp.server.lowlevel import Server
1112
from dotenv import load_dotenv
@@ -31,7 +32,18 @@
3132
)
3233

3334
# Initialize browser and context
34-
browser = Browser()
35+
browser = Browser(
36+
config=BrowserConfig(
37+
chrome_instance_path=os.environ.get("CHROME_PATH"),
38+
extra_chromium_args=[
39+
"--no-sandbox",
40+
"--disable-gpu",
41+
"--disable-software-rasterizer",
42+
"--disable-dev-shm-usage",
43+
"--remote-debugging-port=9222",
44+
],
45+
)
46+
)
3547
context = BrowserContext(browser=browser, config=config)
3648

3749
# Initialize LLM

0 commit comments

Comments
 (0)