Repository navigation
Expand file tree
/
Copy pathDockerfile.base
More file actions
515 lines (471 loc) · 22.3 KB
/
Copy pathDockerfile.base
File metadata and controls
515 lines (471 loc) · 22.3 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
# Devcontainer image for codegeist.ai
#
# Why this exists:
# - Matches the planner devcontainer toolchain for product work.
# - Keeps Docker available inside the container via the custom entrypoint and
# installs Podman as an additional daemonless container engine.
# - Installs the Java 25 and GraalVM toolchain needed by `app/codegeist`.
# - Provides a system Maven installation so the app does not need a wrapper.
# - Adds the Nix package manager for later package migration work without
# switching the devcontainer setup to flakes yet.
# - Includes JBang, Hugo, Kubernetes, Terraform, OpenTofu, Vault, Ansible,
# PowerShell, QEMU/KVM, password-store, speech, YAML, UUID generation, tmux, terminal
# productivity and capture, network, security-scan, and FTP tools so the
# shared workspace can handle Java scripting, site, infrastructure,
# virtualization, deployment, docs previews, and external scan tasks.
# - Installs the Codegeist CLI through the upstream Linux installer from the
# codegeist repository's main branch.
# - `scripts/release-build.sh` copies this source file to release `Dockerfile` so
# consuming repositories still receive the standard Dev Containers filename.
# - `initialize.sh` copies the released `Dockerfile` into `Dockerfile.merged.gen`
# and appends an optional `.codegeist/Dockerfile` fragment before Compose
# builds.
#
# Inputs:
# - CONTAINER_USER and CONTAINER_GROUP select the login user created in the image.
# - CONTAINER_UID and CONTAINER_GID default to 1000 and can be aligned later by the
# devcontainer runtime.
# - VHS_VERSION and TTYD_VERSION select terminal-rendering tools used by
# documentation capture workflows in consuming repositories.
# - TEA_VERSION pins the official Gitea CLI binary installed from dl.gitea.com.
# - BITWARDEN_CLI_VERSION and BITWARDEN_CLI_SHA256 pin and verify the official
# native Linux x64 Bitwarden CLI archive.
# - DOCKER_CREDENTIAL_PASS_VERSION and DOCKER_CREDENTIAL_PASS_SHA256 pin and
# verify the pass-backed Docker registry credential helper.
# - TRIVY_VERSION pins the official Trivy security scanner release.
# - GITLEAKS_VERSION and GITLEAKS_SHA256 pin and verify the official Gitleaks
# secret-scanner release.
# - WHISPER_CPP_VERSION and WHISPER_CPP_SHA256 pin and verify the CPU-only
# transcription CLI used by `cmds/oc-record`; its model is downloaded at
# runtime and is not part of the image.
#
# Related files:
# - cmds/
# - docker-compose.yml
# - devcontainer.json
# - entrypoint.sh
# - initialize.sh
# - scripts/release-build.sh
FROM ubuntu:26.04
ARG CONTAINER_USER=vscode
ARG CONTAINER_GROUP=vscode
ARG CONTAINER_UID=1000
ARG CONTAINER_GID=1000
ARG GRAALVM_VERSION=25.0.2
ARG HUGO_VERSION=0.147.9
ARG VHS_VERSION=0.11.0
ARG TTYD_VERSION=1.7.7
ARG TEA_VERSION=0.14.2
ARG BITWARDEN_CLI_VERSION=2026.8.0
ARG BITWARDEN_CLI_SHA256=367f618e9fcccaac4980ec12c7bafd01df739b5f3cb1af31bc9045cf75eea1d6
ARG DOCKER_CREDENTIAL_PASS_VERSION=0.9.9
ARG DOCKER_CREDENTIAL_PASS_SHA256=ae80a143101672b53c65cd5aa05028897068d39e2649adff83a520ef3218355d
ARG TRIVY_VERSION=0.74.0
ARG GITLEAKS_VERSION=8.30.1
ARG GITLEAKS_SHA256=551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb
ARG WHISPER_CPP_VERSION=1.9.4
ARG WHISPER_CPP_SHA256=57e280cee375ab02425b806ad5146b99f6eb9357e3c2b31357c8a6af2e2e44ae
ARG POWERSHELL_VERSION=7.6.6
ENV LANG=C.UTF-8 \
LC_CTYPE=C.UTF-8 \
CONTAINER_USER=${CONTAINER_USER} \
CONTAINER_GROUP=${CONTAINER_GROUP} \
CONTAINER_UID=${CONTAINER_UID} \
CONTAINER_GID=${CONTAINER_GID} \
JAVA_HOME=/opt/graalvm \
GRAALVM_HOME=/opt/graalvm \
PATH=/opt/nvim/bin:/opt/graalvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Install only the minimum needed to register third-party APT repos.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gnupg \
wget \
&& rm -rf /var/lib/apt/lists/*
# Register all extra APT repos before the main install step.
RUN install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& chmod a+r /etc/apt/keyrings/nodesource.gpg \
&& printf 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_24.x nodistro main\n' \
> /etc/apt/sources.list.d/nodesource.list \
&& wget -qO- https://apt.fury.io/nushell/gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/fury-nushell.gpg \
&& chmod a+r /etc/apt/keyrings/fury-nushell.gpg \
&& printf 'deb [signed-by=/etc/apt/keyrings/fury-nushell.gpg] https://apt.fury.io/nushell/ /\n' \
> /etc/apt/sources.list.d/fury-nushell.list \
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc \
&& chmod a+r /etc/apt/keyrings/docker.asc \
&& printf 'Types: deb\nURIs: https://download.docker.com/linux/ubuntu\nSuites: %s\nComponents: stable\nSigned-By: /etc/apt/keyrings/docker.asc\n' \
'resolute' > /etc/apt/sources.list.d/docker.sources \
&& curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
| gpg --dearmor -o /etc/apt/keyrings/microsoft.gpg \
&& chmod a+r /etc/apt/keyrings/microsoft.gpg \
&& printf 'Types: deb\nURIs: https://packages.microsoft.com/repos/code\nSuites: stable\nComponents: main\nSigned-By: /etc/apt/keyrings/microsoft.gpg\n' \
> /etc/apt/sources.list.d/vscode.sources \
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
-o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& chmod a+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& printf 'Types: deb\nURIs: https://cli.github.com/packages\nSuites: stable\nComponents: main\nArchitectures: amd64\nSigned-By: /etc/apt/keyrings/githubcli-archive-keyring.gpg\n' \
> /etc/apt/sources.list.d/github-cli.sources \
&& curl -fsSL https://apt.releases.hashicorp.com/gpg \
| gpg --dearmor -o /etc/apt/keyrings/hashicorp-archive-keyring.gpg \
&& chmod a+r /etc/apt/keyrings/hashicorp-archive-keyring.gpg \
&& printf 'Types: deb\nURIs: https://apt.releases.hashicorp.com\nSuites: %s\nComponents: main\nSigned-By: /etc/apt/keyrings/hashicorp-archive-keyring.gpg\n' \
'resolute' > /etc/apt/sources.list.d/hashicorp.sources \
&& curl -fsSL https://get.opentofu.org/opentofu.gpg \
-o /etc/apt/keyrings/opentofu.gpg \
&& curl -fsSL https://packages.opentofu.org/opentofu/tofu/gpgkey \
| gpg --no-tty --batch --dearmor -o /etc/apt/keyrings/opentofu-repo.gpg \
&& chmod a+r /etc/apt/keyrings/opentofu.gpg /etc/apt/keyrings/opentofu-repo.gpg \
&& printf 'deb [signed-by=/etc/apt/keyrings/opentofu.gpg,/etc/apt/keyrings/opentofu-repo.gpg] https://packages.opentofu.org/opentofu/tofu/any/ any main\n' \
> /etc/apt/sources.list.d/opentofu.list \
&& chmod a+r /etc/apt/sources.list.d/opentofu.list
# Install the shared development toolchain in one APT transaction. Vault's
# package grants IPC_LOCK for server mlock support; remove it because this image
# provides the CLI and file capabilities block execution in unprivileged containers.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
ansible \
bash \
bash-completion \
ca-certificates \
code \
containerd.io \
curl \
direnv \
docker-buildx-plugin \
docker-ce \
docker-ce-cli \
docker-compose-plugin \
espeak-ng \
ffmpeg \
ftp \
fuse-overlayfs \
gh \
git \
golang-go \
jq \
lftp \
gnupg \
bridge-utils \
cloud-image-utils \
cmake \
cpio \
dnsmasq \
expect \
hping3 \
iproute2 \
iputils-ping \
iptables \
kmod \
netcat-openbsd \
nmap \
maven \
nodejs \
nushell \
openssh-client \
pass \
passt \
podman \
procps \
pwgen \
python3 \
python3-dev \
python3-pip \
qemu-system-x86 \
qemu-utils \
rsync \
slirp4netns \
sslscan \
sshpass \
socat \
sudo \
terraform \
testssl.sh \
tigervnc-viewer \
tmux \
tofu \
vault \
unzip \
uidmap \
uuid-runtime \
wget \
x11-apps \
x11-utils \
xauth \
xvfb \
xz-utils \
zlib1g-dev \
&& setcap -r /usr/bin/vault \
&& rm -rf /var/lib/apt/lists/*
# Ubuntu 26.04 is supported by PowerShell, but its Microsoft product feed does
# not publish PowerShell. Install Microsoft's supported universal package.
RUN curl -fsSL \
"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/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell_${POWERSHELL_VERSION}-1.deb_amd64.deb" \
-o /tmp/powershell.deb \
&& apt-get update \
&& apt-get install -y --no-install-recommends /tmp/powershell.deb \
&& rm -f /tmp/powershell.deb \
&& rm -rf /var/lib/apt/lists/* \
&& pwsh -NoLogo -NoProfile -Command 'exit 0'
RUN curl -LsSf https://astral.sh/uv/install.sh \
| env UV_UNMANAGED_INSTALL=/usr/local/bin sh
RUN npm install -g --prefix /usr/local opencode-ai renovate repomix @ast-grep/cli @devcontainers/cli @mermaid-js/mermaid-cli tiktoken-cli \
&& rm -f /usr/local/bin/sg \
&& rm -rf /tmp/opencode \
&& npm cache clean --force
RUN python3 -m pip install --break-system-packages --no-cache-dir \
ddgr \
graphifyy \
lxml_html_clean \
ssh-audit==3.9.0 \
trafilatura
# Build only the portable CPU transcription CLI. The multilingual model remains
# a runtime download under /tmp so image builds do not carry its 488 MB payload.
RUN curl -fsSL "https://codeload.github.com/ggml-org/whisper.cpp/tar.gz/refs/tags/v${WHISPER_CPP_VERSION}" \
-o /tmp/whisper.cpp.tar.gz \
&& printf '%s %s\n' "$WHISPER_CPP_SHA256" /tmp/whisper.cpp.tar.gz | sha256sum -c - \
&& install -d -m 0755 /tmp/whisper.cpp /tmp/whisper.cpp-build \
&& tar -xzf /tmp/whisper.cpp.tar.gz --strip-components=1 -C /tmp/whisper.cpp \
&& cmake -S /tmp/whisper.cpp -B /tmp/whisper.cpp-build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DGGML_NATIVE=OFF \
-DWHISPER_BUILD_IS_DEV=OFF \
-DWHISPER_BUILD_SERVER=OFF \
-DWHISPER_BUILD_TESTS=OFF \
&& cmake --build /tmp/whisper.cpp-build --target whisper-cli -j "$(nproc)" \
&& install -m 0755 /tmp/whisper.cpp-build/bin/whisper-cli /usr/local/bin/whisper-cli \
&& whisper-cli --version \
&& rm -rf /tmp/whisper.cpp.tar.gz /tmp/whisper.cpp /tmp/whisper.cpp-build
RUN curl -fsSL "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/boyter/scc/releases/latest/download/scc_Linux_x86_64.tar.gz" \
-o /tmp/scc.tar.gz \
&& tar -xzf /tmp/scc.tar.gz -C /usr/local/bin scc \
&& chmod +x /usr/local/bin/scc \
&& rm -f /tmp/scc.tar.gz
# Install the latest official Linux x86_64 terminal tools without aliases or
# user configuration. Versioned assets derive their tag from GitHub's normal
# release redirect instead of consuming the shared unauthenticated API limit;
# stable asset names use releases/latest/download directly.
RUN curl -fsSL "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/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz" \
-o /tmp/nvim.tar.gz \
&& install -d -m 0755 /opt/nvim \
&& tar -xzf /tmp/nvim.tar.gz --strip-components=1 -C /opt/nvim \
&& rm -f /tmp/nvim.tar.gz
RUN gum_tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/charmbracelet/gum/releases/latest)" \
&& gum_tag="${gum_tag##*/}" \
&& gum_version="${gum_tag#v}" \
&& curl -fsSL "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/charmbracelet/gum/releases/download/${gum_tag}/gum_${gum_version}_Linux_x86_64.tar.gz" \
-o /tmp/gum.tar.gz \
&& tar -xzf /tmp/gum.tar.gz --wildcards --strip-components=1 \
-C /usr/local/bin '*/gum' \
&& rm -f /tmp/gum.tar.gz
RUN rg_tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/BurntSushi/ripgrep/releases/latest)" \
&& rg_tag="${rg_tag##*/}" \
&& curl -fsSL "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/BurntSushi/ripgrep/releases/download/${rg_tag}/ripgrep-${rg_tag}-x86_64-unknown-linux-musl.tar.gz" \
-o /tmp/rg.tar.gz \
&& tar -xzf /tmp/rg.tar.gz --wildcards --strip-components=1 \
-C /usr/local/bin '*/rg' \
&& rm -f /tmp/rg.tar.gz
RUN bat_tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/sharkdp/bat/releases/latest)" \
&& bat_tag="${bat_tag##*/}" \
&& curl -fsSL "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/sharkdp/bat/releases/download/${bat_tag}/bat-${bat_tag}-x86_64-unknown-linux-gnu.tar.gz" \
-o /tmp/bat.tar.gz \
&& tar -xzf /tmp/bat.tar.gz --wildcards --strip-components=1 \
-C /usr/local/bin '*/bat' \
&& rm -f /tmp/bat.tar.gz
RUN curl -fsSL "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/aristocratos/btop/releases/latest/download/btop-x86_64-unknown-linux-musl.tar.gz" \
-o /tmp/btop.tar.gz \
&& tar -xzf /tmp/btop.tar.gz --strip-components=3 \
-C /usr/local/bin ./btop/bin/btop \
&& rm -f /tmp/btop.tar.gz
RUN curl -fsSL "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/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz" \
-o /tmp/eza.tar.gz \
&& tar -xzf /tmp/eza.tar.gz -C /usr/local/bin ./eza \
&& rm -f /tmp/eza.tar.gz
RUN dust_tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/bootandy/dust/releases/latest)" \
&& dust_tag="${dust_tag##*/}" \
&& curl -fsSL "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/bootandy/dust/releases/download/${dust_tag}/dust-${dust_tag}-x86_64-unknown-linux-gnu.tar.gz" \
-o /tmp/dust.tar.gz \
&& tar -xzf /tmp/dust.tar.gz --wildcards --strip-components=1 \
-C /usr/local/bin '*/dust' \
&& rm -f /tmp/dust.tar.gz
RUN fzf_tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/junegunn/fzf/releases/latest)" \
&& fzf_tag="${fzf_tag##*/}" \
&& fzf_version="${fzf_tag#v}" \
&& curl -fsSL "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/junegunn/fzf/releases/download/${fzf_tag}/fzf-${fzf_version}-linux_amd64.tar.gz" \
-o /tmp/fzf.tar.gz \
&& tar -xzf /tmp/fzf.tar.gz -C /usr/local/bin fzf \
&& rm -f /tmp/fzf.tar.gz
RUN lazygit_tag="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/jesseduffield/lazygit/releases/latest)" \
&& lazygit_tag="${lazygit_tag##*/}" \
&& lazygit_version="${lazygit_tag#v}" \
&& curl -fsSL "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/jesseduffield/lazygit/releases/download/${lazygit_tag}/lazygit_${lazygit_version}_Linux_x86_64.tar.gz" \
-o /tmp/lazygit.tar.gz \
&& tar -xzf /tmp/lazygit.tar.gz -C /usr/local/bin lazygit \
&& chmod +x /usr/local/bin/lazygit \
&& rm -f /tmp/lazygit.tar.gz
RUN docker_credential_pass_asset="docker-credential-pass-v${DOCKER_CREDENTIAL_PASS_VERSION}.linux-amd64" \
&& curl -fsSL \
"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/docker/docker-credential-helpers/releases/download/v${DOCKER_CREDENTIAL_PASS_VERSION}/${docker_credential_pass_asset}" \
-o "/tmp/${docker_credential_pass_asset}" \
&& printf '%s %s\n' "$DOCKER_CREDENTIAL_PASS_SHA256" "/tmp/${docker_credential_pass_asset}" \
| sha256sum -c - \
&& install -m 0755 "/tmp/${docker_credential_pass_asset}" /usr/local/bin/docker-credential-pass \
&& rm -f "/tmp/${docker_credential_pass_asset}" \
&& docker-credential-pass version
RUN bitwarden_cli_archive="bw-linux-${BITWARDEN_CLI_VERSION}.zip" \
&& curl -fsSL \
"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/bitwarden/clients/releases/download/cli-v${BITWARDEN_CLI_VERSION}/${bitwarden_cli_archive}" \
-o "/tmp/${bitwarden_cli_archive}" \
&& printf '%s %s\n' "$BITWARDEN_CLI_SHA256" "/tmp/${bitwarden_cli_archive}" \
| sha256sum -c - \
&& unzip -q "/tmp/${bitwarden_cli_archive}" -d /tmp/bitwarden-cli \
&& install -m 0755 /tmp/bitwarden-cli/bw /usr/local/bin/bw \
&& rm -rf "/tmp/${bitwarden_cli_archive}" /tmp/bitwarden-cli \
&& install -d -m 0700 /tmp/bitwarden-cli-appdata \
&& printf '%s\n' '{}' > /tmp/bitwarden-cli-appdata/data.json \
&& BITWARDENCLI_APPDATA_DIR=/tmp/bitwarden-cli-appdata bw --version \
&& rm -rf /tmp/bitwarden-cli-appdata
RUN tea_asset="tea-${TEA_VERSION}-linux-amd64" \
&& curl -fsSL "https://dl.gitea.com/tea/${TEA_VERSION}/${tea_asset}" \
-o "/tmp/${tea_asset}" \
&& install -m 0755 "/tmp/${tea_asset}" /usr/local/bin/tea \
&& rm -f "/tmp/${tea_asset}" \
&& tea --version
RUN curl -fsSL "https://raw.githubusercontent.com/aquasecurity/trivy/v${TRIVY_VERSION}/contrib/install.sh" \
| sh -s -- -b /usr/local/bin "v${TRIVY_VERSION}" \
&& trivy --version
RUN curl -fsSL "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/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
-o /tmp/gitleaks.tar.gz \
&& printf '%s %s\n' "$GITLEAKS_SHA256" /tmp/gitleaks.tar.gz | sha256sum -c - \
&& tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks \
&& install -m 0755 /tmp/gitleaks /usr/local/bin/gitleaks \
&& rm -f /tmp/gitleaks.tar.gz /tmp/gitleaks \
&& gitleaks version
RUN curl -fsSL "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/go-task/task/releases/latest/download/task_linux_amd64.tar.gz" \
-o /tmp/task.tar.gz \
&& tar -xzf /tmp/task.tar.gz -C /usr/local/bin task \
&& chmod +x /usr/local/bin/task \
&& task --completion bash > /usr/share/bash-completion/completions/task \
&& rm -f /tmp/task.tar.gz
RUN curl -fsSL "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/charmbracelet/vhs/releases/download/v${VHS_VERSION}/vhs_${VHS_VERSION}_amd64.deb" \
-o /tmp/vhs.deb \
&& dpkg -i /tmp/vhs.deb \
&& rm -f /tmp/vhs.deb \
&& vhs --version \
&& curl -fsSL "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/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \
-o /usr/local/bin/ttyd \
&& chmod +x /usr/local/bin/ttyd \
&& ttyd --version
RUN curl -fsSL https://raw.githubusercontent.com/codegeist-ai/codegeist/main/scripts/install/codegeist-install-linux.sh \
| env CODEGEIST_INSTALL_DIR=/opt/codegeist CODEGEIST_BIN_DIR=/usr/local/bin bash \
&& codegeist --version
RUN curl -fsSL "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/mikefarah/yq/releases/latest/download/yq_linux_amd64" \
-o /usr/local/bin/yq \
&& chmod +x /usr/local/bin/yq \
&& yq --version \
&& curl -fsSL "https://dl.k8s.io/release/$(curl -fsSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
-o /usr/local/bin/kubectl \
&& chmod +x /usr/local/bin/kubectl \
&& kubectl version --client=true \
&& curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 \
| bash \
&& helm version \
&& curl -fsSL "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/derailed/k9s/releases/latest/download/k9s_linux_amd64.deb" \
-o /tmp/k9s_linux_amd64.deb \
&& apt-get update \
&& apt-get install -y --no-install-recommends /tmp/k9s_linux_amd64.deb \
&& rm -f /tmp/k9s_linux_amd64.deb \
&& rm -rf /var/lib/apt/lists/* \
&& k9s version \
&& curl -fsSL https://talos.dev/install | sh \
&& talosctl version --client
RUN curl -fsSL "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/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz" \
-o /tmp/hugo.tar.gz \
&& tar -xzf /tmp/hugo.tar.gz -C /tmp hugo \
&& install -m 0755 /tmp/hugo /usr/local/bin/hugo \
&& hugo version \
&& rm -f /tmp/hugo.tar.gz /tmp/hugo
RUN curl -fsSL "https://dl.google.com/linux/direct/google-chrome-stable_current_$(dpkg --print-architecture).deb" \
-o /tmp/chrome.deb \
&& apt-get update \
&& apt-get install -y --no-install-recommends /tmp/chrome.deb \
&& rm -f /tmp/chrome.deb \
&& rm -rf /var/lib/apt/lists/* \
&& google-chrome --version
RUN install -d -m 0755 /etc/opt/chrome/policies/managed \
&& printf '%s\n' \
'{' \
' "HardwareAccelerationModeEnabled": false' \
'}' \
> /etc/opt/chrome/policies/managed/disable-hardware-accel.json
RUN curl -fsSL "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/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_linux-x64_bin.tar.gz" \
-o /tmp/graalvm.tar.gz \
&& install -d -m 0755 /opt/graalvm \
&& tar -xzf /tmp/graalvm.tar.gz --strip-components=1 -C /opt/graalvm \
&& /opt/graalvm/bin/java -version \
&& /opt/graalvm/bin/native-image --version \
&& rm -f /tmp/graalvm.tar.gz
RUN curl -Ls https://sh.jbang.dev \
| env JBANG_DIR=/opt/jbang bash -s - app setup \
&& ln -sf /opt/jbang/bin/jbang /usr/local/bin/jbang \
&& jbang --version
RUN userdel --remove ubuntu \
&& groupadd --gid "$CONTAINER_GID" "$CONTAINER_GROUP" \
&& useradd --uid "$CONTAINER_UID" --gid "$CONTAINER_GID" --create-home --shell /bin/bash "$CONTAINER_USER" \
&& install -d -m 0755 /data/Projects \
&& install -d -m 0755 /host \
&& install -d -m 0755 /nix \
&& install -d -m 1777 /tmp/ws-data \
&& ln -s /host/run/docker.sock /var/run/host-docker.sock \
&& install -d -m 0755 "/home/$CONTAINER_USER/.config/opencode" \
&& install -d -m 0755 "/home/$CONTAINER_USER/.m2" \
&& install -d -m 0755 "/home/$CONTAINER_USER/.local/share" \
&& install -d -m 0755 "/home/$CONTAINER_USER/.local/state/opencode" \
&& install -o "$CONTAINER_UID" -g "$CONTAINER_GID" -m 0600 /dev/null "/home/$CONTAINER_USER/.Xauthority" \
&& chown -R "$CONTAINER_UID:$CONTAINER_GID" /nix \
"/home/$CONTAINER_USER/.config" \
"/home/$CONTAINER_USER/.m2" \
"/home/$CONTAINER_USER/.local" \
&& echo "$CONTAINER_USER ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/$CONTAINER_USER" \
&& chmod 0440 "/etc/sudoers.d/$CONTAINER_USER"
# Install Nix for the normal workspace user without enabling flakes or replacing
# the existing apt-managed toolchain yet.
RUN su - "$CONTAINER_USER" -c 'curl -L https://nixos.org/nix/install | sh -s -- --no-daemon --no-modify-profile'
# Make login shells pick up the single-user Nix profile and Neovim as well. The
# plain PATH env is not enough because login shells reset Ubuntu's default PATH.
RUN printf '%s\n' \
'if [ -e "/home/'"$CONTAINER_USER"'/.nix-profile/etc/profile.d/nix.sh" ]; then' \
' . "/home/'"$CONTAINER_USER"'/.nix-profile/etc/profile.d/nix.sh"' \
'fi' \
'PATH="/opt/nvim/bin:$PATH"' \
'export PATH' \
> /etc/profile.d/nix.sh
# Make workspace-owned devcontainer scripts directly callable in interactive
# shells. `DEVCONTAINER_WORKSPACE_FOLDER` is runtime state, so this cannot be a
# plain Dockerfile `ENV PATH=...` expansion.
RUN printf '%s\n' \
'PATH="$DEVCONTAINER_WORKSPACE_FOLDER/.devcontainer/scripts:$PATH"' \
'export PATH' \
> /etc/profile.d/codegeist-workspace-scripts.sh
COPY --chmod=0755 .devcontainer/cmds/ /usr/local/bin/
COPY .devcontainer/entrypoint.sh /usr/local/bin/devcontainer-entrypoint
RUN chmod +x /usr/local/bin/devcontainer-entrypoint
ENV USER=${CONTAINER_USER}
ENV HOME=/home/${CONTAINER_USER}
ENV NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
ENV PATH=/home/${CONTAINER_USER}/.nix-profile/bin:/nix/var/nix/profiles/default/bin:${PATH}
VOLUME ["/var/lib/docker"]
ENTRYPOINT ["/usr/local/bin/devcontainer-entrypoint"]
USER ${CONTAINER_USER}