Skip to content
Merged
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
45 changes: 45 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,48 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.agent }}
cache-to: type=gha,mode=max,scope=${{ matrix.agent }}

build-code-server:
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: ./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
71 changes: 71 additions & 0 deletions code-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# code-server image — VS Code in the browser for apk8s.
#
# Extends the upstream codercom/code-server with:
# - gh CLI for GitHub operations from the integrated terminal
# - tmux for persistent terminal sessions
# - claude (Claude Code) and codex for integrated AI assistance
# - entrypoint that configures git identity + gh auth from env vars on boot
#
# Deployed at code-server.prodromou.com via WARP private routing
# (envoy-internal gateway, WOVED-35).
#
# Authentication is handled at the edge by WARP/Cloudflare Access;
# code-server itself runs with --auth none inside the cluster.
#
# Build (from repo root):
# docker build -t ghcr.io/nprodromou/codex-shell:code-server-dev \
# -f code-server/Dockerfile code-server/

FROM codercom/code-server:latest

USER root

# tmux for persistent terminal sessions.
# git and curl are already present in the upstream image.
RUN apt-get update && apt-get install -y --no-install-recommends \
tmux \
&& rm -rf /var/lib/apt/lists/*

# gh CLI — pinned for reproducibility, bump in lockstep with codex-shell Dockerfile.
# renovate: datasource=github-releases depName=cli/cli extractVersion=^v(?<version>.+)$
ARG GH_VERSION=2.87.3
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 — required for npm / claude-code.
# codercom/code-server bundles its own Node.js for the IDE but does not
# expose npm on PATH. Install a system-level LTS Node.js so the integrated
# terminal can use npm/npx like any dev machine.
# renovate: datasource=node-version depName=node versioning=node
ARG NODE_VERSION=22
RUN 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/*

# Claude Code + Codex CLI — AI coding assistants for the integrated terminal.
# Versions pinned in lockstep with the main codex-shell Dockerfile.
# DISABLE_AUTOUPDATER: pin is managed by Renovate, not at runtime.
# renovate: datasource=npm depName=@anthropic-ai/claude-code
ARG CLAUDE_CODE_VERSION=2.1.170
# renovate: datasource=npm depName=@openai/codex
ARG OPENAI_CODEX_VERSION=0.130.0
ENV DISABLE_AUTOUPDATER=true
RUN npm install -g \
"@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}" \
"@openai/codex@${OPENAI_CODEX_VERSION}" \
&& npm cache clean --force

# Startup script: configure git identity + gh auth from env vars, then start code-server.
COPY entrypoint.sh /usr/local/bin/code-server-entrypoint.sh
RUN chmod +x /usr/local/bin/code-server-entrypoint.sh

USER coder

EXPOSE 8080

ENTRYPOINT ["/usr/local/bin/code-server-entrypoint.sh"]
30 changes: 30 additions & 0 deletions code-server/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh
set -e

# Configure git identity from env vars injected by the ExternalSecret.
# Without this, commits from the integrated terminal would land with no
# author identity and git would refuse to commit.
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

# Authenticate gh with the GitHub PAT. The token is provided via the
# GH_TOKEN env var from the ExternalSecret, which is the same mechanism
# used by the claude-cli and codex-cli pods.
if [ -n "$GH_TOKEN" ]; then
echo "$GH_TOKEN" | gh auth login --with-token 2>/dev/null || true
fi

# Start code-server:
# --auth none WARP/CF Access handles auth at the edge
# --disable-telemetry no usage reporting
# /home/coder/workspace default folder to open (mounted from PVC)
exec /usr/bin/code-server \
--bind-addr 0.0.0.0:8080 \
--auth none \
--disable-telemetry \
/home/coder/workspace \
"$@"
Loading