Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/build-code-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: build-code-server

on:
push:
branches: [main]
tags: ["v*"]
paths:
- "Dockerfile.code-server"
- ".github/workflows/build-code-server.yml"
pull_request:
branches: [main]
paths:
- "Dockerfile.code-server"
- ".github/workflows/build-code-server.yml"

env:
# Image lives at ghcr.io/nprodromou/code-server regardless of which
# repo hosts the Dockerfile — GHCR allows cross-repo pushes.
IMAGE: ghcr.io/nprodromou/code-server

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Compute tags
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
flavor: |
latest=false
tags: |
type=raw,value=latest,enable=${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
type=ref,event=branch
type=ref,event=pr
type=sha,prefix=sha-,format=short
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.code-server
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
74 changes: 74 additions & 0 deletions Dockerfile.code-server
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# code-server — VS Code in the browser for apk8s.
#
# Thin overlay on upstream codercom/code-server that adds gh (GitHub CLI),
# tmux, Node.js on the system PATH, and the codex/claude agent CLIs so they
# are available in the integrated terminal.
#
# Authentication is delegated to Cloudflare Access (WARP). code-server itself
# runs with auth: none (config.yaml mounted from the k8s ConfigMap). The only
# network path in is through the CF tunnel.
#
# The upstream image runs as uid/gid 1000 (user: coder). Keep that — the data
# and workspace PVCs must not change ownership across rebuilds.
#
# Deployed via apk8s HelmRelease at kubernetes/apps/agents/code-server/.

# renovate: datasource=docker depName=codercom/code-server
ARG CODE_SERVER_VERSION=4.100.3

FROM codercom/code-server:${CODE_SERVER_VERSION}

ARG NODE_VERSION=22
# renovate: datasource=github-releases depName=cli/cli extractVersion=^v(?P<version>.+)$
ARG GH_VERSION=2.87.3
# renovate: datasource=npm depName=@openai/codex
ARG OPENAI_CODEX_VERSION=0.130.0
# renovate: datasource=npm depName=@anthropic-ai/claude-code
ARG CLAUDE_CODE_VERSION=2.1.139

# Disable Claude Code's runtime auto-updater — version is pinned via ARG.
ENV DISABLE_AUTOUPDATER=true

USER root

# System packages: tmux.
# curl and git are already present in the upstream image.
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends tmux; \
rm -rf /var/lib/apt/lists/*

# GitHub CLI — pinned binary release (not the apt repo, to match the version
# pin pattern used in the rest of the codex-shell toolchain).
RUN set -eux; \
arch="$(dpkg --print-architecture)"; \
curl -fsSL \
"https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${arch}.tar.gz" \
| tar -xz -C /tmp; \
mv "/tmp/gh_${GH_VERSION}_linux_${arch}/bin/gh" /usr/local/bin/gh; \
rm -rf "/tmp/gh_${GH_VERSION}_linux_${arch}"; \
gh --version | head -1

# Node.js — the upstream image ships node internally (/usr/lib/code-server/lib/node)
# but that binary is not on the system PATH for integrated terminal users.
# Install Node.js via NodeSource so `node`, `npm`, and agent CLIs are available.
RUN set -eux; \
curl -fsSL "https://deb.nodesource.com/setup_${NODE_VERSION}.x" | bash -; \
apt-get install -y --no-install-recommends nodejs; \
rm -rf /var/lib/apt/lists/*; \
node --version; npm --version

# Agent CLIs: codex (OpenAI) and claude (Anthropic).
# Installed as root (writes to /usr/lib/node_modules); chown the scope
# directories so the coder user (uid/gid 1000) can run them without EACCES.
RUN set -eux; \
npm install -g \
"@openai/codex@${OPENAI_CODEX_VERSION}" \
"@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}"; \
npm cache clean --force; \
chown -R 1000:1000 /usr/lib/node_modules/@openai; \
chown -h 1000:1000 /usr/bin/codex; \
chown -R 1000:1000 /usr/lib/node_modules/@anthropic-ai; \
chown -h 1000:1000 /usr/bin/claude

USER coder
Loading