-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
175 lines (155 loc) · 8.45 KB
/
Dockerfile
File metadata and controls
175 lines (155 loc) · 8.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
FROM ubuntu:24.04
LABEL org.opencontainers.image.description="AgentBox — ephemeral dev container: code-server, playwright-cli, GitHub Copilot CLI, Azure CLI"
LABEL org.opencontainers.image.source="https://github.com/networg/AgentBox"
LABEL org.opencontainers.image.version="0.1.0"
ENV DEBIAN_FRONTEND=noninteractive \
PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright \
PLAYWRIGHT_MCP_BROWSER=chromium \
LANG=C.UTF-8
# ── Base system + Node.js 22 + GitHub CLI repos ──────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
curl wget git zsh vim nano less jq ripgrep tmux \
ca-certificates gnupg lsb-release apt-transport-https \
python3 python3-pip python3-venv python-is-python3 \
sudo nginx openssh-server gettext-base \
&& mkdir -p /run/sshd \
# Node.js 22
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs \
# GitHub CLI
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] \
https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list \
&& apt-get update && apt-get install -y gh \
&& rm -rf /var/lib/apt/lists/*
# ── Azure CLI + DevOps extension ─────────────────────────────────────────────
RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash \
&& az extension add --name azure-devops --yes \
&& rm -rf /var/lib/apt/lists/*
# ── npm global tools (copilot, playwright) ───────────────────────────────────
RUN npm install -g @github/copilot @playwright/cli@latest \
&& npx playwright install chromium \
&& npx playwright install-deps chromium \
&& chmod -R o+rx /opt/ms-playwright \
&& rm -rf /var/lib/apt/lists/*
# ── ttyd (web terminal) ───────────────────────────────────────────────────────
RUN TTYD_VER="1.7.7" && \
ARCH=$(uname -m) && \
curl -fsSL "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VER}/ttyd.${ARCH}" \
-o /usr/local/bin/ttyd && chmod +x /usr/local/bin/ttyd
# ── code-server (VS Code in browser) ─────────────────────────────────────────
RUN curl -fsSL https://code-server.dev/install.sh | sh
# ── sshd config (certificate-only, no passwords) ──────────────────────────────
RUN cat >> /etc/ssh/sshd_config <<'SSHD'
Port 2222
TrustedUserCAKeys /etc/ssh/trusted_ca_keys.pub
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile none
PermitRootLogin no
AllowUsers agentbox
SSHD
# ── agentbox user ─────────────────────────────────────────────────────────────
RUN useradd -m -s /bin/zsh agentbox && \
echo 'agentbox ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
mkdir -p /home/agentbox/workspace && \
chown agentbox:agentbox /home/agentbox/workspace
# ── Oh My Zsh ─────────────────────────────────────────────────────────────────
RUN su - agentbox -c \
'sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended'
# ── Shell environment ─────────────────────────────────────────────────────────
RUN su - agentbox -c 'echo "export PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright" >> ~/.zshrc' && \
su - agentbox -c 'echo "export PLAYWRIGHT_MCP_BROWSER=chromium" >> ~/.zshrc'
# ── code-server config (no auth — security via random URL on ACI) ────────────
RUN mkdir -p /home/agentbox/.config/code-server && \
printf 'bind-addr: 127.0.0.1:8080\nauth: none\ncert: false\n' \
> /home/agentbox/.config/code-server/config.yaml && \
mkdir -p /home/agentbox/.local/share/code-server/User && \
printf '{\n "workbench.startupEditor": "none",\n "workbench.welcomePage.walkthroughs.openOnInstall": false\n}\n' \
> /home/agentbox/.local/share/code-server/User/settings.json && \
chown -R agentbox:agentbox /home/agentbox/.config /home/agentbox/.local
# ── Mobile keys toolbar for ttyd ──────────────────────────────────────────────
COPY mobile-keys.js /var/www/html/mobile-keys.js
# ── tmux config + session picker + session manager ─────────────────────────
COPY tmux.conf /home/agentbox/.tmux.conf
COPY session-picker.py /usr/local/bin/session-picker.py
COPY session-manager.py /usr/local/bin/session-manager.py
RUN chmod +x /usr/local/bin/session-picker.py /usr/local/bin/session-manager.py && \
chown agentbox:agentbox /home/agentbox/.tmux.conf && \
mkdir -p /etc/nginx/conf.d/sessions
# ── nginx reverse proxy (port 80 → code-server + ttyd) ──────────────────────
RUN printf '\
# Proxy auth: check X-AgentBox-Token header against PROXY_SECRET env var.\n\
# The $proxy_secret variable is set by envsubst in entrypoint.sh.\n\
map $http_x_agentbox_token $agentbox_auth_ok {\n\
default 0;\n\
"${proxy_secret}" 1;\n\
}\n\
\n\
server {\n\
listen 80 default_server;\n\
listen [::]:80 default_server;\n\
\n\
location = / {\n\
return 302 https://portal.agentbox.networg.com;\n\
}\n\
\n\
# Static assets (mobile toolbar JS) — no auth needed\n\
location = /mobile-keys.js {\n\
alias /var/www/html/mobile-keys.js;\n\
}\n\
\n\
# VS Code (code-server)\n\
location /editor/ {\n\
if ($agentbox_auth_ok = 0) {\n\
return 403 "Forbidden: missing or invalid proxy token";\n\
}\n\
proxy_pass http://127.0.0.1:8080/;\n\
proxy_set_header Host $host;\n\
proxy_set_header Upgrade $http_upgrade;\n\
proxy_set_header Connection upgrade;\n\
proxy_set_header Accept-Encoding gzip;\n\
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\
}\n\
\n\
# Web terminal (ttyd) — inject mobile toolbar\n\
location /terminal/ {\n\
if ($agentbox_auth_ok = 0) {\n\
return 403 "Forbidden: missing or invalid proxy token";\n\
}\n\
proxy_pass http://127.0.0.1:7681/;\n\
proxy_set_header Host $host;\n\
proxy_set_header Upgrade $http_upgrade;\n\
proxy_set_header Connection upgrade;\n\
proxy_http_version 1.1;\n\
sub_filter_types text/html;\n\
sub_filter_once off;\n\
sub_filter "</head>" "<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0,maximum-scale=1.0,interactive-widget=resizes-content\\"></head>";\n\
sub_filter "</body>" "<script src=\\"../mobile-keys.js\\"></script></body>";\n\
proxy_set_header Accept-Encoding "";\n\
}\n\
\n\
# Per-session terminal routes (generated by session-manager.py)\n\
include /etc/nginx/conf.d/sessions/*.conf;\n\
\n\
# Session manager API\n\
location /api/sessions {\n\
if ($agentbox_auth_ok = 0) {\n\
return 403 "Forbidden: missing or invalid proxy token";\n\
}\n\
proxy_pass http://127.0.0.1:8081;\n\
proxy_set_header Host $host;\n\
}\n\
}\n\
' > /etc/nginx/sites-available/default.template
# ── sp-read CLI placeholder (SharePoint document retrieval) ────────────────────
COPY tools/sp-read /usr/local/bin/sp-read
RUN chmod +x /usr/local/bin/sp-read
# 80 = nginx (code-server + ttyd), also expose raw ports for local Docker
EXPOSE 80 2222 7681 8080
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD curl -sf http://127.0.0.1:80/editor/ || exit 1
ENTRYPOINT ["/entrypoint.sh"]