| set -e | |
| # Default port, can be overridden by PORT env var from Hugging Face | |
| APP_PORT=${PORT:-7860} | |
| # Default workspace, can be overridden by args to this script or Docker CMD | |
| DEFAULT_WORKSPACE_PATH=${1:-/home/coder/project} | |
| # Ensure necessary directories exist and have correct permissions for the 'coder' user | |
| # These are usually created by the base image, but good to ensure. | |
| mkdir -p "${DEFAULT_WORKSPACE_PATH}" | |
| mkdir -p "${USER_DATA_DIR}" # Typically /home/coder/.local/share/code-server | |
| mkdir -p "${EXTENSIONS_DIR}" # Typically /home/coder/.local/share/code-server/extensions | |
| mkdir -p "${CONFIG_DIR}" # Typically /home/coder/.config/code-server | |
| # Change ownership to coder user if script is run as root initially (not expected in HF Spaces) | |
| # However, Hugging Face Spaces usually run as a non-root user that matches the Dockerfile USER. | |
| # The codercom/code-server image already runs as 'coder' (UID 1000, GID 1000). | |
| # So, explicit chown might not be strictly necessary here if files are copied with --chown=coder:coder | |
| # and directories are created by the 'coder' user process. | |
| echo "Ensuring correct ownership for coder user..." | |
| # Since we are running as coder user (defined in base image), these should already be owned by coder. | |
| # If not, it means something is wrong with the base image or execution context. | |
| # We'll skip chown for now as it might fail in restricted environments if not run as root. | |
| # Install extensions if they are not already installed | |
| # List of extensions to install | |
| EXTENSIONS_TO_INSTALL=( | |
| "ms-python.python" | |
| "dbaeumer.vscode-eslint" | |
| "ms-ceintl.vscode-language-pack-zh-hans" | |
| "rooveterinaryinc.roo-cline" | |
| ) | |
| INSTALLED_EXTENSIONS_LIST=$(code-server --list-extensions --extensions-dir "${EXTENSIONS_DIR}") | |
| for EXTENSION_ID in "${EXTENSIONS_TO_INSTALL[@]}"; do | |
| if echo "${INSTALLED_EXTENSIONS_LIST}" | grep -qi "${EXTENSION_ID}"; then | |
| echo "Extension ${EXTENSION_ID} is already installed." | |
| else | |
| echo "Installing extension ${EXTENSION_ID}..." | |
| code-server --extensions-dir "${EXTENSIONS_DIR}" --install-extension "${EXTENSION_ID}" || echo "Failed to install extension ${EXTENSION_ID}, continuing..." | |
| fi | |
| done | |
| # Prepare arguments for code-server | |
| ARGS=( | |
| "--bind-addr" "0.0.0.0:${APP_PORT}" | |
| "--user-data-dir" "${USER_DATA_DIR}" | |
| "--extensions-dir" "${EXTENSIONS_DIR}" | |
| "--config" "${CONFIG_DIR}/config.yaml" | |
| "--auth" "password" # Use password authentication | |
| # "--disable-telemetry" # Optional: disable telemetry | |
| ) | |
| # If PASSWORD environment variable is set (from Hugging Face Secrets), use it. | |
| # The base image itself will pick up the PASSWORD env var if --auth password is set. | |
| if [ -n "${PASSWORD}" ]; then | |
| echo "Password environment variable is set. code-server will use it." | |
| else | |
| echo "WARNING: PASSWORD environment variable is not set. code-server might start without a password or with a default one if not configured otherwise." | |
| fi | |
| # The last argument is the workspace directory to open | |
| ARGS+=("${DEFAULT_WORKSPACE_PATH}") | |
| echo "Starting code-server on port ${APP_PORT} with workspace ${DEFAULT_WORKSPACE_PATH}..." | |
| # Execute code-server with all arguments | |
| # The PASSWORD env var is automatically picked up by code-server when --auth password is used. | |
| exec code-server "${ARGS[@]}" | |