#!/bin/bash set -e # Custom entrypoint for code-server with additional setup # Supports both rooted Docker containers and rootless Podman containers CURRENT_USER=$(whoami) CURRENT_UID=$(id -u) echo "🚀 Starting custom code-server entrypoint (running as $CURRENT_USER, UID: $CURRENT_UID)..." # Detect if we're running as root or not IS_ROOT=false if [ "$CURRENT_UID" -eq 0 ]; then IS_ROOT=true echo "🔐 Running in rooted container mode - will perform system setup" else echo "👤 Running in rootless container mode - assuming permissions already granted" fi # Ensure proper home directory structure (critical for volume mounts) echo "🏠 Setting up home directory structure..." # Create home directory for coder user if it doesn't exist if [ ! -d "/home/coder" ]; then echo "📁 Creating /home/coder directory..." mkdir -p /home/coder fi # Set ownership only if running as root if [ "$IS_ROOT" = true ]; then chown coder:coder /home/coder chmod 755 /home/coder else # In rootless mode, just ensure it's accessible chmod 755 /home/coder 2>/dev/null || true fi # Set up essential dotfiles and shell configuration if [ ! -f "/home/coder/.bashrc" ]; then echo "⚙️ Creating default .bashrc..." cat > /home/coder/.bashrc << 'EOF' # ~/.bashrc: executed by bash(1) for non-login shells. # If not running interactively, don't do anything case $- in *i*) ;; *) return;; esac # Load Homebrew environment if available if [ -d "/home/linuxbrew/.linuxbrew" ]; then eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" fi # Some useful aliases alias ll='ls -alF' alias la='ls -A' alias l='ls -CF' # Enable color support if [ -x /usr/bin/dircolors ]; then test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" alias ls='ls --color=auto' alias grep='grep --color=auto' fi EOF # Set ownership only if running as root if [ "$IS_ROOT" = true ]; then chown coder:coder /home/coder/.bashrc fi fi # Set up .profile for login shells if [ ! -f "/home/coder/.profile" ]; then echo "⚙️ Creating default .profile..." cat > /home/coder/.profile << 'EOF' # ~/.profile: executed by the command interpreter for login shells. # Load Homebrew environment if available if [ -d "/home/linuxbrew/.linuxbrew" ]; then eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" fi # Set PATH to include user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi EOF # Set ownership only if running as root if [ "$IS_ROOT" = true ]; then chown coder:coder /home/coder/.profile fi fi # Install/Setup Homebrew if not already present echo "🍺 Setting up Homebrew..." if [ ! -d "/home/linuxbrew/.linuxbrew" ] || [ ! -f "/home/linuxbrew/.linuxbrew/bin/brew" ]; then echo "📦 Installing Homebrew..." # Create linuxbrew user directory structure mkdir -p /home/linuxbrew/.linuxbrew # Clone Homebrew repository git clone --depth=1 https://github.com/Homebrew/brew /home/linuxbrew/.linuxbrew/Homebrew # Create bin directory and symlink mkdir -p /home/linuxbrew/.linuxbrew/bin ln -sf /home/linuxbrew/.linuxbrew/Homebrew/bin/brew /home/linuxbrew/.linuxbrew/bin/brew # Set proper ownership only if running as root if [ "$IS_ROOT" = true ]; then chown -R coder:coder /home/linuxbrew fi echo "✅ Homebrew installed successfully!" else echo "✅ Homebrew already installed, ensuring proper ownership..." # Ensure ownership is correct only if running as root (important for volume mounts) if [ "$IS_ROOT" = true ]; then chown -R coder:coder /home/linuxbrew fi fi # Create workspace directory if it doesn't exist if [ ! -d "/workspace" ]; then echo "📁 Creating workspace directory..." mkdir -p /workspace fi # Ensure proper ownership of workspace only if running as root if [ "$IS_ROOT" = true ]; then chown coder:coder /workspace chmod 755 /workspace else # In rootless mode, just ensure it's accessible chmod 755 /workspace 2>/dev/null || true fi # Set up any workspace-specific initialization if [ -f "/workspace/.devcontainer/init.sh" ]; then echo "🛠️ Running workspace initialization script..." chmod +x /workspace/.devcontainer/init.sh if [ "$IS_ROOT" = true ]; then # Run as coder user when root su - coder -c "/workspace/.devcontainer/init.sh" else # Run directly when not root /workspace/.devcontainer/init.sh fi fi # Ensure the coder user has access to docker if docker group exists (only when root) if [ "$IS_ROOT" = true ] && getent group docker > /dev/null 2>&1; then echo "🐳 Ensuring coder user is in docker group..." usermod -aG docker coder fi echo "✅ Setup complete, chainloading official entrypoint..." # Switch to coder user and chainload the official code-server entrypoint if [ "$IS_ROOT" = true ]; then echo "🔄 Switching to coder user and launching code-server..." # Use su with proper environment setup when running as root # Set required environment variables for code-server export ENTRYPOINTD="/home/coder/entrypoint.d" export USER="coder" export HOME="/home/coder" exec su - coder -c "export ENTRYPOINTD=\"/home/coder/entrypoint.d\" && export USER=\"coder\" && export HOME=\"/home/coder\" && cd /workspace && exec /usr/bin/entrypoint-official.sh $*" else echo "🔄 Launching code-server directly..." # Run directly when not root (rootless mode) export ENTRYPOINTD="${HOME}/entrypoint.d" export USER="${USER:-$(whoami)}" cd /workspace exec /usr/bin/entrypoint-official.sh "$@" fi