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
67 changes: 67 additions & 0 deletions .github/workflows/build-code-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: build-code-server

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

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

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: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

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

- 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,scope=code-server
cache-to: type=gha,mode=max,scope=code-server
63 changes: 63 additions & 0 deletions Dockerfile.code-server
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# code-server image — VS Code in the browser for apk8s.
# Extends codercom/code-server with the agent toolchain: gh CLI, tmux,
# ripgrep, jq, and the codex + claude-code CLIs so the integrated terminal
# can run them without a separate setup step.
#
# Deployed under agents/code-server in apk8s (WOVED-35).
# Accessible at code-server.prodromou.com via CF Tunnel + Cloudflare Access.
# Identity (gh auth, git config) is wired up by the custom entrypoint from
# GH_TOKEN / GIT_USER_NAME / GIT_USER_EMAIL in the pod secret.

FROM codercom/code-server:latest

USER root

# ── gh CLI ────────────────────────────────────────────────────────────────
# renovate: datasource=github-releases depName=cli/cli
ARG GH_VERSION=v2.87.3

# ── Agent CLIs (npm) ──────────────────────────────────────────────────────
# 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 above and
# bumped by Renovate PRs, so the in-process updater would only produce a
# noisy banner and then fail (npm rename inside /usr/bin/ requires root).
ENV DISABLE_AUTOUPDATER=true

# Install system tools, gh CLI, and npm-based agent CLIs in one layer.
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
tmux ripgrep fd-find jq unzip curl; \
# fd is renamed fdfind on Debian; expose canonical name.
ln -sf /usr/bin/fdfind /usr/local/bin/fd; \
\
# gh CLI — pinned upstream binary release.
arch="$(dpkg --print-architecture)"; \
GH_VER="${GH_VERSION#v}"; \
curl -fsSL \
"https://github.com/cli/cli/releases/download/${GH_VERSION}/gh_${GH_VER}_linux_${arch}.tar.gz" \
| tar -xz -C /tmp; \
mv "/tmp/gh_${GH_VER}_linux_${arch}/bin/gh" /usr/local/bin/gh; \
rm -rf "/tmp/gh_${GH_VER}_linux_${arch}"; \
gh --version; \
\
# Agent CLIs via npm. code-server's base image ships Node.js; we
# install these as root so they land in /usr/bin/{codex,claude}.
npm install -g \
"@openai/codex@${OPENAI_CODEX_VERSION}" \
"@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}"; \
npm cache clean --force; \
\
rm -rf /var/lib/apt/lists/*

# Custom entrypoint — configures git identity + gh auth from env, then
# execs the upstream code-server binary.
COPY --chmod=0755 bin/code-server-entrypoint.sh /usr/local/bin/code-server-entrypoint.sh

USER coder

ENTRYPOINT ["/usr/local/bin/code-server-entrypoint.sh"]
32 changes: 32 additions & 0 deletions bin/code-server-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# code-server entrypoint.
#
# Runs as the `coder` user (uid 1000). On every pod start:
# 1. Wires git identity from GIT_USER_NAME / GIT_USER_EMAIL env vars.
# 2. Logs gh CLI in with GH_TOKEN (if present).
# 3. Execs the upstream code-server binary (reads ~/.config/code-server/
# config.yaml — mounted from ConfigMap with auth: none).
#
# Identity env vars come from the code-server-secret ExternalSecret in apk8s
# (backed by the `agents-code-server` 1Password item).

set -euo pipefail

# ── Git identity ────────────────────────────────────────────────────────────
if [[ -n "${GIT_USER_NAME:-}" ]]; then
git config --global user.name "${GIT_USER_NAME}"
fi
if [[ -n "${GIT_USER_EMAIL:-}" ]]; then
git config --global user.email "${GIT_USER_EMAIL}"
fi

# ── gh auth ────────────────────────────────────────────────────────────────
if [[ -n "${GH_TOKEN:-}" ]]; then
echo "${GH_TOKEN}" | gh auth login --with-token 2>/dev/null || true
fi

# ── Start code-server ───────────────────────────────────────────────────────
# Config is mounted at ~/.config/code-server/config.yaml (auth: none,
# bind-addr: 0.0.0.0:8080). Passing the workspace dir as the positional arg
# opens it as the default folder on first load.
exec /usr/bin/code-server /home/coder/workspace
Loading