From 43c0d1756ed9e2fd4377b8c640d8dd64173dab2e Mon Sep 17 00:00:00 2001 From: Charles Bennett Date: Thu, 26 Feb 2026 12:18:13 -0500 Subject: [PATCH] New dockerfile, init.sh, config.yaml, and settings.json, based on upstream 3f238407. --- .dockerignore | 2 + Dockerfile | 141 +++++++++++++++++++++++++++++++++ ci/release-image/config.yaml | 4 + ci/release-image/entrypoint.sh | 120 +++++++++++++++++++++++----- ci/release-image/settings.json | 4 + 5 files changed, 250 insertions(+), 21 deletions(-) create mode 100644 Dockerfile create mode 100644 ci/release-image/config.yaml create mode 100644 ci/release-image/settings.json diff --git a/.dockerignore b/.dockerignore index 9bcce7a80897..dd790041870f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,5 @@ ** !release-packages !ci +!Dockerfile +!requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000000..949b18233c1b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,141 @@ +# Build stage for Python +FROM debian:bullseye-slim AS python-builder + +# Install some Python build-related stuff +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + build-essential \ + wget \ + libgdbm-dev \ + libncursesw5-dev \ + libffi-dev \ + liblzma-dev \ + libreadline-dev \ + libsqlite3-dev \ + libbz2-dev \ + libssl-dev \ + libxml2-dev \ + libxmlsec1-dev \ + tk-dev \ + xz-utils \ + zlib1g-dev && \ + rm -rf /var/lib/apt/lists/* + +# Build Python 3.13.8 from source +RUN cd /tmp && \ + wget https://www.python.org/ftp/python/3.13.8/Python-3.13.8.tgz && \ + tar xzf Python-3.13.8.tgz && \ + cd Python-3.13.8 && \ + ./configure --enable-optimizations --prefix=/opt/python && \ + make -j$(nproc) && \ + make altinstall && \ + cd /tmp && \ + rm -rf Python-3.13.8* + + +# Final stage +FROM codercom/code-server:4.19.1-bullseye + +# Install _runtime_ dependencies: +RUN apt-get update && \ + apt-get -y upgrade && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + git \ + dumb-init \ + htop \ + locales \ + lsb-release \ + libnss-ldap \ + ldap-utils \ + man-db \ + nano \ + openssh-client \ + procps \ + zsh \ + curl \ + less \ + vim \ + wget \ + # Python _runtime_ dependencies + libbz2-1.0 \ + libffi7 \ + liblzma5 \ + libncursesw6 \ + libreadline8 \ + libsqlite3-0 \ + libssl1.1 \ + libxml2 \ + libxmlsec1 \ + tk \ + zlib1g && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Copy Python from python-builder stage: +COPY --from=python-builder /opt/python /opt/python + +# Create Python symlinks: +RUN ln -sf /opt/python/bin/python3.13 /usr/local/bin/python3 && \ + ln -sf /opt/python/bin/python3.13 /usr/local/bin/python && \ + ln -sf /opt/python/bin/pip3.13 /usr/local/bin/pip3 && \ + ln -sf /opt/python/bin/pip3.13 /usr/local/bin/pip + +# Install Python packages +COPY ./requirements.txt /tmp/requirements.txt +RUN pip3 install --no-cache-dir --upgrade pip && \ + pip3 install --no-cache-dir -r /tmp/requirements.txt && \ + rm /tmp/requirements.txt + +# Install latest stable Node.js (24.9.0) +RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \ + apt-get install -y nodejs=24.9.0-1nodesource1 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Install golang 1.24.9 +RUN ARCH=$(dpkg --print-architecture) && \ + wget https://go.dev/dl/go1.24.9.linux-${ARCH}.tar.gz && \ + tar -C /usr/local -xzf go1.24.9.linux-${ARCH}.tar.gz && \ + rm go1.24.9.linux-${ARCH}.tar.gz + +# Set up environment and PATH +ENV LANG=en_US.UTF-8 +ENV GOPATH=/go +ENV GOROOT=/usr/local/go +ENV PATH="/opt/python/bin:$GOPATH/bin:$GOROOT/bin:$PATH" + +#----------------------------------------------------------------------------- +# Install code-server extensions +# Note: This installs extensions in /root/.local/share/code-server/extensions. +# $HOME is not avaible at build time, so tar up ext directory and put it +# in /opt/code-server/helx-extensions.tgz. An init script will copy them +# to the user's $HOME once it's been set up by user-mutator. +#----------------------------------------------------------------------------- +RUN /usr/bin/code-server --install-extension ms-python.python \ + --install-extension ms-python.debugpy \ + --install-extension njqdev.vscode-python-typehint \ + --install-extension magicstack.magicpython \ + --install-extension njpwerner.autodocstring \ + --install-extension EricSia.pythonsnippets3 \ + --install-extension golang.go \ + --install-extension christian-kohler.npm-intellisense \ + --install-extension christian-kohler.path-intellisense \ + --install-extension esbenp.prettier-vscode && \ + # tar up and move extension archive so init script can later propagate it to user's $HOME + /bin/tar -czvf helx-extensions.tgz -C /root/.local/share/code-server extensions && \ + mkdir -p /opt/code-server && \ + mv /home/coder/helx-extensions.tgz /opt/code-server/helx-default-extensions.tgz && \ + chmod 644 /opt/code-server/helx-default-extensions.tgz && \ + # Remove extensions files and config.yaml under /root + rm -f /root/.config/code-server/config.yaml && \ + rm -rf /root/.local/share/code-server/extensions/* + +COPY --chmod=0755 ci/release-image/entrypoint.sh /usr/bin/entrypoint.sh +COPY --chmod=0644 ci/release-image/config.yaml /opt/code-server/config.yaml +COPY --chmod=0644 ci/release-image/settings.json /opt/code-server/settings.json + +# Expose code-server port +EXPOSE 8080 + +ENTRYPOINT ["dumb-init", "--"] +CMD ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "--auth", "none", "--cert", "false", "."] diff --git a/ci/release-image/config.yaml b/ci/release-image/config.yaml new file mode 100644 index 000000000000..5187c57ff517 --- /dev/null +++ b/ci/release-image/config.yaml @@ -0,0 +1,4 @@ +bind-addr: 0.0.0.0:8080 +auth: none +cert: false +disable-telemetry: true diff --git a/ci/release-image/entrypoint.sh b/ci/release-image/entrypoint.sh index efe2f39d9bd9..ba90e3a46583 100755 --- a/ci/release-image/entrypoint.sh +++ b/ci/release-image/entrypoint.sh @@ -1,27 +1,105 @@ -#!/bin/sh +#!/bin/bash set -eu -# We do this first to ensure sudo works below when renaming the user. -# Otherwise the current container UID may not exist in the passwd database. -eval "$(fixuid -q)" - -if [ "${DOCKER_USER-}" ]; then - USER="$DOCKER_USER" - if [ -z "$(id -u "$DOCKER_USER" 2>/dev/null)" ]; then - echo "$DOCKER_USER ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers.d/nopasswd > /dev/null - # Unfortunately we cannot change $HOME as we cannot move any bind mounts - # nor can we bind mount $HOME into a new home as that requires a privileged container. - sudo usermod --login "$DOCKER_USER" coder - sudo groupmod -n "$DOCKER_USER" coder - - sudo sed -i "/coder/d" /etc/sudoers.d/nopasswd - fi -fi +HELX_DEFAULTS_DIR="/opt/code-server" +HELX_DEFAULT_SETTINGS="$HELX_DEFAULTS_DIR/settings.json" +HELX_DEFAULT_CONFIG="$HELX_DEFAULTS_DIR/config.yaml" +HELX_EXTENSION_ARCHIVE="$HELX_DEFAULTS_DIR/helx-default-extensions.tgz" + +USER_SCRIPT_DIR="$HOME/entrypoint.d" +USER_CONFIG_DIR="$HOME/.config/code-server" +USER_SETTINGS_DIR="$HOME/.local/share/code-server/User" +USER_EXTENSION_DIR="$HOME/.local/share/code-server/extensions" + +USER_CONFIG_FILE="$USER_CONFIG_DIR/config.yaml" +USER_SETTINGS_FILE="$USER_SETTINGS_DIR/settings.json" + +USER_SCRIPTS_ENABLED=1 + +INIT_SCRIPT="$(basename "$0")" -# Allow users to have scripts run on container startup to prepare workspace. +umask 0022 + +log() { echo "[$INIT_SCRIPT]: $*"; } + +log "Running." + +# Allow users to run scripts to set up workspace on container startup. # https://github.com/coder/code-server/issues/5177 -if [ -d "${ENTRYPOINTD}" ]; then - find "${ENTRYPOINTD}" -type f -executable -print -exec {} \; +if [ ! -d "$USER_SCRIPT_DIR" ]; then + log "Creating script directory for user scripts." + mkdir -p "$USER_SCRIPT_DIR" +else + if [ $USER_SCRIPTS_ENABLED -eq 1 ]; then + log "Checking $USER_SCRIPT_DIR for user scripts." + for script in "$USER_SCRIPT_DIR"/*.sh; do + if [ -x "$script" ]; then + log "Running script: $script" + bash "$script" + STATUS=$? + if [ $STATUS -ne 0 ]; then + log "Error: Script $script failed with exit code $STATUS." + fi + else + log "$script is not executable; skipping." + fi + done + else + log "Running user scripts not enabled." + fi +fi + +# Copy in config.yaml file if not present; vs-code creates one with +# auth: password set by default! +if [ ! -f "$USER_CONFIG_FILE" ]; then + log "Copying default config.yaml file to $USER_CONFIG_FILE." + mkdir -p "$USER_CONFIG_DIR" + chmod 755 "$USER_CONFIG_DIR" + cp "$HELX_DEFAULT_CONFIG" "$USER_CONFIG_FILE" + chmod 644 "$USER_CONFIG_FILE" +else + log "$USER_CONFIG_FILE file exists." +fi + +# Copy in settings.json if not present +if [ ! -f $USER_SETTINGS_FILE ]; then + log "Copying default settings.json file to $USER_SETTINGS_FILE" + mkdir -p $USER_SETTINGS_DIR + chmod 755 "$USER_SETTINGS_DIR" + cp $HELX_DEFAULT_SETTINGS $USER_SETTINGS_FILE + chmod 644 "$USER_SETTINGS_FILE" +else + log "$USER_SETTINGS_FILE file exists." +fi + +# Only add default extensions the first time. If there's an existing extensions directory, bail +if [ ! -d "$USER_EXTENSION_DIR" ]; then + log "Creating extensions directory to add default extensions." + mkdir -p "$USER_EXTENSION_DIR" + chmod 755 "$USER_EXTENSION_DIR" + tar -xzf $HELX_EXTENSION_ARCHIVE -C $USER_EXTENSION_DIR --skip-old-files --strip-components=1 + find "$USER_EXTENSION_DIR" -type d -exec chmod 755 {} \; + find "$USER_EXTENSION_DIR" -type f -exec chmod 644 {} \; + log "Finished installing default extensions." +else + log "Found existing extensions directory, not installing default extensions." fi -exec dumb-init /usr/bin/code-server "$@" +# Set up a default workspace so it doesn't run in /home/coder +log "Setting default workspace." +export DEFAULT_WORKSPACE=$HOME + +# Expand args passed in--but replace last one with $HOME: +log "Passed in args: [ $@ ]" +cmd_args="${@:1:$#-1}" +cmd_args+=" ${HOME}" +log "Updated args : [ ${cmd_args} ]" + +entrypoint="dumb-init -- /usr/bin/code-server " +log "Entrypoint : [ ${entrypoint}]" + +startup_cmd="$entrypoint" +startup_cmd+="$cmd_args" +log "Starting : [ ${startup_cmd} ]" + +exec $startup_cmd diff --git a/ci/release-image/settings.json b/ci/release-image/settings.json new file mode 100644 index 000000000000..50bcbe7289f0 --- /dev/null +++ b/ci/release-image/settings.json @@ -0,0 +1,4 @@ +{ + "workbench.colorTheme": "Default Dark Modern", + "security.workspace.trust.enabled": false, +}