Skip to content

Commit acf975a

Browse files
Charles-Henri ROBICHEclaude
andcommitted
Add GitHub CLI, OpenAI, Gemini CLI with auto-update support
- Install GitHub CLI (gh) from official apt repository - Add Python3 and pip for AI tools - Install OpenAI Python package for Codex API access (latest) - Install Google Generative AI Python SDK for Gemini API (latest) - Auto-detect and install latest Node.js version from nodejs.org - Move Claude Code installation to init script for auto-update support - Claude Code now installs to /config/.npm-global as user abc - Enables Claude Code's built-in auto-update feature - Add init-claude-code s6 service for first-run setup and updates - Update CLAUDE.md with comprehensive architecture documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d1f5a18 commit acf975a

7 files changed

Lines changed: 80 additions & 16 deletions

File tree

CLAUDE.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,30 @@ docker build --no-cache --pull -f Dockerfile.aarch64 -t lscr.io/linuxserver/code
4646
The `/root` directory contains files copied into the container at build time:
4747

4848
- **root/etc/s6-overlay/s6-rc.d/init-code-server/run** - Initialization script that sets up sudo access, SSH permissions, and directory structure
49+
- **root/etc/s6-overlay/s6-rc.d/init-claude-code/run** - Initialization script that installs/updates Claude Code in user-writable location for auto-updates
4950
- **root/etc/s6-overlay/s6-rc.d/svc-code-server/run** - Service script that launches code-server with appropriate flags
5051
- **root/usr/local/bin/install-extension** - Helper script for installing VS Code extensions (used by Docker mods)
5152

5253
### Custom Dockerfile Features
5354

5455
The `Dockerfile.custom` variant includes:
55-
- **Claude Code**: Installed globally via npm during build
56-
- **Google Cloud CLI**: Installed from official apt repository with GPG keyring
57-
- **Node.js 22.14.0**: Custom Node.js installation supporting both amd64 and arm64 architectures
58-
- **Vertex AI Environment Variables**: Pre-configured for Anthropic's Vertex AI integration
59-
- `CLAUDE_CODE_USE_VERTEX=1`
60-
- `CLOUD_ML_REGION=us-east5`
61-
- `ANTHROPIC_VERTEX_PROJECT_ID=oa-data-btdpexploration-np`
62-
- `DISABLE_PROMPT_CACHING=0`
56+
57+
**Development Tools:**
58+
- **Claude Code**: Installed at first startup via init script to `/config/.npm-global` for auto-update support (latest from npm registry)
59+
- **GitHub CLI** (`gh`): Latest version from official GitHub CLI apt repository
60+
- **Google Cloud CLI** (`gcloud`): Latest version from official Google Cloud apt repository
61+
- **Node.js**: Latest stable version auto-detected from nodejs.org, supporting both amd64 and arm64 architectures
62+
63+
**AI API Tools:**
64+
- **OpenAI CLI**: Latest Python package for accessing OpenAI APIs including Codex (`openai`)
65+
- **Google Generative AI**: Latest Python SDK for Gemini API (`google-generativeai`)
66+
67+
**Environment Variables:**
68+
Pre-configured for Anthropic's Vertex AI integration:
69+
- `CLAUDE_CODE_USE_VERTEX=1`
70+
- `CLOUD_ML_REGION=us-east5`
71+
- `ANTHROPIC_VERTEX_PROJECT_ID=oa-data-btdpexploration-np`
72+
- `DISABLE_PROMPT_CACHING=0`
6373

6474
## Making Changes
6575

@@ -99,7 +109,13 @@ The container uses **s6-overlay** for process supervision. The initialization fl
99109
- Manages ownership/permissions (skips `/config/workspace` contents for performance)
100110
- Sets SSH directory permissions (700 for directories, 600 for private keys, 644 for public keys)
101111

102-
2. **svc-code-server** starts the service:
112+
2. **init-claude-code** runs after config initialization:
113+
- Creates `/config/.npm-global` directory for user-writable npm packages
114+
- Installs Claude Code as user `abc` (first startup only)
115+
- Checks for and applies updates on subsequent startups
116+
- Enables Claude Code's built-in auto-update feature
117+
118+
3. **svc-code-server** starts the service:
103119
- Configures authentication (password, hashed password, or none)
104120
- Sets up proxy domain if specified
105121
- Launches code-server bound to `0.0.0.0:8443` (or `[::]:8443` for non-root)

Dockerfile.custom

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## custom Dockerfile for code-server that includes claude-code + gcloud + Vertex env
1+
## custom Dockerfile for code-server that includes claude-code + gcloud + gh + AI CLIs
22
# syntax=docker/dockerfile:1
33

44
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble
@@ -22,6 +22,10 @@ ENV CLAUDE_CODE_USE_VERTEX=1 \
2222
NPM_CONFIG_FUND=false \
2323
NPM_CONFIG_AUDIT=false
2424

25+
# Configure npm for user-writable global installs and add to PATH
26+
ENV NPM_CONFIG_PREFIX=/config/.npm-global \
27+
PATH=/config/.npm-global/bin:${PATH}
28+
2529
RUN \
2630
echo "**** install runtime dependencies ****" && \
2731
apt-get update && \
@@ -33,16 +37,29 @@ RUN \
3337
libatomic1 \
3438
nano \
3539
net-tools \
40+
python3 \
41+
python3-pip \
3642
sudo && \
43+
echo "**** install GitHub CLI (apt repo w/ keyring) ****" && \
44+
mkdir -p /usr/share/keyrings && \
45+
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
46+
| gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg && \
47+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
48+
> /etc/apt/sources.list.d/github-cli.list && \
3749
echo "**** install Google Cloud CLI (apt repo w/ keyring) ****" && \
3850
rm -f /etc/apt/sources.list.d/google-cloud-sdk.list && \
39-
mkdir -p /usr/share/keyrings && \
4051
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg \
4152
| gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg && \
4253
echo 'deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main' \
4354
> /etc/apt/sources.list.d/google-cloud-sdk.list && \
4455
apt-get update && \
45-
apt-get install -y google-cloud-cli && \
56+
apt-get install -y \
57+
gh \
58+
google-cloud-cli && \
59+
echo "**** install AI CLI tools via pip ****" && \
60+
pip3 install --no-cache-dir --break-system-packages \
61+
openai \
62+
google-generativeai && \
4663
echo "**** install code-server ****" && \
4764
if [ -z ${CODE_RELEASE+x} ]; then \
4865
CODE_RELEASE=$(curl -sX GET https://api.github.com/repos/coder/code-server/releases/latest \
@@ -55,17 +72,17 @@ RUN \
5572
curl -o /tmp/code-server.tar.gz -L \
5673
"https://github.com/coder/code-server/releases/download/v${CODE_RELEASE}/code-server-${CODE_RELEASE}-linux-${CODE_ARCH}.tar.gz" && \
5774
tar xf /tmp/code-server.tar.gz -C /app/code-server --strip-components=1 && \
58-
echo "**** install Node.js and npm ****" && \
59-
NODE_VERSION=22.14.0 && \
75+
echo "**** install Node.js and npm (latest) ****" && \
76+
NODE_VERSION=$(curl -sL https://nodejs.org/dist/latest/SHASUMS256.txt | head -1 | sed 's/.*node-v\([0-9.]*\)-.*/\1/') && \
6077
ARCH=$(uname -m) && \
6178
if [ "$ARCH" = "aarch64" ]; then NODE_ARCH="arm64"; fi && \
6279
if [ "$ARCH" = "x86_64" ]; then NODE_ARCH="x64"; fi && \
6380
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.gz" \
6481
| tar -xz -C /usr/local/ --strip-components=1 && \
6582
node -v && npm -v && \
66-
echo "**** upgrade npm and install claude-code globally ****" && \
83+
echo "**** upgrade npm to latest ****" && \
6784
npm install -g npm@latest && \
68-
npm install -g @anthropic-ai/claude-code && \
85+
echo "**** claude-code will be installed at first startup in init script ****" && \
6986
printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \
7087
echo "**** clean up ****" && \
7188
apt-get clean && \

root/etc/s6-overlay/s6-rc.d/init-claude-code/dependencies.d/init-config-end

Whitespace-only changes.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/with-contenv bash
2+
# shellcheck shell=bash
3+
4+
# Install/update claude-code in user-writable location for auto-updates
5+
if [[ -z ${LSIO_NON_ROOT_USER} ]]; then
6+
echo "Setting up Claude Code for user abc with auto-update support"
7+
8+
# Create npm global directory if it doesn't exist
9+
mkdir -p /config/.npm-global
10+
11+
# Install/update claude-code as user abc
12+
s6-setuidgid abc bash -c '
13+
export NPM_CONFIG_PREFIX=/config/.npm-global
14+
export PATH=/config/.npm-global/bin:$PATH
15+
16+
# Check if claude-code is installed
17+
if command -v claude &> /dev/null; then
18+
echo "Claude Code already installed, checking for updates..."
19+
npm update -g @anthropic-ai/claude-code || echo "Update check completed"
20+
else
21+
echo "Installing Claude Code for the first time..."
22+
npm install -g @anthropic-ai/claude-code
23+
fi
24+
25+
echo "Claude Code setup complete"
26+
'
27+
else
28+
echo "Skipping Claude Code setup in non-root mode"
29+
fi
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
oneshot
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/etc/s6-overlay/s6-rc.d/init-claude-code/run

root/etc/s6-overlay/s6-rc.d/user/contents.d/init-claude-code

Whitespace-only changes.

0 commit comments

Comments
 (0)