@@ -27,7 +27,7 @@ RUN mkdir -p /etc/apt/keyrings \
2727 && chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg \
2828 && echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list \
2929 && apt-get update \
30- && apt-get install -y kubectl \
30+ && apt-get install -y --no-install-recommends kubectl \
3131 && rm -rf /var/lib/apt/lists/*
3232
3333# Layer 2: User permissions - sudo with su blocked
@@ -37,25 +37,35 @@ RUN apt-get update && apt-get install -y --no-install-recommends sudo \
3737 && visudo -c -f /etc/sudoers.d/coder-nopasswd \
3838 && rm -rf /var/lib/apt/lists/*
3939
40- # Layer 3: Go (latest) with China mirror and tools
41- ENV GO_VERSION=1.24.0
40+ # Layer 3: Go (pinned stable) with China mirror and tools
41+ ENV GO_VERSION=1.26.1
42+ ENV GO_SHA256_AMD64=031f088e5d955bab8657ede27ad4e3bc5b7c1ba281f05f245bcc304f327c987a
43+ ENV GO_SHA256_ARM64=a290581cfe4fe28ddd737dde3095f3dbeb7f2e4065cab4eae44dfc53b760c2f7
4244ENV GOPROXY=https://goproxy.cn,direct
4345# GOPATH for user packages (can be mounted), tools installed to /opt/go-tools
4446ENV GOPATH=/home/coder/go
4547ENV GO_TOOLS_PATH=/opt/go-tools
4648ENV PATH=/usr/local/go/bin:/opt/go-tools/bin:/home/coder/go/bin:$PATH
4749
4850RUN ARCH=$(dpkg --print-architecture) \
49- && curl -fsSL https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz | tar -C /usr/local -xzf - \
51+ && case "$ARCH" in \
52+ amd64) GO_SHA256="$GO_SHA256_AMD64" ;; \
53+ arm64) GO_SHA256="$GO_SHA256_ARM64" ;; \
54+ *) echo "Unsupported architecture: $ARCH" && exit 1 ;; \
55+ esac \
56+ && curl -fsSL https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz -o /tmp/go.tgz \
57+ && echo "${GO_SHA256} /tmp/go.tgz" | sha256sum -c - \
58+ && rm -rf /usr/local/go \
59+ && tar -C /usr/local -xzf /tmp/go.tgz \
60+ && rm -f /tmp/go.tgz \
5061 && go version
5162
5263# Install Go tools to /opt/go-tools (not affected by volume mounts on /home/coder)
53- RUN mkdir -p /opt/go-tools \
54- && GOPATH=/opt/go-tools go install golang.org/x/tools/gopls@latest \
55- && GOPATH=/opt/go-tools go install github.com/go-delve/delve/cmd/dlv@latest \
56- && GOPATH=/opt/go-tools go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest \
57- && GOPATH=/opt/go-tools go install golang.org/x/tools/cmd/goimports@latest \
58- && chown -R coder:coder /opt/go-tools
64+ RUN install -d -o coder -g coder /opt/go-tools \
65+ && sudo -u coder env GOPATH=/opt/go-tools go install golang.org/x/tools/gopls@latest \
66+ && sudo -u coder env GOPATH=/opt/go-tools go install github.com/go-delve/delve/cmd/dlv@latest \
67+ && sudo -u coder env GOPATH=/opt/go-tools go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest \
68+ && sudo -u coder env GOPATH=/opt/go-tools go install golang.org/x/tools/cmd/goimports@latest
5969
6070# Create symlinks for go commands (ensures availability even when PATH is reset)
6171RUN ln -s /usr/local/go/bin/go /usr/local/bin/go \
@@ -65,18 +75,21 @@ RUN ln -s /usr/local/go/bin/go /usr/local/bin/go \
6575ENV UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
6676
6777# Install Miniforge (conda-forge based, no Anaconda ToS required)
68- RUN ARCH=$(dpkg --print-architecture) && \
78+ RUN install -d -o coder -g coder /opt/conda \
79+ && ARCH=$(dpkg --print-architecture) && \
6980 if [ "$ARCH" = "amd64" ]; then CONDA_ARCH="x86_64" ; \
7081 elif [ "$ARCH" = "arm64" ]; then CONDA_ARCH="aarch64" ; \
7182 else CONDA_ARCH="$ARCH" ; fi && \
7283 curl -fsSL https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-${CONDA_ARCH}.sh -o /tmp/miniforge.sh \
73- && bash /tmp/miniforge.sh -b -p /opt/conda \
84+ && chmod +x /tmp/miniforge.sh \
85+ && sudo -u coder bash /tmp/miniforge.sh -b -p /opt/conda \
7486 && rm /tmp/miniforge.sh
7587ENV PATH=/opt/conda/bin:$PATH
7688
7789# Install Python 3.13 via conda-forge and create symlinks
78- RUN conda install -y python=3.13 \
79- && conda clean -afy \
90+ RUN sudo -u coder /opt/conda/bin/conda install -y python=3.13 \
91+ && sudo -u coder /opt/conda/bin/conda config --set show_channel_urls yes \
92+ && sudo -u coder /opt/conda/bin/conda clean -afy \
8093 && ln -sf /opt/conda/bin/python /usr/bin/python3 \
8194 && ln -sf /opt/conda/bin/python /usr/bin/python \
8295 && ln -sf /opt/conda/bin/pip /usr/bin/pip3 \
@@ -90,12 +103,13 @@ ENV NODE_VERSION=22
90103
91104# Install Node.js from NodeSource
92105RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - \
93- && apt-get install -y nodejs \
106+ && apt-get install -y --no-install-recommends nodejs \
94107 && rm -rf /var/lib/apt/lists/*
95108
96109# Configure npm mirror and install pnpm, yarn, iflow-cli, claude-code
97110RUN npm config set registry https://registry.npmmirror.com --global \
98111 && npm install -g pnpm yarn @iflow-ai/iflow-cli@latest @anthropic-ai/claude-code@latest \
112+ && npm cache clean --force \
99113 && pnpm config set registry https://registry.npmmirror.com \
100114 && yarn config set registry https://registry.npmmirror.com
101115
@@ -124,6 +138,8 @@ RUN ln -s /opt/temurin-21-jdk/bin/java /usr/local/bin/java \
124138# Layer 7: Ruby (rbenv) + Rails with Ruby China mirror
125139# Install rbenv to /opt/rbenv to avoid being overwritten by volume mounts
126140ENV RBENV_ROOT=/opt/rbenv
141+ ENV RUBY_VERSION=4.0.2
142+ ENV RUBY_GEM_ABI=4.0.0
127143ENV PATH=$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH
128144
129145# Install Ruby dependencies
@@ -142,16 +158,20 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
142158 && rm -rf /var/lib/apt/lists/*
143159
144160# Install rbenv and ruby-build to /opt/rbenv (system path, not affected by volume mounts)
145- RUN git clone https://github.com/rbenv/rbenv.git /opt/rbenv \
146- && git clone https://github.com/rbenv/ruby-build.git /opt/rbenv/plugins/ruby-build
161+ RUN git clone --depth 1 https://github.com/rbenv/rbenv.git /opt/rbenv \
162+ && git clone --depth 1 https://github.com/rbenv/ruby-build.git /opt/rbenv/plugins/ruby-build \
163+ && chown -R coder:coder /opt/rbenv
147164
148165# Install latest stable Ruby and Rails
149- RUN /opt/rbenv/plugins/ruby-build/install.sh \
150- && rbenv install 3.4.4 \
151- && rbenv global 3.4.4 \
166+ RUN sudo -u coder env RUBY_VERSION=${RUBY_VERSION} bash -lc 'set -euo pipefail \
167+ && export RBENV_ROOT=/opt/rbenv \
168+ && export PATH="$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH" \
169+ && /opt/rbenv/plugins/ruby-build/install.sh \
170+ && rbenv install "$RUBY_VERSION" \
171+ && rbenv global "$RUBY_VERSION" \
152172 && rbenv rehash \
153173 && gem install bundler rails --no-document \
154- && rbenv rehash
174+ && rbenv rehash'
155175
156176# Configure gem mirror
157177RUN echo "---\n :sources:\n - https://gems.ruby-china.com/" > /home/coder/.gemrc
@@ -175,7 +195,8 @@ RUN echo '\n\
175195export PATH=/opt/go-tools/bin:/opt/rbenv/bin:/opt/rbenv/shims:/opt/temurin-21-jdk/bin:/opt/conda/bin:/usr/local/go/bin:/home/coder/go/bin:$PATH\n \
176196\n \
177197# User-installed gem executables path\n \
178- export PATH=/home/coder/.local/share/gem/ruby/3.4.0/bin:$PATH\n \
198+ export RUBY_GEM_ABI=${RUBY_GEM_ABI:-4.0.0}\n \
199+ export PATH=/home/coder/.local/share/gem/ruby/${RUBY_GEM_ABI}/bin:$PATH\n \
179200\n \
180201# Initialize rbenv\n \
181202if [ -x /opt/rbenv/bin/rbenv ]; then\n \
@@ -228,16 +249,8 @@ RUN cp /opt/dev-configs/gemrc /home/coder/.gemrc \
228249 && cp /opt/dev-configs/pip.conf /home/coder/.config/pip/pip.conf \
229250 && cat /opt/dev-configs/bashrc-append.sh >> /home/coder/.bashrc
230251
231- # conda config - Miniforge uses conda-forge by default (no Anaconda ToS)
232- RUN /opt/conda/bin/conda config --set show_channel_urls yes
233-
234252# Set ownership for coder user
235- RUN chown -R coder:coder /home/coder \
236- && chown -R coder:coder /opt/conda \
237- && chown -R coder:coder /opt/go-tools \
238- && chown -R coder:coder /opt/rbenv/versions \
239- && chown -R coder:coder /opt/rbenv/shims \
240- && chown coder:coder /opt/rbenv/version
253+ RUN chown -R coder:coder /home/coder
241254
242255# Create entrypoint script that initializes home directory on container start
243256# This ensures configs are properly set when /home/coder is mounted externally
0 commit comments