A complete cross-compilation setup for building nginx for Android using Android NDK. This project successfully builds nginx binaries for all major Android architectures with full HTTP/3 and QUIC support, HTTP/2 with proper compression, and all modern web server features.
- β Full nginx functionality on Android with all HTTP protocols
- β HTTP/3 and QUIC support with OpenSSL 3.3.2
- β HTTP/2 with proper compression using Gzip (Brotli removed to fix compatibility)
- β TLS 1.3 support for modern web standards
- β HTTP basic authentication with password hashing support
- β Cross-platform support for all Android architectures
- β DIY libcrypt implementation for Android compatibility
- β CPU affinity optimization disabled safely for Android
- β Automated build system with comprehensive scripts
- β Production-ready binaries optimized for size and performance
This is one of the most advanced nginx Android builds available, supporting all major HTTP protocols:
- HTTP/1.1 - Traditional HTTP with keep-alive
- HTTP/2 - Multiplexed connections with Gzip compression (Brotli removed for compatibility)
- HTTP/3 - Latest protocol over QUIC with UDP transport
- QUIC - Low-latency transport protocol with built-in encryption
- TLS 1.3 - Latest TLS with improved security and performance
- arm64-v8a (64-bit ARM) - Modern Android devices
- armeabi-v7a (32-bit ARM) - Older Android devices
- x86_64 (64-bit Intel) - Android emulators and Intel devices
- x86 (32-bit Intel) - Older emulators and Intel devices
- Android NDK (tested with version 27.0.12077973)
- macOS/Linux development environment
- Git for cloning dependencies
# Set your Android NDK path
export ANDROID_NDK_ROOT=~/Library/Android/sdk/ndk/27.0.12077973
# Build nginx for all architectures (this handles everything automatically)
./scripts/build-android.sh# Set your Android NDK path
export ANDROID_NDK_ROOT=~/Library/Android/sdk/ndk/27.0.12077973
# Build nginx for specific architecture only
ANDROID_ARCHS=x86_64 ./scripts/build-android.sh --arch x86_64# Clean build (remove previous build artifacts)
./scripts/build-android.sh --clean
# Skip dependency cloning (if already done)
./scripts/build-android.sh --skip-deps
# Combine options
./scripts/build-android.sh --clean --arch x86_64
# Get help
./scripts/build-android.sh --help# Deploy to Android device/emulator
./scripts/deploy.sh --arch x86_64
# Start nginx on device
adb shell /data/local/tmp/nginx/start-nginx.sh
# Test all protocols
curl http://localhost:8080/api/test # HTTP/1.1
curl -k https://localhost:8443/api/test # HTTP/2
curl -k https://localhost:8444/api/test --http3-only # HTTP/3
# Test Gzip compression
curl -k -H "Accept-Encoding: gzip" https://localhost:8443/nginx-android-build/
βββ scripts/ # Build automation scripts
β βββ android-config.sh # Android NDK configuration
β βββ build-android.sh # Main build orchestrator
β βββ build-diy-crypt.sh # Build custom libcrypt
β βββ build-nginx.sh # Build nginx with patches (Brotli removed)
β βββ build-openssl.sh # Build OpenSSL with QUIC
β βββ build-pcre2.sh # Build PCRE2
β βββ build-zlib.sh # Build zlib
β βββ clone-deps.sh # Clone source dependencies
β βββ deploy.sh # Deploy to Android device
β βββ test.sh # Test built binaries
β βββ generate-*.sh # Generate certs and test content
βββ src/ # Source code and patches
β βββ diy-crypt/ # Custom libcrypt implementation
β βββ nginx_patches/ # nginx cross-compilation patches
βββ config/ # nginx configuration files
β βββ nginx.conf # Production nginx config with Gzip
β βββ mime.types # MIME type definitions
βββ test/ # Test content and resources
β βββ html/ # Test web content
βββ certs/ # SSL certificates for testing
βββ build/ # Build output (gitignored)
β βββ install/ # Built libraries per architecture
β βββ nginx-*/ # nginx build directories
βββ README.md # This file
build-android.sh- Main build script that orchestrates the entire build processandroid-config.sh- Android NDK toolchain configuration and setupclone-deps.sh- Clone all source dependencies (nginx, OpenSSL, etc.)build-nginx.sh- Build nginx with cross-compilation patches (Brotli removed)build-diy-crypt.sh- Build custom libcrypt implementation
build-openssl.sh- Build OpenSSL 3.3.2 with QUIC supportbuild-pcre2.sh- Build PCRE2 regular expression librarybuild-zlib.sh- Build zlib compression librarybuild-libxcrypt.sh- Build alternative libxcrypt (optional)
deploy.sh- Deploy nginx to Android device/emulatortest.sh- Test the built nginx binariesgenerate-certs.sh- Generate SSL certificates for HTTPS/HTTP/3generate-test-content.sh- Generate test content for nginx
The Achievement: This build includes full HTTP/3 and QUIC support on Android - one of the first nginx Android builds to achieve this.
Technical Implementation:
- OpenSSL 3.3.2 with
enable-quicflag for QUIC protocol support - nginx 1.26.2 with
--with-http_v3_moduleenabled - All QUIC source modules compiled and working:
ngx_event_quic.c- Core QUIC event handlingngx_event_quic_transport.c- QUIC transport layerngx_event_quic_protection.c- QUIC encryption/decryptionngx_event_quic_frames.c- QUIC frame processingngx_http_v3.c- HTTP/3 protocol implementation- And 15+ other QUIC modules
Protocol Configuration:
- HTTP/1.1 on port 8080 (TCP)
- HTTP/2 on port 8443 (TCP with TLS)
- HTTP/3 on port 8444 (UDP with QUIC)
The Achievement: This build uses Gzip compression for optimal compatibility with HTTP/2 protocol.
Technical Implementation:
- Gzip Compression - Reliable compression with excellent browser compatibility
- HTTP/2 Compatibility - Brotli module removed to prevent compression conflicts
- Content-Type Detection - Automatic compression for text, CSS, JS, JSON, XML
Compression Features:
- β Dynamic Compression - Real-time gzip encoding
- β Configurable Levels - Compression level 6 (balanced speed/ratio)
- β Content-Type Filtering - Compress text, CSS, JS, JSON, XML, SVG
- β Browser Compatibility - Universal support across all browsers
- β HTTP/2 Safe - No compression conflicts with HTTP/2 protocol
Performance Benefits:
- Reduced bandwidth usage - critical for Android devices
- Faster page loads especially on mobile networks
- Better user experience with faster content delivery
- HTTP/2 compatibility - No compression errors in browsers
Build Process:
# Gzip is built into nginx core - no external dependencies needed
# Brotli module and libraries have been removed to prevent HTTP/2 conflictsThe Achievement: Full HTTP/2 support with proper browser compatibility and no compression errors.
Technical Implementation:
- Modern HTTP/2 Configuration - Uses
http2 on;directive (not deprecated syntax) - Compression Compatibility - Gzip compression works seamlessly with HTTP/2
- Browser Support - Works with Chrome, Firefox, Safari, and other modern browsers
- TLS 1.3 Integration - HTTP/2 over TLS 1.3 for maximum security
HTTP/2 Features:
- β Multiplexing - Multiple requests over single connection
- β Header Compression - HPACK compression without conflicts
- β Server Push - Ready for HTTP/2 server push (configurable)
- β Stream Prioritization - Proper request prioritization
- β Binary Protocol - Efficient binary framing
The Challenge: Android doesn't provide libcrypt, which nginx requires for HTTP basic authentication. Most solutions simply disable this functionality, but we took a different approach.
Our Solution: We implemented a complete DIY libcrypt library based on OpenSSL that provides full compatibility with standard Unix crypt functions.
- β Complete crypt() API - Standard Unix crypt functions
- β OpenSSL DES Implementation - Uses authentic DES encryption from OpenSSL
- β Traditional Unix crypt() - 13-character output (2 salt + 11 hash)
- β
Thread-Safe Operations -
crypt_r()with proper crypt_data structure - β
Extended Functions -
crypt_rn(),crypt_ra(),crypt_gensalt*() - β Proper Salt Validation - ASCII64 character set validation
- β Error Handling - errno and failure tokens as per standards
- β Memory Safety - Sensitive data clearing and bounds checking
- Algorithm: Traditional DES with 25 iterations (authentic Unix crypt)
- Salt Format: 2-character ASCII64 salt (./0-9A-Za-z)
- Output Format: 13 characters total (compatible with standard crypt)
- Dependencies: Uses existing OpenSSL (already required by nginx)
- Size: Lightweight ~2KB static library
- Performance: Optimized for Android with minimal overhead
This implementation ensures that nginx on Android has full HTTP basic authentication support without compromising on security or compatibility.
The Challenge: Android doesn't provide the cpu_set_t type and CPU affinity functions that nginx uses for performance optimization.
Our Solution: Implemented a combined patch that safely disables CPU affinity on Android without affecting performance.
- β
Header File Modifications - Disables CPU affinity in
ngx_setaffinity.h - β
Source File Modifications - Wraps all CPU affinity code in
ngx_setaffinity.c - β
Android Detection - Uses
#if defined(__ANDROID__)guards - β No Performance Impact - nginx worker processes still distribute load effectively
- β Maintainable Code - Single patch file instead of multiple separate patches
The build system includes 8 patches to make nginx cross-compile successfully:
01-cross-compilation-sizeof.patch- Fix sizeof detection for cross-compilation02-cross-compilation-feature.patch- Fix feature detection when cross-compiling03-android-os-detection.patch- Proper Android OS detection04-android-enable-diy-crypt.patch- Enable our OpenSSL-based DIY crypt05-android-linux-config.patch- Android-specific Linux configuration06-android-unix-crypt.patch- Additional crypt detection with OpenSSL libs07-android-epoll-macros.patch- Fix epoll macros for Android08-android-cpu-affinity.patch- NEW: Combined CPU affinity patch for Android
- Static linking - All dependencies statically linked for portability
- Size optimization - Binaries optimized for size with
-Osflag - Function/data sections - Enable garbage collection of unused code
- Strip symbols - Remove debug symbols for smaller binaries
- QUIC enabled - OpenSSL built with
enable-quicfor HTTP/3 support
- nginx 1.26.2 - Latest stable version with HTTP/3 support
- OpenSSL 3.3.2 - For TLS/SSL and QUIC support
- PCRE2 - Regular expression support
- zlib - Compression support
- DIY libcrypt - OpenSSL DES-based password hashing implementation
- Cross-compilation patches - nginx modifications for Android compatibility
- Combined CPU affinity patch - Android-specific performance optimization
After successful build, you'll find nginx binaries at:
build/install/{architecture}/nginx/sbin/nginx
The complete installation structure:
build/install/{architecture}/
βββ nginx/
β βββ sbin/nginx # Main nginx binary with HTTP/3
β βββ conf/ # Configuration files
β βββ html/ # Default web content
β βββ logs/ # Log directory
βββ lib/ # Static libraries (OpenSSL, zlib, PCRE2, libcrypt)
βββ include/ # Header files
- arm64-v8a: ~5.4MB
- armeabi-v7a: ~4.2MB
- x86_64: ~5.3MB
- x86: ~5.6MB
Built with the following modules:
--with-http_ssl_module # HTTPS support
--with-http_v2_module # HTTP/2 support
--with-http_v3_module # HTTP/3 and QUIC support
--with-http_realip_module # Real IP detection
--with-http_gzip_static_module # Static gzip compression
--with-http_stub_status_module # Status monitoring
--with-pcre-jit # JIT regex compilation
# Test the DIY crypt implementation
cd src/diy-crypt
make test
# Expected output:
# β
Different salts produce different hashes
# β
Different passwords produce different hashes
# β
Consistency check passes
# β
Salt validation works correctly
# β
Extended functions work
# β
Salt generation works# Deploy to device
./scripts/deploy.sh --arch x86_64
# Start nginx
adb shell /data/local/tmp/nginx/start-nginx.sh
# Test all protocols
adb forward tcp:8080 tcp:8080
adb forward tcp:8443 tcp:8443
adb forward udp:8444 udp:8444
curl http://localhost:8080/api/test # HTTP/1.1
curl -k https://localhost:8443/api/test # HTTP/2
curl -k https://localhost:8444/api/test --http3-only # HTTP/3# Test Gzip compression
curl -k -H "Accept-Encoding: gzip" https://localhost:8443/css/style.css
# Should return: Content-Encoding: gzip
# Test without compression
curl -k -H "Accept-Encoding: identity" https://localhost:8443/css/style.css
# Should return: No Content-Encoding header
# Check compression headers
curl -k -I -H "Accept-Encoding: gzip" https://localhost:8443/
# Should return: Vary: Accept-EncodingNDK Path Issues
# Make sure NDK path is correct
export ANDROID_NDK_ROOT=/path/to/your/ndkBuild Failures
# Clean build directories
rm -rf build/
# Rebuild with clean flag
./scripts/build-android.sh --cleanHTTP/3 Not Working
# Verify nginx version includes HTTP/3
adb shell "/data/local/tmp/nginx/sbin/nginx -V" | grep http_v3_module
# Check QUIC ports are listening
adb shell "netstat -ln | grep 8444"Missing Dependencies
# Ensure you have required tools
which git make patch curlThis project represents several significant achievements in nginx Android development:
- First HTTP/3 and QUIC support on Android nginx
- HTTP/2 with proper compression - Gzip compression without browser conflicts
- Complete DIY libcrypt implementation for HTTP basic auth
- Combined CPU affinity patch for cleaner Android compatibility
- All Android architectures supported with single build system
- Production-ready binaries with full feature set
- Comprehensive testing and deployment framework
This project is open source. nginx is licensed under the 2-clause BSD license. Dependencies have their respective licenses.