Skip to content

Instantly share code, notes, and snippets.

@njames
Last active March 31, 2026 03:55
Show Gist options
  • Select an option

  • Save njames/d35d0983228784b06ebeb3bb240dc4ca to your computer and use it in GitHub Desktop.

Select an option

Save njames/d35d0983228784b06ebeb3bb240dc4ca to your computer and use it in GitHub Desktop.
Install MS SQL Server, PHP-FPM and Nginx
#!/usr/bin/env bash
# =============================================================================
# install_wsl_stack.sh
# Installs: MS ODBC Driver + sqlsrv tools, Nginx, PHP-FPM, sqlsrv/pdo_sqlsrv
# Target: Ubuntu 22.04 / 24.04 on WSL2
# Usage: chmod +x install_wsl_stack.sh && ./install_wsl_stack.sh
# =============================================================================
set -euo pipefail
PHP_VERSION="8.5"
UBUNTU_VERSION=$(lsb_release -rs)
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
section() { echo -e "\n${YELLOW}==============================${NC}"; echo -e "${YELLOW} $*${NC}"; echo -e "${YELLOW}==============================${NC}"; }
# ── Root check ────────────────────────────────────────────────────────────────
[[ $EUID -ne 0 ]] && error "Run as root or with sudo: sudo ./install_wsl_stack.sh"
# =============================================================================
# 1. SYSTEM PREREQUISITES
# =============================================================================
section "1. System Prerequisites"
apt-get update -qq
apt-get upgrade -y
apt-get install -y \
curl gnupg2 software-properties-common \
apt-transport-https lsb-release ca-certificates \
unzip build-essential unixodbc-dev
info "Prerequisites installed."
# =============================================================================
# 2. MICROSOFT ODBC DRIVER + SQL TOOLS
# =============================================================================
section "2. Microsoft ODBC Driver 18 + sqlcmd"
MSSQL_LIST="/etc/apt/sources.list.d/mssql-release.list"
if [[ ! -f "$MSSQL_LIST" ]]; then
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
| gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
curl -fsSL "https://packages.microsoft.com/config/ubuntu/${UBUNTU_VERSION}/prod.list" \
| tee "$MSSQL_LIST"
info "Microsoft repo added."
else
warn "Microsoft repo already present — skipping."
fi
apt-get update -qq
ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18
# Add tools to PATH for all users
PROFILE_LINE='export PATH="$PATH:/opt/mssql-tools18/bin"'
grep -qxF "$PROFILE_LINE" /etc/profile.d/mssql-tools.sh 2>/dev/null \
|| echo "$PROFILE_LINE" > /etc/profile.d/mssql-tools.sh
info "sqlcmd + bcp installed. Run 'source /etc/profile.d/mssql-tools.sh' to update PATH."
# =============================================================================
# 3. NGINX
# =============================================================================
section "3. Nginx"
apt-get install -y nginx
service nginx start || warn "nginx start failed — may need manual start in WSL."
info "Nginx installed."
# =============================================================================
# 4. PHP ${PHP_VERSION} + PHP-FPM
# =============================================================================
section "4. PHP ${PHP_VERSION} & PHP-FPM"
# Add Ondřej Surý PPA
add-apt-repository -y ppa:ondrej/php
apt-get update -qq
apt-get install -y \
php${PHP_VERSION}-fpm \
php${PHP_VERSION}-cli \
php${PHP_VERSION}-dev \
php${PHP_VERSION}-common \
php${PHP_VERSION}-mbstring \
php${PHP_VERSION}-xml \
php${PHP_VERSION}-curl \
php${PHP_VERSION}-zip \
php${PHP_VERSION}-intl \
php${PHP_VERSION}-bcmath \
php${PHP_VERSION}-gd \
php-pear
service php${PHP_VERSION}-fpm start || warn "php-fpm start failed — may need manual start in WSL."
info "PHP ${PHP_VERSION}-FPM installed."
# =============================================================================
# 5. sqlsrv + pdo_sqlsrv PECL EXTENSIONS
# =============================================================================
section "5. sqlsrv & pdo_sqlsrv PHP Extensions"
pecl channel-update pecl.php.net
# Install extensions (|| true avoids exit if already installed)
printf "\n" | pecl install sqlsrv || warn "sqlsrv may already be installed."
printf "\n" | pecl install pdo_sqlsrv || warn "pdo_sqlsrv may already be installed."
# Write ini files
for EXT in sqlsrv pdo_sqlsrv; do
INI_PATH="/etc/php/${PHP_VERSION}/mods-available/${EXT}.ini"
[[ -f "$INI_PATH" ]] || echo "extension=${EXT}.so" > "$INI_PATH"
done
# Enable for CLI and FPM
phpenmod -v ${PHP_VERSION} sqlsrv pdo_sqlsrv
service php${PHP_VERSION}-fpm restart || warn "php-fpm restart failed — restart manually."
info "sqlsrv & pdo_sqlsrv enabled."
# =============================================================================
# 6. NGINX ↔ PHP-FPM CONFIGURATION
# =============================================================================
section "6. Nginx + PHP-FPM Site Config"
SITE_CONF="/etc/nginx/sites-available/default"
WEB_ROOT="/var/www/html"
cat > "$SITE_CONF" <<EOF
server {
listen 80 default_server;
listen [::]:80 default_server;
root ${WEB_ROOT};
index index.php index.html index.htm;
server_name _;
location / {
try_files \$uri \$uri/ =404;
}
location ~ \.php\$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php${PHP_VERSION}-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
EOF
# Drop a phpinfo test page
cat > "${WEB_ROOT}/info.php" <<'EOF'
<?php phpinfo();
EOF
nginx -t && service nginx reload
info "Nginx configured and reloaded."
# =============================================================================
# 7. VERIFICATION
# =============================================================================
section "7. Verification"
echo ""
info "PHP version: $(php -r 'echo PHP_VERSION;')"
info "Loaded extensions:"
php -m | grep -E "sqlsrv|pdo_sqlsrv|mbstring|curl|xml" | sed 's/^/ ✔ /'
echo ""
info "sqlcmd path: $(which sqlcmd 2>/dev/null || echo 'not in current PATH — source /etc/profile.d/mssql-tools.sh')"
info "Nginx config test: $(nginx -t 2>&1 | tr '\n' ' ')"
echo ""
echo -e "${GREEN}✅ Installation complete!${NC}"
echo -e " → Test PHP-FPM via browser/curl: http://localhost/info.php"
echo -e " → Remove info.php when done: rm ${WEB_ROOT}/info.php"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment