#!/bin/bash # Info: Script to install Coder # Author: Provisioning System # Release: 1.0 # Date: 2025-07-24 USAGE="install-coder.sh" [ "$1" == "-h" ] && echo "$USAGE" && exit 1 [ -r "env-coder" ] && . ./env-coder CODER_VERSION=${CODER_VERSION:-2.23.4} # Determine architecture ARCH="$(uname -m)" case $ARCH in x86_64) ARCH="amd64" ;; aarch64) ARCH="arm64" ;; armv7*) ARCH="armv7" ;; *) echo "Unsupported architecture: $ARCH" && exit 1 ;; esac # Determine OS OS="$(uname -s | tr '[:upper:]' '[:lower:]')" case $OS in linux) OS="linux" ;; darwin) OS="darwin" ;; *) echo "Unsupported OS: $OS" && exit 1 ;; esac CODER_URL=https://github.com/coder/coder/releases/download CODER_BINARY=v${CODER_VERSION}/coder_${CODER_VERSION}_${OS}_${ARCH}.tar.gz CODER_ARCHIVE=coder_${CODER_VERSION}_${OS}_${ARCH}.tar.gz CODER_RUN_PATH=${CODER_RUN_PATH:-/usr/local/bin/coder} CODER_SYSTEMCTL_MODE=${CODER_SYSTEMCTL_MODE:-enabled} CODER_CONFIG_PATH=${CODER_CONFIG_PATH:-/etc/coder} CODER_WORK_PATH=${CODER_WORK_PATH:-/var/lib/coder} CODER_RUN_USER=${CODER_RUN_USER:-coder} CODER_RUN_GROUP=${CODER_RUN_GROUP:-coder} CODER_RUN_USER_HOME=${CODER_RUN_USER_HOME:-/home/coder} CODER_ACCESS_URL=${CODER_ACCESS_URL:-http://localhost:7080} CODER_HTTP_ADDRESS=${CODER_HTTP_ADDRESS:-0.0.0.0:7080} echo "Installing Coder ${CODER_VERSION}..." # Install dependencies echo "Installing dependencies..." if command -v apt-get >/dev/null 2>&1; then apt-get update apt-get install -y curl ca-certificates git elif command -v yum >/dev/null 2>&1; then yum update -y yum install -y curl ca-certificates git elif command -v dnf >/dev/null 2>&1; then dnf update -y dnf install -y curl ca-certificates git else echo "Package manager not found. Please install curl, ca-certificates, and git manually." exit 1 fi # Create user and group if ! id "$CODER_RUN_USER" &>/dev/null; then groupadd -r "$CODER_RUN_GROUP" useradd -r -g "$CODER_RUN_GROUP" -d "$CODER_RUN_USER_HOME" -s /bin/bash -c "Coder service user" "$CODER_RUN_USER" fi # Create directories mkdir -p "$CODER_CONFIG_PATH" mkdir -p "$CODER_WORK_PATH" mkdir -p "$CODER_RUN_USER_HOME" # Download and install Coder cd /tmp echo "Downloading Coder from ${CODER_URL}/${CODER_BINARY}..." curl -L -o "$CODER_ARCHIVE" "${CODER_URL}/${CODER_BINARY}" if [ ! -f "$CODER_ARCHIVE" ]; then echo "Failed to download Coder archive" exit 1 fi # Extract and install binary echo "Extracting Coder..." tar -xzf "$CODER_ARCHIVE" if [ ! -f "coder" ]; then echo "Failed to extract Coder binary" exit 1 fi # Install binary chmod +x coder mv coder "$(dirname "$CODER_RUN_PATH")/" # Create environment file cat > "$CODER_CONFIG_PATH/coder.env" << EOF CODER_ACCESS_URL=$CODER_ACCESS_URL CODER_HTTP_ADDRESS=$CODER_HTTP_ADDRESS CODER_CONFIG_DIR=$CODER_WORK_PATH EOF # Load additional environment variables from template if available if [ -f "env-coder" ]; then cat env-coder >> "$CODER_CONFIG_PATH/coder.env" fi # Set ownership chown -R "$CODER_RUN_USER:$CODER_RUN_GROUP" "$CODER_WORK_PATH" chown -R "$CODER_RUN_USER:$CODER_RUN_GROUP" "$CODER_RUN_USER_HOME" chown -R "$CODER_RUN_USER:$CODER_RUN_GROUP" "$CODER_CONFIG_PATH" # Create systemd service file cat > /etc/systemd/system/coder.service << EOF [Unit] Description=Coder Development Environment Platform Documentation=https://coder.com/docs After=network-online.target Wants=network-online.target $(if [ "${CODER_DATABASE_TYPE:-postgresql}" = "postgresql" ] && [ -z "$CODER_PG_CONNECTION_URL" ]; then echo "After=postgresql.service"; echo "Wants=postgresql.service"; fi) [Service] Type=simple User=$CODER_RUN_USER Group=$CODER_RUN_GROUP EnvironmentFile=$CODER_CONFIG_PATH/coder.env WorkingDirectory=$CODER_WORK_PATH ExecStart=$CODER_RUN_PATH server ExecReload=/bin/kill -HUP \$MAINPID Restart=always RestartSec=10 # Security settings NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=$CODER_WORK_PATH $CODER_CONFIG_PATH CapabilityBoundingSet=CAP_NET_BIND_SERVICE # Resource limits LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF # Initialize Coder database and first user if needed echo "Initializing Coder server..." sudo -u "$CODER_RUN_USER" bash -c " export CODER_CONFIG_DIR='$CODER_WORK_PATH' export CODER_ACCESS_URL='$CODER_ACCESS_URL' export CODER_HTTP_ADDRESS='$CODER_HTTP_ADDRESS' cd '$CODER_WORK_PATH' if [ ! -f '$CODER_WORK_PATH/.initialized' ]; then timeout 30 '$CODER_RUN_PATH' server --init-only 2>/dev/null || true touch '$CODER_WORK_PATH/.initialized' fi " # Enable and start service systemctl daemon-reload systemctl "$CODER_SYSTEMCTL_MODE" coder.service if [ "$CODER_SYSTEMCTL_MODE" = "enabled" ]; then systemctl start coder.service # Wait a moment for service to start sleep 5 fi # Cleanup cd / rm -rf /tmp/"$CODER_ARCHIVE" /tmp/coder echo "Coder installation completed!" echo "Service: coder.service" echo "Coder Server available at: $CODER_ACCESS_URL" echo "Configuration: $CODER_CONFIG_PATH/coder.env" echo "Data directory: $CODER_WORK_PATH" # Display service status if systemctl is-active --quiet coder.service; then echo "✅ Coder service is running" echo "" echo "First time login:" echo "1. Open $CODER_ACCESS_URL in a browser" echo "2. Create your first admin user account" echo "3. Start creating workspaces and templates" else echo "⚠️ Coder service status:" systemctl status coder.service --no-pager -l fi