@opencode-cloud/core 1.0.8 → 3.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,19 @@
16
16
  #
17
17
  # =============================================================================
18
18
 
19
+ # -----------------------------------------------------------------------------
20
+ # Version Pinning Policy
21
+ # -----------------------------------------------------------------------------
22
+ # - APT packages: Use major.minor.* wildcards for patch updates
23
+ # - GitHub tools: Pin to release tags (vX.Y.Z)
24
+ # - Cargo/Go: Pin to exact versions (@X.Y.Z)
25
+ # - Security exceptions marked with: # UNPINNED: package - reason
26
+ # - Self-managing installers (mise, rustup, etc.) trusted to handle versions
27
+ #
28
+ # To check for updates: just check-updates
29
+ # Last version audit: 2026-01-22
30
+ # -----------------------------------------------------------------------------
31
+
19
32
  # -----------------------------------------------------------------------------
20
33
  # Stage 1: Builder
21
34
  # -----------------------------------------------------------------------------
@@ -26,12 +39,13 @@ FROM ubuntu:24.04 AS builder
26
39
  ENV DEBIAN_FRONTEND=noninteractive
27
40
  ENV TZ=UTC
28
41
 
29
- # Install build essentials
42
+ # Install build essentials (2026-01-22)
30
43
  RUN apt-get update && apt-get install -y --no-install-recommends \
31
- build-essential \
44
+ build-essential=12.* \
45
+ # UNPINNED: ca-certificates - security-critical root certs, needs auto-updates
32
46
  ca-certificates \
33
- curl \
34
- git \
47
+ curl=8.5.* \
48
+ git=1:2.43.* \
35
49
  && rm -rf /var/lib/apt/lists/*
36
50
 
37
51
  # -----------------------------------------------------------------------------
@@ -59,70 +73,85 @@ ENV LC_ALL=C.UTF-8
59
73
  # -----------------------------------------------------------------------------
60
74
  # Install core system packages in logical groups for better caching
61
75
 
62
- # Group 1: Core utilities and build tools
76
+ # Group 1: Core utilities and build tools (2026-01-22)
63
77
  RUN apt-get update && apt-get install -y --no-install-recommends \
64
- # Signal handling
65
- tini \
66
- dumb-init \
78
+ # Init systems
79
+ tini=0.19.* \
80
+ dumb-init=1.2.* \
81
+ # systemd for Cockpit support
82
+ systemd=255.* \
83
+ systemd-sysv=255.* \
84
+ dbus=1.14.* \
67
85
  # Shell and terminal
68
- zsh \
69
- tmux \
86
+ zsh=5.9-* \
87
+ tmux=3.4-* \
70
88
  # Editors
71
- vim \
72
- neovim \
73
- nano \
89
+ vim=2:9.1.* \
90
+ neovim=0.9.* \
91
+ nano=7.2-* \
74
92
  # Build essentials
75
- build-essential \
76
- pkg-config \
77
- cmake \
93
+ build-essential=12.* \
94
+ pkg-config=1.8.* \
95
+ cmake=3.28.* \
78
96
  # Version control
79
- git \
80
- git-lfs \
97
+ git=1:2.43.* \
98
+ git-lfs=3.4.* \
81
99
  # Core utilities
82
- curl \
83
- wget \
100
+ curl=8.5.* \
101
+ wget=1.21.* \
102
+ # UNPINNED: ca-certificates - security-critical root certs, needs auto-updates
84
103
  ca-certificates \
104
+ # UNPINNED: gnupg - key management security, needs auto-updates
85
105
  gnupg \
86
- lsb-release \
87
- software-properties-common \
88
- sudo \
106
+ lsb-release=12.* \
107
+ software-properties-common=0.99.* \
108
+ sudo=1.9.* \
109
+ # UNPINNED: openssh-client - security-critical, needs auto-updates
89
110
  openssh-client \
90
111
  # Process/system tools
91
- htop \
92
- procps \
93
- less \
94
- file \
95
- tree \
112
+ htop=3.3.* \
113
+ procps=2:4.0.* \
114
+ less=590-* \
115
+ file=1:5.45-* \
116
+ tree=2.1.* \
96
117
  # JSON/YAML processing
97
- jq \
118
+ jq=1.7.* \
98
119
  # Network tools
99
- netcat-openbsd \
100
- iputils-ping \
101
- dnsutils \
120
+ netcat-openbsd=1.226-* \
121
+ iputils-ping=3:20240117-* \
122
+ dnsutils=1:9.18.* \
102
123
  # Compression
103
- zip \
104
- unzip \
105
- xz-utils \
106
- p7zip-full \
124
+ zip=3.0-* \
125
+ unzip=6.0-* \
126
+ xz-utils=5.6.* \
127
+ p7zip-full=16.02* \
107
128
  && rm -rf /var/lib/apt/lists/*
108
129
 
109
- # Group 2: Database clients
130
+ # Mask unnecessary systemd services for container environment
131
+ RUN systemctl mask \
132
+ dev-hugepages.mount \
133
+ sys-fs-fuse-connections.mount \
134
+ systemd-update-utmp.service \
135
+ systemd-tmpfiles-setup.service \
136
+ systemd-remount-fs.service
137
+
138
+ # Group 2: Database clients (2026-01-22)
110
139
  RUN apt-get update && apt-get install -y --no-install-recommends \
111
- sqlite3 \
112
- postgresql-client \
113
- default-mysql-client \
140
+ sqlite3=3.45.* \
141
+ postgresql-client=16+* \
142
+ default-mysql-client=1.1.* \
114
143
  && rm -rf /var/lib/apt/lists/*
115
144
 
116
- # Group 3: Development libraries (for compiling tools)
145
+ # Group 3: Development libraries for compiling tools (2026-01-22)
117
146
  RUN apt-get update && apt-get install -y --no-install-recommends \
118
- libssl-dev \
119
- libffi-dev \
120
- zlib1g-dev \
121
- libbz2-dev \
122
- libreadline-dev \
123
- libsqlite3-dev \
124
- libncurses-dev \
125
- liblzma-dev \
147
+ libssl-dev=3.0.* \
148
+ libffi-dev=3.4.* \
149
+ zlib1g-dev=1:1.3.* \
150
+ libbz2-dev=1.0.* \
151
+ libreadline-dev=8.2-* \
152
+ libsqlite3-dev=3.45.* \
153
+ libncurses-dev=6.4+* \
154
+ liblzma-dev=5.6.* \
126
155
  && rm -rf /var/lib/apt/lists/*
127
156
 
128
157
  # -----------------------------------------------------------------------------
@@ -151,31 +180,36 @@ ENV PATH="/home/opencode/.local/bin:${PATH}"
151
180
  # -----------------------------------------------------------------------------
152
181
  # Shell Setup: Zsh + Oh My Zsh + Starship
153
182
  # -----------------------------------------------------------------------------
154
- # Install Oh My Zsh
155
- RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
183
+ # Oh My Zsh - self-managing installer, trusted to handle versions
184
+ # Disabled temporarily to reduce Docker build time.
185
+ # RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
156
186
 
157
- # Install Starship prompt
158
- RUN curl -sS https://starship.rs/install.sh | sh -s -- --yes --bin-dir /home/opencode/.local/bin
187
+ # Starship prompt - self-managing installer, trusted to handle versions
188
+ # Disabled temporarily to reduce Docker build time.
189
+ # RUN curl -sS https://starship.rs/install.sh | sh -s -- --yes --bin-dir /home/opencode/.local/bin
159
190
 
160
191
  # Configure zsh with starship
161
- RUN echo 'eval "$(starship init zsh)"' >> /home/opencode/.zshrc \
162
- && echo 'export PATH="/home/opencode/.local/bin:$PATH"' >> /home/opencode/.zshrc
192
+ # Disabled temporarily to reduce Docker build time.
193
+ # RUN echo 'eval "$(starship init zsh)"' >> /home/opencode/.zshrc \
194
+ # && echo 'export PATH="/home/opencode/.local/bin:$PATH"' >> /home/opencode/.zshrc
163
195
 
164
196
  # -----------------------------------------------------------------------------
165
197
  # mise: Universal Version Manager
166
198
  # -----------------------------------------------------------------------------
167
- # Install mise for managing Node.js, Python, Rust, Go
199
+ # mise - self-managing installer, trusted to handle versions
168
200
  RUN curl https://mise.run | sh \
169
201
  && echo 'eval "$(/home/opencode/.local/bin/mise activate zsh)"' >> /home/opencode/.zshrc
170
202
 
171
- # Install language runtimes via mise
172
- # Using specific LTS/stable versions for reproducibility
203
+ # Install language runtimes via mise (2026-01-22)
204
+ # - node@lts: mise handles LTS resolution (currently 22.x)
205
+ # - python@3.12: pinned to minor version
206
+ # - go@1.24: pinned to minor version (was @latest)
173
207
  RUN /home/opencode/.local/bin/mise install node@lts \
174
208
  && /home/opencode/.local/bin/mise install python@3.12 \
175
- && /home/opencode/.local/bin/mise install go@latest \
209
+ && /home/opencode/.local/bin/mise install go@1.24 \
176
210
  && /home/opencode/.local/bin/mise use --global node@lts \
177
211
  && /home/opencode/.local/bin/mise use --global python@3.12 \
178
- && /home/opencode/.local/bin/mise use --global go@latest
212
+ && /home/opencode/.local/bin/mise use --global go@1.24
179
213
 
180
214
  # Set up mise shims in PATH for non-interactive shells
181
215
  ENV PATH="/home/opencode/.local/share/mise/shims:${PATH}"
@@ -183,7 +217,8 @@ ENV PATH="/home/opencode/.local/share/mise/shims:${PATH}"
183
217
  # -----------------------------------------------------------------------------
184
218
  # Rust Installation
185
219
  # -----------------------------------------------------------------------------
186
- # Install Rust via rustup (mise rust support is experimental)
220
+ # rustup - self-managing installer, trusted to handle versions
221
+ # Uses stable toolchain (rustup manages toolchain versioning)
187
222
  RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
188
223
  && . /home/opencode/.cargo/env \
189
224
  && rustup component add rust-analyzer rustfmt clippy
@@ -196,17 +231,17 @@ ENV PATH="/home/opencode/.cargo/bin:${PATH}"
196
231
  # Switch to bash for mise activation (mise outputs bash-specific syntax)
197
232
  SHELL ["/bin/bash", "-c"]
198
233
 
199
- # Install pnpm (corepack is included with Node.js)
234
+ # Install pnpm 10.x via corepack (2026-01-22)
200
235
  RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
201
236
  && corepack enable \
202
- && corepack prepare pnpm@latest --activate
237
+ && corepack prepare pnpm@10.28.1 --activate
203
238
 
204
239
  # Set up pnpm global bin directory
205
240
  ENV PNPM_HOME="/home/opencode/.local/share/pnpm"
206
241
  ENV PATH="${PNPM_HOME}:${PATH}"
207
242
  RUN mkdir -p "${PNPM_HOME}"
208
243
 
209
- # Install uv (fast Python package manager)
244
+ # uv - self-managing installer, trusted to handle versions (fast Python package manager)
210
245
  RUN curl -LsSf https://astral.sh/uv/install.sh | sh
211
246
 
212
247
  # Install pipx for isolated Python application installs
@@ -219,51 +254,58 @@ RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
219
254
  && pnpm add -g typescript
220
255
 
221
256
  # -----------------------------------------------------------------------------
222
- # Modern CLI Tools (Rust-based)
257
+ # Modern CLI Tools (Rust-based) - pinned versions (2026-01-22)
223
258
  # -----------------------------------------------------------------------------
224
- # Install via cargo for latest versions
259
+ # ripgrep 15.1.0 - fast regex search
260
+ # eza 0.23.4 - modern ls replacement
225
261
  RUN . /home/opencode/.cargo/env \
226
- && cargo install --locked \
227
- ripgrep \
228
- eza
262
+ && cargo install --locked ripgrep@15.1.0 eza@0.23.4
229
263
 
230
- # Install lazygit (Go-based)
231
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
232
- && go install github.com/jesseduffield/lazygit@latest
264
+ # lazygit v0.58.1 (2026-01-12) - terminal UI for git
265
+ # Disabled temporarily to reduce Docker build time.
266
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
267
+ # && go install github.com/jesseduffield/lazygit@v0.58.1
233
268
 
234
269
  # -----------------------------------------------------------------------------
235
270
  # Additional Development Tools
236
271
  # -----------------------------------------------------------------------------
237
- # Install fzf
238
- RUN git clone --depth 1 https://github.com/junegunn/fzf.git /home/opencode/.fzf \
239
- && /home/opencode/.fzf/install --all --no-bash --no-fish
272
+ # fzf v0.67.0 (2025-11-16) - fuzzy finder
273
+ # Disabled temporarily to reduce Docker build time.
274
+ # RUN git clone --branch v0.67.0 --depth 1 https://github.com/junegunn/fzf.git /home/opencode/.fzf \
275
+ # && /home/opencode/.fzf/install --all --no-bash --no-fish
240
276
 
241
- # Install yq (YAML processor)
242
- RUN curl -sL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_$(dpkg --print-architecture) -o /home/opencode/.local/bin/yq \
243
- && chmod +x /home/opencode/.local/bin/yq
277
+ # yq v4.50.1 (2025-12-14) - YAML processor
278
+ # Disabled temporarily to reduce Docker build time.
279
+ # RUN curl -sL https://github.com/mikefarah/yq/releases/download/v4.50.1/yq_linux_$(dpkg --print-architecture) -o /home/opencode/.local/bin/yq \
280
+ # && chmod +x /home/opencode/.local/bin/yq
244
281
 
245
- # Install direnv
246
- USER root
247
- RUN apt-get update && apt-get install -y --no-install-recommends direnv \
248
- && rm -rf /var/lib/apt/lists/*
249
- USER opencode
250
- RUN echo 'eval "$(direnv hook zsh)"' >> /home/opencode/.zshrc
282
+ # Install direnv (2026-01-22)
283
+ # Disabled temporarily to reduce Docker build time.
284
+ # USER root
285
+ # RUN apt-get update && apt-get install -y --no-install-recommends direnv=2.32.* \
286
+ # && rm -rf /var/lib/apt/lists/*
287
+ # USER opencode
288
+ # RUN echo 'eval "$(direnv hook zsh)"' >> /home/opencode/.zshrc
251
289
 
252
290
  # Install HTTPie
253
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
254
- && pipx install httpie
255
-
256
- # Install shellcheck and shfmt
291
+ # Disabled temporarily to reduce Docker build time.
292
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
293
+ # && pipx install httpie
294
+
295
+ # Install shellcheck (2026-01-22)
296
+ # Disabled temporarily to reduce Docker build time.
297
+ # USER root
298
+ # RUN apt-get update && apt-get install -y --no-install-recommends shellcheck=0.9.* \
299
+ # && rm -rf /var/lib/apt/lists/*
300
+ # USER opencode
301
+ # shfmt v3.12.0 (2025-07-06) - shell formatter
302
+ # Disabled temporarily to reduce Docker build time.
303
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
304
+ # && go install mvdan.cc/sh/v3/cmd/shfmt@v3.12.0
305
+
306
+ # Install btop system monitor (2026-01-22)
257
307
  USER root
258
- RUN apt-get update && apt-get install -y --no-install-recommends shellcheck \
259
- && rm -rf /var/lib/apt/lists/*
260
- USER opencode
261
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
262
- && go install mvdan.cc/sh/v3/cmd/shfmt@latest
263
-
264
- # Install btop (system monitor)
265
- USER root
266
- RUN apt-get update && apt-get install -y --no-install-recommends btop \
308
+ RUN apt-get update && apt-get install -y --no-install-recommends btop=1.3.* \
267
309
  && rm -rf /var/lib/apt/lists/*
268
310
  USER opencode
269
311
 
@@ -279,67 +321,111 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | d
279
321
  USER opencode
280
322
 
281
323
  # -----------------------------------------------------------------------------
282
- # CI/CD Tools
283
- # -----------------------------------------------------------------------------
284
- # Install act (run GitHub Actions locally)
285
- RUN curl -sL https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash -s -- -b /home/opencode/.local/bin
286
-
287
- # -----------------------------------------------------------------------------
288
- # Rust Tooling
324
+ # Cockpit Web Console (2026-01-22)
289
325
  # -----------------------------------------------------------------------------
290
- RUN . /home/opencode/.cargo/env \
291
- && cargo install --locked \
292
- cargo-nextest \
293
- cargo-audit \
294
- cargo-deny
295
-
296
- # Install mold (fast linker) via apt for easier setup
326
+ # Cockpit provides web-based administration for the container
327
+ # Ubuntu noble has cockpit 316 in main repos
297
328
  USER root
298
- RUN apt-get update && apt-get install -y --no-install-recommends mold \
329
+ RUN apt-get update && \
330
+ apt-get install -y --no-install-recommends \
331
+ cockpit-ws \
332
+ cockpit-system \
333
+ cockpit-bridge \
299
334
  && rm -rf /var/lib/apt/lists/*
300
- USER opencode
301
335
 
302
- # -----------------------------------------------------------------------------
303
- # Code Quality Tools
304
- # -----------------------------------------------------------------------------
305
- # JavaScript/TypeScript tools
306
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
307
- && pnpm add -g \
308
- prettier \
309
- eslint \
310
- @biomejs/biome
311
-
312
- # Python tools
313
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
314
- && pipx install black \
315
- && pipx install ruff
336
+ # Enable Cockpit socket activation (manual symlink since systemctl doesn't work during build)
337
+ RUN mkdir -p /etc/systemd/system/sockets.target.wants \
338
+ && ln -sf /lib/systemd/system/cockpit.socket /etc/systemd/system/sockets.target.wants/cockpit.socket
339
+
340
+ # Configure Cockpit for HTTP (TLS terminated externally) and proxy headers
341
+ RUN mkdir -p /etc/cockpit && \
342
+ printf '%s\n' \
343
+ '[WebService]' \
344
+ '# Allow HTTP connections (TLS terminated externally like opencode)' \
345
+ 'AllowUnencrypted = true' \
346
+ '' \
347
+ '# Trust proxy headers for X-Forwarded-For, X-Forwarded-Proto' \
348
+ 'ProtocolHeader = X-Forwarded-Proto' \
349
+ 'ForwardedForHeader = X-Forwarded-For' \
350
+ '' \
351
+ '# Limit concurrent login attempts' \
352
+ 'MaxStartups = 10' \
353
+ > /etc/cockpit/cockpit.conf
316
354
 
317
- # Test runners (commonly needed)
318
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
319
- && pnpm add -g jest vitest
320
-
321
- # Python pytest via pipx
322
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
323
- && pipx install pytest
355
+ USER opencode
324
356
 
325
357
  # -----------------------------------------------------------------------------
326
- # Protocol Buffers / gRPC
358
+ # CI/CD + tooling (disabled)
327
359
  # -----------------------------------------------------------------------------
328
- USER root
329
- RUN apt-get update && apt-get install -y --no-install-recommends protobuf-compiler \
330
- && rm -rf /var/lib/apt/lists/*
331
- USER opencode
332
-
333
- # Install grpcurl
334
- RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
335
- && go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
360
+ # NOTE: Commented out because this section adds significant time in GitHub Actions
361
+ # builds. We will reconsider re-adding these tools later, potentially in a more
362
+ # templated/configured Docker image optimized for build tooling.
363
+ # -----------------------------------------------------------------------------
364
+ # # CI/CD Tools
365
+ # # -----------------------------------------------------------------------------
366
+ # # act v0.2.84 (2026-01-01) - run GitHub Actions locally
367
+ # RUN curl -sL https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash -s -- -b /home/opencode/.local/bin v0.2.84
368
+ #
369
+ # # -----------------------------------------------------------------------------
370
+ # # Rust Tooling - pinned versions (2026-01-22)
371
+ # # -----------------------------------------------------------------------------
372
+ # # cargo-nextest 0.9.122 - fast test runner
373
+ # # cargo-audit 0.22.0 - security audit
374
+ # # cargo-deny 0.19.0 - dependency linter
375
+ # RUN . /home/opencode/.cargo/env \
376
+ # && cargo install --locked cargo-nextest@0.9.122 cargo-audit@0.22.0 cargo-deny@0.19.0
377
+ #
378
+ # # Install mold fast linker (2026-01-22)
379
+ # USER root
380
+ # RUN apt-get update && apt-get install -y --no-install-recommends mold=2.30.* \
381
+ # && rm -rf /var/lib/apt/lists/*
382
+ # USER opencode
383
+ #
384
+ # # -----------------------------------------------------------------------------
385
+ # # Code Quality Tools
386
+ # # -----------------------------------------------------------------------------
387
+ # # JavaScript/TypeScript tools
388
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
389
+ # && pnpm add -g \
390
+ # prettier \
391
+ # eslint \
392
+ # @biomejs/biome
393
+ #
394
+ # # Python tools
395
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
396
+ # && pipx install black \
397
+ # && pipx install ruff
398
+ #
399
+ # # Test runners (commonly needed)
400
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
401
+ # && pnpm add -g jest vitest
402
+ #
403
+ # # Python pytest via pipx
404
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
405
+ # && pipx install pytest
406
+ #
407
+ # # -----------------------------------------------------------------------------
408
+ # # Protocol Buffers / gRPC (2026-01-22)
409
+ # # -----------------------------------------------------------------------------
410
+ # USER root
411
+ # RUN apt-get update && apt-get install -y --no-install-recommends protobuf-compiler=3.21.* \
412
+ # && rm -rf /var/lib/apt/lists/*
413
+ # USER opencode
414
+ #
415
+ # # grpcurl v1.9.3 (2025-03-11) - gRPC debugging tool
416
+ # RUN eval "$(/home/opencode/.local/bin/mise activate bash)" \
417
+ # && go install github.com/fullstorydev/grpcurl/cmd/grpcurl@v1.9.3
336
418
 
337
419
  # -----------------------------------------------------------------------------
338
420
  # opencode Installation
339
421
  # -----------------------------------------------------------------------------
340
- # Install opencode using official install script
422
+ # opencode - self-managing installer, trusted to handle versions
341
423
  # The script installs to ~/.opencode/bin/
342
- RUN curl -fsSL https://opencode.ai/install | bash \
424
+ # Retry logic added because opencode.ai API can be flaky during parallel builds
425
+ RUN for i in 1 2 3 4 5; do \
426
+ curl -fsSL https://opencode.ai/install | bash && break || \
427
+ echo "Attempt $i failed, retrying in 10s..." && sleep 10; \
428
+ done \
343
429
  && ls -la /home/opencode/.opencode/bin/opencode \
344
430
  && /home/opencode/.opencode/bin/opencode --version
345
431
 
@@ -350,7 +436,38 @@ ENV PATH="/home/opencode/.opencode/bin:${PATH}"
350
436
  # GSD Plugin Installation
351
437
  # -----------------------------------------------------------------------------
352
438
  # Install the GSD (Get Shit Done) plugin for opencode
353
- RUN git clone https://github.com/rokicool/gsd-opencode.git /home/opencode/.config/opencode/plugins/gsd-opencode
439
+ # Note: If this fails in container builds due to "~" path resolution, retry with
440
+ # OPENCODE_CONFIG_DIR=/home/opencode/.config/opencode set explicitly.
441
+ RUN npx --yes get-shit-done-cc --opencode --global
442
+
443
+ # -----------------------------------------------------------------------------
444
+ # opencode systemd Service (2026-01-22)
445
+ # -----------------------------------------------------------------------------
446
+ # Create opencode as a systemd service for Cockpit integration
447
+ USER root
448
+ RUN printf '%s\n' \
449
+ '[Unit]' \
450
+ 'Description=opencode Web Interface' \
451
+ 'After=network.target' \
452
+ '' \
453
+ '[Service]' \
454
+ 'Type=simple' \
455
+ 'User=opencode' \
456
+ 'WorkingDirectory=/home/opencode/workspace' \
457
+ 'ExecStart=/home/opencode/.opencode/bin/opencode web --port 3000 --hostname 0.0.0.0' \
458
+ 'Restart=always' \
459
+ 'RestartSec=5' \
460
+ 'Environment=PATH=/home/opencode/.opencode/bin:/home/opencode/.local/bin:/home/opencode/.cargo/bin:/home/opencode/.local/share/mise/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' \
461
+ '' \
462
+ '[Install]' \
463
+ 'WantedBy=multi-user.target' \
464
+ > /etc/systemd/system/opencode.service
465
+
466
+ # Enable opencode service to start at boot (manual symlink since systemctl doesn't work during build)
467
+ RUN mkdir -p /etc/systemd/system/multi-user.target.wants \
468
+ && ln -sf /etc/systemd/system/opencode.service /etc/systemd/system/multi-user.target.wants/opencode.service
469
+
470
+ USER opencode
354
471
 
355
472
  # -----------------------------------------------------------------------------
356
473
  # Sensible Defaults Configuration
@@ -364,81 +481,110 @@ RUN git config --global init.defaultBranch main \
364
481
 
365
482
  # Starship configuration (minimal, fast prompt)
366
483
  RUN mkdir -p /home/opencode/.config \
367
- && cat > /home/opencode/.config/starship.toml << 'STARSHIP'
368
- # Minimal starship config for fast prompt
369
- format = """
370
- $directory\
371
- $git_branch\
372
- $git_status\
373
- $character"""
374
-
375
- [directory]
376
- truncation_length = 3
377
- truncate_to_repo = true
378
-
379
- [git_branch]
380
- format = "[$branch]($style) "
381
- style = "bold purple"
382
-
383
- [git_status]
384
- format = '([$all_status$ahead_behind]($style) )'
385
-
386
- [character]
387
- success_symbol = "[>](bold green)"
388
- error_symbol = "[>](bold red)"
389
- STARSHIP
484
+ && printf '%s\n' \
485
+ '# Minimal starship config for fast prompt' \
486
+ 'format = """' \
487
+ '$directory\' \
488
+ '$git_branch\' \
489
+ '$git_status\' \
490
+ '$character"""' \
491
+ '' \
492
+ '[directory]' \
493
+ 'truncation_length = 3' \
494
+ 'truncate_to_repo = true' \
495
+ '' \
496
+ '[git_branch]' \
497
+ 'format = "[$branch]($style) "' \
498
+ 'style = "bold purple"' \
499
+ '' \
500
+ '[git_status]' \
501
+ 'format = '"'"'([$all_status$ahead_behind]($style) )'"'"'' \
502
+ '' \
503
+ '[character]' \
504
+ 'success_symbol = "[>](bold green)"' \
505
+ 'error_symbol = "[>](bold red)"' \
506
+ > /home/opencode/.config/starship.toml
390
507
 
391
508
  # Shell aliases
392
- RUN cat >> /home/opencode/.zshrc << 'ALIASES'
393
-
394
- # Modern CLI aliases
395
- alias ls="eza --icons"
396
- alias ll="eza -l --icons"
397
- alias la="eza -la --icons"
398
- alias lt="eza --tree --icons"
399
- alias grep="rg"
400
- alias top="btop"
401
-
402
- # Git aliases
403
- alias g="git"
404
- alias gs="git status"
405
- alias gd="git diff"
406
- alias gc="git commit"
407
- alias gp="git push"
408
- alias gl="git pull"
409
- alias gco="git checkout"
410
- alias gb="git branch"
411
- alias lg="lazygit"
412
-
413
- # Docker aliases (for Docker-in-Docker)
414
- alias d="docker"
415
- alias dc="docker compose"
416
-
417
- ALIASES
509
+ RUN printf '%s\n' \
510
+ '' \
511
+ '# Modern CLI aliases' \
512
+ 'alias ls="eza --icons"' \
513
+ 'alias ll="eza -l --icons"' \
514
+ 'alias la="eza -la --icons"' \
515
+ 'alias lt="eza --tree --icons"' \
516
+ 'alias grep="rg"' \
517
+ 'alias top="btop"' \
518
+ '' \
519
+ '# Git aliases' \
520
+ 'alias g="git"' \
521
+ 'alias gs="git status"' \
522
+ 'alias gd="git diff"' \
523
+ 'alias gc="git commit"' \
524
+ 'alias gp="git push"' \
525
+ 'alias gl="git pull"' \
526
+ 'alias gco="git checkout"' \
527
+ 'alias gb="git branch"' \
528
+ 'alias lg="lazygit"' \
529
+ '' \
530
+ '# Docker aliases (for Docker-in-Docker)' \
531
+ 'alias d="docker"' \
532
+ 'alias dc="docker compose"' \
533
+ '' \
534
+ >> /home/opencode/.zshrc
418
535
 
419
536
  # Set up pipx path
420
537
  RUN echo 'export PATH="/home/opencode/.local/bin:$PATH"' >> /home/opencode/.zshrc
421
538
 
539
+ # -----------------------------------------------------------------------------
540
+ # Entrypoint Script (Hybrid Init Support)
541
+ # -----------------------------------------------------------------------------
542
+ # Supports both tini (default, works everywhere) and systemd (for Cockpit on Linux)
543
+ # Set USE_SYSTEMD=1 environment variable to use systemd init
544
+ # Note: Entrypoint runs as root to support both modes; tini mode drops to opencode user
545
+ USER root
546
+ RUN printf '%s\n' \
547
+ '#!/bin/bash' \
548
+ 'if [ "${USE_SYSTEMD}" = "1" ]; then' \
549
+ ' exec /sbin/init' \
550
+ 'else' \
551
+ ' # Use runuser to switch to opencode user without password prompt' \
552
+ ' exec /usr/bin/tini -- runuser -u opencode -- /home/opencode/.opencode/bin/opencode web --port 3000 --hostname 0.0.0.0' \
553
+ 'fi' \
554
+ > /usr/local/bin/entrypoint.sh && chmod +x /usr/local/bin/entrypoint.sh
555
+
556
+ # Note: Don't set USER here - entrypoint needs root to use runuser
557
+ # The tini mode drops privileges to opencode user via runuser
558
+
422
559
  # -----------------------------------------------------------------------------
423
560
  # Health Check
424
561
  # -----------------------------------------------------------------------------
425
- # Port 3000 must match OPENCODE_WEB_PORT in container.rs
426
- HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
562
+ # Check that opencode health endpoint responds
563
+ # Works for both tini and systemd modes
564
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
427
565
  CMD curl -f http://localhost:3000/health || exit 1
428
566
 
567
+ # -----------------------------------------------------------------------------
568
+ # Version File
569
+ # -----------------------------------------------------------------------------
570
+ # Store version in file for runtime access (debugging, scripts)
571
+ # Keep this near the end: changing the version invalidates the cache
572
+ # and significantly slows down docker builds if placed earlier.
573
+ USER root
574
+ ARG OPENCODE_CLOUD_VERSION=dev
575
+ LABEL org.opencode-cloud.version="${OPENCODE_CLOUD_VERSION}"
576
+ RUN echo "${OPENCODE_CLOUD_VERSION}" > /etc/opencode-cloud-version
577
+ # Note: Stay as root - entrypoint.sh needs root to run either:
578
+ # - /sbin/init (systemd mode)
579
+ # - runuser (tini mode, which then drops privileges to opencode user)
580
+
429
581
  # -----------------------------------------------------------------------------
430
582
  # Final Configuration
431
583
  # -----------------------------------------------------------------------------
432
584
  WORKDIR /home/opencode/workspace
433
585
 
434
- # Expose opencode web port (matches OPENCODE_WEB_PORT in container.rs)
435
- EXPOSE 3000
436
-
437
- # Use tini as init system for proper signal handling
438
- ENTRYPOINT ["/usr/bin/tini", "--"]
586
+ # Expose opencode web port (3000) and Cockpit port (9090)
587
+ EXPOSE 3000 9090
439
588
 
440
- # Default command: start opencode web interface
441
- # - Port 3000 must match OPENCODE_WEB_PORT in container.rs
442
- # - Using full path to ensure binary is found (opencode installs to ~/.opencode/bin/)
443
- # - --hostname 0.0.0.0 is required for Docker port mapping (default 127.0.0.1 only listens on loopback)
444
- CMD ["/home/opencode/.opencode/bin/opencode", "web", "--port", "3000", "--hostname", "0.0.0.0"]
589
+ # Hybrid init: entrypoint script chooses tini or systemd based on USE_SYSTEMD env
590
+ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]