-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
55 lines (50 loc) · 2.56 KB
/
Copy pathDockerfile
File metadata and controls
55 lines (50 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
FROM node:24-slim
# ttyd is not packaged for Debian - the upstream release binary is static
# and published per architecture, which is cheaper than building
# libwebsockets in here.
ARG TTYD_VERSION=1.7.7
ARG TARGETARCH
# git, because the repositories a session works on are the point of this
# image and Claude Code's core workflows need it - node:24-slim carries none.
RUN apt-get update \
&& apt-get install -y --no-install-recommends tmux ca-certificates curl git procps \
&& rm -rf /var/lib/apt/lists/* \
# Pinned by content, not only by tag: a release asset can be replaced
# under its tag, and strangers run this image. The hashes belong to
# TTYD_VERSION above and move with it.
&& case "$TARGETARCH" in \
amd64) ttyd_arch=x86_64 ttyd_sha=8a217c968aba172e0dbf3f34447218dc015bc4d5e59bf51db2f2cd12b7be4f55 ;; \
arm64) ttyd_arch=aarch64 ttyd_sha=b38acadd89d1d396a0f5649aa52c539edbad07f4bc7348b27b4f4b7219dd4165 ;; \
*) echo "unsupported architecture: $TARGETARCH" >&2; exit 1 ;; \
esac \
&& curl -fsSL "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.${ttyd_arch}" -o /usr/local/bin/ttyd \
&& echo "${ttyd_sha} /usr/local/bin/ttyd" | sha256sum -c - \
&& chmod +x /usr/local/bin/ttyd \
&& npm install -g @anthropic-ai/claude-code
# Anyone who reaches the port gets a shell as this user - the same reason
# deploy/claudux.service sets User=. The container default would be root.
#
# uid 1000, which the base image's own `node` user holds and therefore gives
# up here: a host user at 1000 has to stay able to write the files under a
# mounted -v ~/code:/projects. --create-home leaves /home/claudux to
# claudux, so the volume the README mounts there inherits that ownership and
# the app creates .claudux under it on first write.
RUN userdel -r node \
&& useradd --create-home --uid 1000 --shell /bin/bash claudux \
# So the documented volume mount target exists with the right
# ownership even before anything is actually mounted there.
&& mkdir -p /projects \
&& chown claudux:claudux /projects
WORKDIR /app
# Deliberately no --chown: /app stays root-owned, so a session cannot
# rewrite the code the next container start runs. npm ci runs as root here
# either way.
COPY . .
RUN npm ci --omit=dev
USER claudux
# USER does not set HOME, and config.js resolves every per-installation path
# through os.homedir() - which reads $HOME first. Left to the runtime it is
# either unset or still /root, and the second case is unwritable.
ENV HOME=/home/claudux
EXPOSE 4001
CMD ["node", "src/server.js"]