@@ -39,18 +39,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends sudo \
3939# Layer 3: Go (latest) with China mirror and tools
4040ENV GO_VERSION=1.24.0
4141ENV GOPROXY=https://goproxy.cn,direct
42+ # GOPATH for user packages (can be mounted), tools installed to /opt/go-tools
4243ENV GOPATH=/home/coder/go
43- ENV PATH=/usr/local/go/bin:/home/coder/go/bin:$PATH
44+ ENV GO_TOOLS_PATH=/opt/go-tools
45+ ENV PATH=/usr/local/go/bin:/opt/go-tools/bin:/home/coder/go/bin:$PATH
4446
4547RUN ARCH=$(dpkg --print-architecture) \
4648 && curl -fsSL https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz | tar -C /usr/local -xzf - \
4749 && go version
4850
49- # Install Go tools
50- RUN go install golang.org/x/tools/gopls@latest \
51- && go install github.com/go-delve/delve/cmd/dlv@latest \
52- && go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest \
53- && go install golang.org/x/tools/cmd/goimports@latest
51+ # Install Go tools to /opt/go-tools (not affected by volume mounts on /home/coder)
52+ RUN mkdir -p /opt/go-tools \
53+ && GOPATH=/opt/go-tools go install golang.org/x/tools/gopls@latest \
54+ && GOPATH=/opt/go-tools go install github.com/go-delve/delve/cmd/dlv@latest \
55+ && GOPATH=/opt/go-tools go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest \
56+ && GOPATH=/opt/go-tools go install golang.org/x/tools/cmd/goimports@latest \
57+ && chown -R coder:coder /opt/go-tools
5458
5559# Create symlinks for go commands (ensures availability even when PATH is reset)
5660RUN ln -s /usr/local/go/bin/go /usr/local/bin/go \
@@ -157,25 +161,25 @@ RUN echo "---\n:sources:\n - https://gems.ruby-china.com/" > /home/coder/.gemrc
157161RUN echo '#!/bin/sh\n \
158162# Development tools PATH configuration\n \
159163# Note: Symlinks in /usr/local/bin provide fallback, this is additional coverage\n \
160- export PATH=/opt/rbenv/bin:/opt/rbenv/shims:/usr/local/go/bin:/home/coder/go/bin:/opt/temurin-21-jdk/bin:/opt/conda/bin:$PATH' > /etc/profile.d/dev-tools.sh \
164+ export PATH=/opt/go-tools/bin:/opt/ rbenv/bin:/opt/rbenv/shims:/usr/local/go/bin:/home/coder/go/bin:/opt/temurin-21-jdk/bin:/opt/conda/bin:$PATH' > /etc/profile.d/dev-tools.sh \
161165 && chmod +x /etc/profile.d/dev-tools.sh
162166
163- # Create directories for external mounting support
164- RUN mkdir -p /home/coder/project \
165- && mkdir -p /home/coder/.local/share/code-server \
166- && mkdir -p /home/coder/.local/share/pnpm \
167- && mkdir -p /home/coder/.m2/repository \
168- && mkdir -p /home/coder/.config/pip \
169- && mkdir -p /home/coder/.npm \
170- && mkdir -p /home/coder/.cache/uv \
171- && mkdir -p /home/coder/.cache/pip \
172- && mkdir -p /home/coder/go
167+ # Create config templates directory (for volume mount compatibility)
168+ # When /home/coder is mounted externally, these templates will be used to initialize configs
169+ RUN mkdir -p /opt/dev-configs
173170
174- # Declare volumes for external mounting (optional, users can override with -v)
175- # These can be mounted to persist data across container restarts
176- VOLUME ["/home/coder/project" ]
171+ # bashrc append content template
172+ RUN echo '\n \
173+ # Restore Docker ENV PATH (VS Code terminal resets PATH)\n \
174+ export 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 \
175+ \n \
176+ # Initialize rbenv\n \
177+ eval "$(/opt/rbenv/bin/rbenv init - bash)"' > /opt/dev-configs/bashrc-append.sh
178+
179+ # gemrc template
180+ RUN echo '---\n :sources:\n - https://gems.ruby-china.com/' > /opt/dev-configs/gemrc
177181
178- # Maven settings.xml with Aliyun mirror
182+ # Maven settings.xml template
179183RUN echo '<?xml version="1.0" encoding="UTF-8"?>\n \
180184<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"\n \
181185 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n \
@@ -188,31 +192,56 @@ RUN echo '<?xml version="1.0" encoding="UTF-8"?>\n\
188192 <url>https://maven.aliyun.com/repository/public</url>\n \
189193 </mirror>\n \
190194 </mirrors>\n \
191- </settings>' > /home/coder/.m2/ settings.xml
195+ </settings>' > /opt/dev-configs/m2- settings.xml
192196
193- # pip config with Tsinghua mirror
194- RUN echo '[global]\n index-url = https://pypi.tuna.tsinghua.edu.cn/simple' > /home/coder/.config/pip /pip.conf
197+ # pip config template
198+ RUN echo '[global]\n index-url = https://pypi.tuna.tsinghua.edu.cn/simple' > /opt/dev-configs /pip.conf
195199
196- # conda config - Miniforge uses conda-forge by default (no Anaconda ToS)
197- RUN /opt/conda/bin/conda config --set show_channel_urls yes
200+ # Copy initialization script
201+ COPY scripts/init-home.sh /opt/dev-configs/init-home.sh
202+ RUN chmod +x /opt/dev-configs/init-home.sh
203+
204+ # Create directories for external mounting support
205+ RUN mkdir -p /home/coder/project \
206+ && mkdir -p /home/coder/.local/share/code-server \
207+ && mkdir -p /home/coder/.local/share/pnpm \
208+ && mkdir -p /home/coder/.m2/repository \
209+ && mkdir -p /home/coder/.config/pip \
210+ && mkdir -p /home/coder/.npm \
211+ && mkdir -p /home/coder/.cache/uv \
212+ && mkdir -p /home/coder/.cache/pip \
213+ && mkdir -p /home/coder/go
198214
199- # npm config (already configured in Layer 5)
200- RUN mkdir -p /home/coder/.npm
215+ # Declare volumes for external mounting (optional, users can override with -v)
216+ # These can be mounted to persist data across container restarts
217+ VOLUME ["/home/coder/project" ]
201218
202- # Add PATH restoration and rbenv initialization to .bashrc
203- # VS Code terminal is non-login shell, only .bashrc is read
204- # Use >> to append instead of > to avoid overwriting existing .bashrc
205- RUN echo '\n \
206- # Restore Docker ENV PATH (VS Code terminal resets PATH)\n \
207- export PATH=/opt/rbenv/bin:/opt/rbenv/shims:/opt/temurin-21-jdk/bin:/opt/conda/bin:/usr/local/go/bin:/home/coder/go/bin:$PATH\n \
208- \n \
209- # Initialize rbenv\n \
210- eval "$(/opt/rbenv/bin/rbenv init - bash)"' >> /home/coder/.bashrc
219+ # Initialize config files from templates
220+ RUN cp /opt/dev-configs/gemrc /home/coder/.gemrc \
221+ && cp /opt/dev-configs/m2-settings.xml /home/coder/.m2/settings.xml \
222+ && cp /opt/dev-configs/pip.conf /home/coder/.config/pip/pip.conf \
223+ && cat /opt/dev-configs/bashrc-append.sh >> /home/coder/.bashrc
224+
225+ # conda config - Miniforge uses conda-forge by default (no Anaconda ToS)
226+ RUN /opt/conda/bin/conda config --set show_channel_urls yes
211227
212228# Set ownership for coder user
213- # Note: /opt/rbenv is owned by root, but accessible by all users
214229RUN chown -R coder:coder /home/coder \
215- && chown -R coder:coder /opt/conda
230+ && chown -R coder:coder /opt/conda \
231+ && chown -R coder:coder /opt/go-tools
232+
233+ # Create entrypoint script that initializes home directory on container start
234+ # This ensures configs are properly set when /home/coder is mounted externally
235+ RUN echo '#!/bin/bash\n \
236+ # Initialize home directory if mounted externally\n \
237+ /opt/dev-configs/init-home.sh\n \
238+ # Execute the original entrypoint or command\n \
239+ exec "$@"' > /entrypoint.sh \
240+ && chmod +x /entrypoint.sh
216241
217242USER coder
218243WORKDIR /home/coder/project
244+
245+ # Use custom entrypoint to handle volume mount initialization
246+ ENTRYPOINT ["/entrypoint.sh" ]
247+ CMD ["code-server" , "--bind-addr" , "0.0.0.0:8080" , "." ]
0 commit comments