forked from mikael-lovqvist/claude-docker
Updated dockerfile to use node24 and install claude from google cloud storage
This commit is contained in:
28
Dockerfile
28
Dockerfile
@@ -1,24 +1,26 @@
|
||||
FROM node:20-slim
|
||||
FROM node:24-bookworm-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git \
|
||||
curl \
|
||||
wget \
|
||||
jq \
|
||||
netcat-openbsd \
|
||||
socat \
|
||||
iputils-ping \
|
||||
iproute2 \
|
||||
dnsutils \
|
||||
python3 \
|
||||
git curl wget jq netcat-openbsd socat \
|
||||
iputils-ping iproute2 dnsutils python3 \
|
||||
unzip zstd procps lsof psmisc \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
RUN npm install -g @anthropic-ai/claude-code
|
||||
RUN GCS="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases" \
|
||||
&& VERSION=$(curl -fsSL "$GCS/latest") \
|
||||
&& CHECKSUM=$(curl -fsSL "$GCS/$VERSION/manifest.json" | jq -r '.platforms["linux-x64"].checksum') \
|
||||
&& curl -fsSL "$GCS/$VERSION/linux-x64/claude" -o /tmp/claude \
|
||||
&& echo "$CHECKSUM /tmp/claude" | sha256sum -c \
|
||||
&& mv /tmp/claude /usr/local/bin/claude \
|
||||
&& chmod +x /usr/local/bin/claude
|
||||
|
||||
RUN groupmod -g $GID node && usermod -u $UID -g $GID -l claude node && usermod -d /home/claude -m claude
|
||||
RUN (userdel node 2>/dev/null || true) \
|
||||
&& (groupdel node 2>/dev/null || true) \
|
||||
&& groupadd -g $GID claude \
|
||||
&& useradd -u $UID -g $GID -m -s /bin/bash claude
|
||||
USER claude
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
122
dockerfile.md
Normal file
122
dockerfile.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Dockerfile Notes
|
||||
|
||||
## Base image
|
||||
|
||||
```dockerfile
|
||||
FROM node:24-bookworm-slim
|
||||
```
|
||||
|
||||
Uses the official Node.js 24 image on Debian Bookworm (slim variant). Node.js is required because `claude` is a Node.js application distributed as a self-contained binary.
|
||||
|
||||
The slim variant strips documentation and locale files to keep the image small, while still including everything needed to run Node apps.
|
||||
|
||||
**Note:** This image ships with a `node` user and `node` group, both at UID/GID 1000. This is a convention in official Docker images — providing a ready-made unprivileged user so containers don't run as root by default. We replace this user with `claude` (see below).
|
||||
|
||||
---
|
||||
|
||||
## System packages
|
||||
|
||||
```dockerfile
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git curl wget jq netcat-openbsd socat \
|
||||
iputils-ping iproute2 dnsutils python3 \
|
||||
unzip zstd procps lsof psmisc \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
```
|
||||
|
||||
Tools installed for use inside the container:
|
||||
|
||||
| Package | Purpose |
|
||||
|---|---|
|
||||
| `git` | Version control |
|
||||
| `curl`, `wget` | HTTP requests / file downloads |
|
||||
| `jq` | JSON processing on the command line |
|
||||
| `netcat-openbsd` | TCP/UDP connection testing (`nc`) |
|
||||
| `socat` | Multipurpose socket relay |
|
||||
| `iputils-ping` | `ping` command |
|
||||
| `iproute2` | `ip` command, network inspection |
|
||||
| `dnsutils` | `dig`, `nslookup` |
|
||||
| `python3` | Scripting |
|
||||
| `unzip` | Zip archive extraction |
|
||||
| `zstd` | Zstandard compression/decompression |
|
||||
| `procps` | `ps`, `top`, process inspection |
|
||||
| `lsof` | List open files / sockets |
|
||||
| `psmisc` | `fuser`, `killall`, `pstree` |
|
||||
|
||||
The `rm -rf /var/lib/apt/lists/*` at the end discards the apt package index so it doesn't bloat the image layer.
|
||||
|
||||
---
|
||||
|
||||
## UID/GID build args
|
||||
|
||||
```dockerfile
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
```
|
||||
|
||||
Build-time arguments that control which UID and GID the `claude` user gets inside the container. The defaults are 1000/1000 (the most common primary user on Linux desktops).
|
||||
|
||||
The purpose is to match the host system's user, so that files written inside the container (e.g. in a mounted workspace volume) are owned by the correct user on the host — avoiding permission issues.
|
||||
|
||||
Pass these at build time to override:
|
||||
|
||||
```sh
|
||||
docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Claude binary installation
|
||||
|
||||
```dockerfile
|
||||
RUN GCS="https://storage.googleapis.com/..." \
|
||||
&& VERSION=$(curl -fsSL "$GCS/latest") \
|
||||
&& CHECKSUM=$(curl -fsSL "$GCS/$VERSION/manifest.json" | jq -r '.platforms["linux-x64"].checksum') \
|
||||
&& curl -fsSL "$GCS/$VERSION/linux-x64/claude" -o /tmp/claude \
|
||||
&& echo "$CHECKSUM /tmp/claude" | sha256sum -c \
|
||||
&& mv /tmp/claude /usr/local/bin/claude \
|
||||
&& chmod +x /usr/local/bin/claude
|
||||
```
|
||||
|
||||
Downloads the latest `claude` release from Google Cloud Storage:
|
||||
|
||||
1. Fetches the current version string from `latest`
|
||||
2. Fetches the expected SHA-256 checksum from `manifest.json`
|
||||
3. Downloads the `linux-x64` binary to `/tmp/claude`
|
||||
4. Verifies the checksum before installing — build fails if it doesn't match
|
||||
5. Moves the binary to `/usr/local/bin/claude` and makes it executable
|
||||
|
||||
---
|
||||
|
||||
## User setup
|
||||
|
||||
```dockerfile
|
||||
RUN userdel node && groupdel node \
|
||||
&& groupadd -g $GID claude \
|
||||
&& useradd -u $UID -g $GID -m -s /bin/bash claude
|
||||
USER claude
|
||||
```
|
||||
|
||||
The base image's `node` user and group are removed first to free up UID/GID 1000 (or whatever was passed in). A `claude` user and group are then created in their place.
|
||||
|
||||
- `-m` creates a home directory at `/home/claude`
|
||||
- `-s /bin/bash` sets bash as the login shell
|
||||
- `USER claude` switches all subsequent instructions (and the running container) to this unprivileged user
|
||||
|
||||
---
|
||||
|
||||
## Workspace and entrypoint
|
||||
|
||||
```dockerfile
|
||||
WORKDIR /workspace
|
||||
|
||||
CMD ["claude"]
|
||||
```
|
||||
|
||||
`/workspace` is the default working directory — intended to be bind-mounted from the host:
|
||||
|
||||
```sh
|
||||
docker run -it -v "$PWD:/workspace" claude-image
|
||||
```
|
||||
|
||||
`CMD ["claude"]` launches the Claude Code CLI when the container starts.
|
||||
Reference in New Issue
Block a user