mirror of
https://github.com/Qbix/webserver.git
synced 2026-07-22 07:57:23 +02:00
Initial release — pure PHP web server, 55-73% of nginx throughput
Standalone server with zero dependencies beyond PHP 8.1+. Static files with in-memory response cache, keep-alive, TCP_NODELAY, gzip/brotli, WebSocket, live dashboard, rate limiting. Includes PHAR builder and GitHub Actions CI for static binaries (Linux x86_64, Linux ARM64, macOS x86_64, macOS Apple Silicon).
This commit is contained in:
+176
@@ -0,0 +1,176 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Build a self-contained Qbix Server binary.
|
||||
#
|
||||
# The binary includes the PHP interpreter + all server code.
|
||||
# No PHP installation needed on the target machine.
|
||||
#
|
||||
# Usage: ./build-binary.sh [--arch=x86_64|aarch64] [--os=linux|macos]
|
||||
#
|
||||
# Prerequisites:
|
||||
# - Docker (for cross-compilation) or local build tools
|
||||
# - ~2GB disk space for the build
|
||||
#
|
||||
# Output: bin/qbix-server (or bin/qbix-server-$OS-$ARCH)
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
BIN_DIR="$SCRIPT_DIR/bin"
|
||||
SRC_DIR="$SCRIPT_DIR/src"
|
||||
|
||||
ARCH="${ARCH:-$(uname -m)}"
|
||||
OS="${OS:-linux}"
|
||||
PHP_VERSION="8.3"
|
||||
|
||||
# Parse args
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--arch=*) ARCH="${arg#*=}" ;;
|
||||
--os=*) OS="${arg#*=}" ;;
|
||||
--help)
|
||||
echo "Usage: $0 [--arch=x86_64|aarch64] [--os=linux|macos]"
|
||||
echo ""
|
||||
echo "Builds a self-contained Qbix Server binary."
|
||||
echo "Requires Docker for cross-compilation."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
mkdir -p "$BIN_DIR"
|
||||
|
||||
echo "═══════════════════════════════════════════"
|
||||
echo " Building Qbix Server binary"
|
||||
echo " PHP: $PHP_VERSION"
|
||||
echo " OS: $OS"
|
||||
echo " Arch: $ARCH"
|
||||
echo "═══════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# ── Method 1: static-php-cli (preferred) ─────────
|
||||
|
||||
build_with_static_php_cli() {
|
||||
echo "Using static-php-cli..."
|
||||
|
||||
# Check if static-php-cli is available
|
||||
if ! command -v spc &>/dev/null; then
|
||||
echo "Installing static-php-cli..."
|
||||
# Download the latest release
|
||||
SPC_URL="https://github.com/crazywhalecc/static-php-cli/releases/latest/download/spc-linux-x86_64.tar.gz"
|
||||
if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
||||
SPC_URL="https://github.com/crazywhalecc/static-php-cli/releases/latest/download/spc-linux-aarch64.tar.gz"
|
||||
fi
|
||||
curl -sL "$SPC_URL" | tar xz -C /tmp/
|
||||
chmod +x /tmp/spc
|
||||
SPC="/tmp/spc"
|
||||
else
|
||||
SPC="spc"
|
||||
fi
|
||||
|
||||
# Build PHP micro SAPI with required extensions
|
||||
$SPC doctor --auto-fix 2>/dev/null || true
|
||||
$SPC download --with-php=$PHP_VERSION \
|
||||
--for-extensions=pcntl,sockets,openssl,mbstring,filter,ctype,tokenizer
|
||||
$SPC build \
|
||||
pcntl,sockets,openssl,mbstring,filter,ctype,tokenizer \
|
||||
--build-micro \
|
||||
--debug
|
||||
|
||||
MICRO_SFXN="buildroot/bin/micro.sfx"
|
||||
|
||||
# First build the PHAR, then cat micro.sfx + phar = binary
|
||||
echo "Building PHAR for embedding..."
|
||||
php -d phar.readonly=0 "$SCRIPT_DIR/build-phar.php"
|
||||
|
||||
echo "Combining micro.sfx + PHAR..."
|
||||
cat "$MICRO_SFXN" "$BIN_DIR/qbix-server.phar" > "$BIN_DIR/qbix-server"
|
||||
chmod +x "$BIN_DIR/qbix-server"
|
||||
|
||||
echo ""
|
||||
echo "Binary built: $BIN_DIR/qbix-server"
|
||||
ls -lh "$BIN_DIR/qbix-server"
|
||||
}
|
||||
|
||||
# ── Method 2: Docker-based build ─────────────────
|
||||
|
||||
build_with_docker() {
|
||||
echo "Using Docker for isolated build..."
|
||||
|
||||
# Create a temporary Dockerfile
|
||||
TMPDIR=$(mktemp -d)
|
||||
cp -r "$SRC_DIR" "$TMPDIR/src"
|
||||
cp "$SCRIPT_DIR/build-phar.php" "$TMPDIR/"
|
||||
|
||||
cat > "$TMPDIR/Dockerfile" << 'DOCKERFILE'
|
||||
FROM php:8.3-cli-alpine AS builder
|
||||
|
||||
RUN apk add --no-cache curl bash tar
|
||||
|
||||
# Install static-php-cli
|
||||
RUN curl -sL https://github.com/crazywhalecc/static-php-cli/releases/latest/download/spc-linux-x86_64.tar.gz \
|
||||
| tar xz -C /usr/local/bin/ && chmod +x /usr/local/bin/spc
|
||||
|
||||
WORKDIR /build
|
||||
COPY src/ src/
|
||||
COPY build-phar.php .
|
||||
|
||||
# Build PHAR first
|
||||
RUN mkdir -p bin && php -d phar.readonly=0 build-phar.php
|
||||
|
||||
# Download PHP sources and build micro SAPI
|
||||
RUN spc doctor --auto-fix 2>/dev/null || true
|
||||
RUN spc download --with-php=8.3 --for-extensions=pcntl,sockets,openssl,mbstring,filter
|
||||
RUN spc build pcntl,sockets,openssl,mbstring,filter --build-micro
|
||||
|
||||
# Combine
|
||||
RUN cat buildroot/bin/micro.sfx bin/qbix-server.phar > bin/qbix-server && \
|
||||
chmod +x bin/qbix-server
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /build/bin/qbix-server /qbix-server
|
||||
DOCKERFILE
|
||||
|
||||
docker build -t qbix-server-builder "$TMPDIR"
|
||||
docker create --name qbix-extract qbix-server-builder
|
||||
docker cp qbix-extract:/qbix-server "$BIN_DIR/qbix-server"
|
||||
docker rm qbix-extract
|
||||
docker rmi qbix-server-builder 2>/dev/null || true
|
||||
|
||||
rm -rf "$TMPDIR"
|
||||
|
||||
echo ""
|
||||
echo "Binary built: $BIN_DIR/qbix-server"
|
||||
ls -lh "$BIN_DIR/qbix-server"
|
||||
}
|
||||
|
||||
# ── Method 3: Manual build (fallback) ────────────
|
||||
|
||||
build_manual() {
|
||||
echo "Building PHAR (binary build requires static-php-cli or Docker)..."
|
||||
php -d phar.readonly=0 "$SCRIPT_DIR/build-phar.php"
|
||||
|
||||
echo ""
|
||||
echo "PHAR built. For a static binary, install static-php-cli or use Docker:"
|
||||
echo " Method A: curl -sL https://github.com/crazywhalecc/static-php-cli/... | tar xz"
|
||||
echo " Method B: $0 --docker"
|
||||
echo ""
|
||||
echo "The PHAR works identically: php bin/qbix-server.phar --port=8080"
|
||||
}
|
||||
|
||||
# ── Choose build method ──────────────────────────
|
||||
|
||||
if [ "$1" = "--docker" ] && command -v docker &>/dev/null; then
|
||||
build_with_docker
|
||||
elif command -v spc &>/dev/null || [ -f /tmp/spc ]; then
|
||||
build_with_static_php_cli
|
||||
elif command -v docker &>/dev/null; then
|
||||
echo "static-php-cli not found, falling back to Docker build..."
|
||||
build_with_docker
|
||||
else
|
||||
build_manual
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Done."
|
||||
Reference in New Issue
Block a user