dockerfile分享: ubuntu+php8.4.24+swoole6.1.8

AI摘要
【知识分享】该内容为一份Dockerfile构建脚本,用于在Ubuntu 24.04基础镜像上编译安装PHP 8.4.24、Swoole 6.1.8及GNU libiconv,并配置多个PECL扩展(redis、mongodb、grpc等)及Composer。脚本采用多阶段构建优化镜像体积,包含详细的编译参数、依赖安装及iconv功能验证逻辑,属于技术性容器配置方案。
# ------------------------------
# Builder 编译阶段 Ubuntu 24.04
# libiconv-1.17 + PHP-8.4.24 + Swoole-6.1.8
# ------------------------------
FROM ubuntu:24.04 AS builder

LABEL maintainer="zhaohao731869706@163.com"

ENV PHP_VERSION=8.4.24
ENV ICONV_VERSION=1.17
ENV SWOOLE_VERSION=6.1.8
ENV ICONV_PREFIX=/usr/local/libiconv

ENV LANG=C.UTF-8
ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND=noninteractive

# 换阿里云源 + 安装编译依赖
# 注意:Ubuntu 24.04 默认源在 /etc/apt/sources.list.d/ubuntu.sources(deb822 格式),
# 需先删除它,再写入传统格式的 aliyun 源,否则仍会走官方源拖慢速度。
RUN set -ex; \
    ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime; \
    rm -f /etc/apt/sources.list.d/ubuntu.sources; \
    printf '%s\n' \
        'deb http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse' \
        'deb http://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse' \
        'deb http://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse' \
        > /etc/apt/sources.list; \
    apt-get update -y; \
    apt-get install -y --no-install-recommends \
        gcc g++ make autoconf automake libtool bison re2c git pkg-config xz-utils \
        wget curl zip unzip ca-certificates tzdata \
        libssl-dev libffi-dev libevent-dev libc-ares-dev \
        libssh2-1-dev libcurl4-openssl-dev libpq-dev libsqlite3-dev \
        unixodbc-dev libgmp-dev libzip-dev libsodium-dev \
        libjpeg-turbo8-dev libfreetype-dev libpng-dev \
        libxml2-dev libxslt1-dev libicu-dev libonig-dev libreadline-dev \
        libbz2-dev libwebp-dev libxpm-dev libzstd-dev libsasl2-dev zlib1g-dev; \
    apt-get clean; rm -rf /var/lib/apt/lists/*

# 编译 libiconv + PHP + Swoole + Composer
RUN set -ex; \
    cd /tmp; \
    ( wget --timeout=60 --tries=3 -O libiconv.tar.gz https://mirror.tuna.tsinghua.edu.cn/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \
        || wget --timeout=60 --tries=3 -O libiconv.tar.gz https://ftp.gnu.org/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz ); \
    tar -zxf libiconv.tar.gz; \
    cd libiconv-${ICONV_VERSION}; \
    ./configure --prefix=${ICONV_PREFIX}; \
    make -j"$(nproc 2>/dev/null || echo 4)"; \
    make install; \
    cd /tmp; rm -rf libiconv-${ICONV_VERSION} libiconv.tar.gz; \
    echo "${ICONV_PREFIX}/lib" > /etc/ld.so.conf.d/libiconv.conf; \
    ldconfig; \
    \
    cd /tmp; \
    ( wget --timeout=60 --tries=3 -O php.tar.gz https://www.php.net/distributions/php-${PHP_VERSION}.tar.gz \
        || wget --timeout=60 --tries=3 -O php.tar.gz https://museum.php.net/php8/php-${PHP_VERSION}.tar.gz ); \
    tar -zxf php.tar.gz; \
    cd php-${PHP_VERSION}; \
    CPPFLAGS="-I${ICONV_PREFIX}/include" \
    LDFLAGS="-L${ICONV_PREFIX}/lib" \
    LD_LIBRARY_PATH="${ICONV_PREFIX}/lib" \
    ./configure \
        --prefix=/usr/local/php84 \
        --with-config-file-path=/usr/local/php84/lib \
        --with-config-file-scan-dir=/usr/local/php84/lib/php/conf.d \
        --disable-cgi \
        --enable-cli \
        --enable-fpm \
        --with-iconv=${ICONV_PREFIX} \
        --enable-mbstring \
        --enable-opcache=shared \
        --with-openssl \
        --with-curl \
        --enable-bcmath \
        --enable-ctype \
        --enable-calendar \
        --enable-exif \
        --enable-fileinfo \
        --enable-intl \
        --enable-pcntl \
        --enable-pdo \
        --with-pdo-mysql \
        --with-pdo-sqlite \
        --with-pdo-odbc=unixODBC,/usr \
        --enable-phar \
        --enable-posix \
        --enable-session \
        --enable-shmop \
        --enable-sockets \
        --enable-sysvshm \
        --enable-sysvsem \
        --enable-sysvmsg \
        --enable-ftp \
        --with-bz2 \
        --with-pgsql=/usr \
        --with-pdo-pgsql=/usr \
        --enable-tokenizer \
        --enable-xml \
        --enable-xmlreader \
        --enable-xmlwriter \
        --with-xsl \
        --with-zip \
        --with-sodium \
        --enable-gd \
        --with-jpeg \
        --with-freetype \
        --with-webp \
        --with-xpm \
        --with-mysqli \
        --with-sqlite3 \
        --with-gmp \
        --with-readline \
        --enable-soap; \
    make -j"$(nproc 2>/dev/null || echo 4)"; \
    make install; \
    \
    mkdir -p /usr/local/php84/lib/php/conf.d; \
    mkdir -p /usr/local/php84/etc/php-fpm.d; \
    \
    cp ./php.ini-production /usr/local/php84/lib/php.ini; \
    printf '%s\n' 'date.timezone = Asia/Shanghai' >> /usr/local/php84/lib/php.ini; \
    \
    # OPcache 需要显式以 zend_extension 方式加载,并配置 JIT 缓冲区
    printf '%s\n' \
        'zend_extension=opcache.so' \
        'opcache.enable=1' \
        'opcache.enable_cli=1' \
        'opcache.jit=1255' \
        'opcache.jit_buffer_size=128M' \
        'opcache.memory_consumption=256' \
        'opcache.max_accelerated_files=20000' \
        > /usr/local/php84/lib/php/conf.d/opcache.ini; \
    \
    cp /usr/local/php84/etc/php-fpm.conf.default /usr/local/php84/etc/php-fpm.conf; \
    cp /usr/local/php84/etc/php-fpm.d/www.conf.default /usr/local/php84/etc/php-fpm.d/www.conf; \
    sed -i 's/^user = www-data/user = root/' /usr/local/php84/etc/php-fpm.d/www.conf; \
    sed -i 's/^group = www-data/group = root/' /usr/local/php84/etc/php-fpm.d/www.conf; \
    sed -i 's|^listen = 127.0.0.1:9000|listen = 0.0.0.0:9000|' /usr/local/php84/etc/php-fpm.d/www.conf; \
    sed -i 's|^;clear_env = no|clear_env = no|' /usr/local/php84/etc/php-fpm.d/www.conf; \
    \
    cd /tmp; rm -rf php-${PHP_VERSION} php.tar.gz; \
    \
    # Swoole:优先 PECL 源(稳定),失败回退 GitHub 归档;--strip-components 兼容两种目录名
    cd /tmp; \
    ( wget --timeout=60 --tries=3 -O swoole.tgz https://pecl.php.net/get/swoole-${SWOOLE_VERSION}.tgz \
        || wget --timeout=60 --tries=3 -O swoole.tgz https://github.com/swoole/swoole-src/archive/refs/tags/v${SWOOLE_VERSION}.tar.gz ); \
    mkdir -p swoole-build; \
    tar -zxf swoole.tgz -C swoole-build --strip-components=1; \
    cd swoole-build; \
    /usr/local/php84/bin/phpize; \
    CPPFLAGS="-I${ICONV_PREFIX}/include" LDFLAGS="-L${ICONV_PREFIX}/lib" \
    ./configure --with-php-config=/usr/local/php84/bin/php-config \
        --enable-openssl \
        --enable-sockets \
        --enable-mysqlnd \
        --enable-swoole-curl \
        --enable-cares; \
    make -j"$(nproc 2>/dev/null || echo 4)"; \
    make install; \
    echo 'extension=swoole.so' > /usr/local/php84/lib/php/conf.d/swoole.ini; \
    cd /tmp; rm -rf swoole-build swoole.tgz; \
    \
    # ---- PECL 扩展:igbinary / redis / apcu / mongodb / inotify ----
    # 统一从 pecl.php.net 拉取最新稳定版编译;igbinary 必须先装(供 redis 序列化使用)
    pecl_build() { \
        n="$1"; shift; \
        cd /tmp; rm -rf "ext-${n}" "${n}.tgz"; mkdir -p "ext-${n}"; \
        wget --timeout=60 --tries=3 -O "${n}.tgz" "https://pecl.php.net/get/${n}"; \
        tar -zxf "${n}.tgz" -C "ext-${n}" --strip-components=1; \
        cd "ext-${n}"; \
        /usr/local/php84/bin/phpize; \
        ./configure --with-php-config=/usr/local/php84/bin/php-config "$@"; \
        make -j"$(nproc 2>/dev/null || echo 4)"; \
        make install; \
        cd /tmp; rm -rf "ext-${n}" "${n}.tgz"; \
    }; \
    pecl_build igbinary; \
    echo 'extension=igbinary.so' > /usr/local/php84/lib/php/conf.d/igbinary.ini; \
    pecl_build redis --enable-redis-igbinary --enable-redis-lzf --enable-redis-zstd; \
    echo 'extension=redis.so' > /usr/local/php84/lib/php/conf.d/redis.ini; \
    pecl_build apcu; \
    printf '%s\n' 'extension=apcu.so' 'apc.enable_cli=1' > /usr/local/php84/lib/php/conf.d/apcu.ini; \
    pecl_build mongodb; \
    echo 'extension=mongodb.so' > /usr/local/php84/lib/php/conf.d/mongodb.ini; \
    pecl_build inotify; \
    echo 'extension=inotify.so' > /usr/local/php84/lib/php/conf.d/inotify.ini; \
    pecl_build xlswriter; \
    echo 'extension=xlswriter.so' > /usr/local/php84/lib/php/conf.d/xlswriter.ini; \
    # protobuf 供 grpc 使用,需先装;grpc 自带 C-core,编译较慢(10~30 分钟)属正常
    pecl_build protobuf; \
    echo 'extension=protobuf.so' > /usr/local/php84/lib/php/conf.d/protobuf.ini; \
    pecl_build grpc; \
    echo 'extension=grpc.so' > /usr/local/php84/lib/php/conf.d/grpc.ini; \
    \
    # Composer:直接取阿里云镜像的 composer.phar,并配置国内 packagist 加速
    wget --timeout=60 --tries=3 -O /usr/local/php84/bin/composer https://mirrors.aliyun.com/composer/composer.phar; \
    chmod +x /usr/local/php84/bin/composer; \
    /usr/local/php84/bin/php /usr/local/php84/bin/composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ || true; \
    \
    export PATH="/usr/local/php84/bin:${PATH}"; \
    export LD_LIBRARY_PATH="${ICONV_PREFIX}/lib"; \
    php -v; \
    php -m | grep -Ei "iconv|swoole|pdo_odbc|opcache|intl|gd|mbstring|redis|mongodb|apcu|igbinary|inotify|pgsql|bz2|grpc|protobuf|xlswriter"; \
    echo '==== iconv 详情 (Linux 下 implementation 标签恒为 glibc 属正常;关键看 version 与下方 //IGNORE 实测) ===='; \
    php -i | grep -i 'iconv'; \
    echo '==== 断言1: 必须链接 GNU libiconv (version 应为 1.x, glibc 会是 2.x) ===='; \
    php -i | grep -qiE 'iconv library version => 1\.'; \
    echo '==== 断言2: //IGNORE 功能实测 (不可映射字符应被忽略, 得到 ab) ===='; \
    php -r 'error_reporting(E_ALL); $a=iconv("UTF-8","GBK//IGNORE","a\xEF\xBF\xBDb"); $b=@iconv("UTF-8","GBK//IGNORE","a\xFFb"); var_dump($a,$b); if($a!=="ab"){fwrite(STDERR,"ICONV FAIL: //IGNORE 不可映射字符未得到 ab\n");exit(1);} echo ($b==="ab"?"ICONV(GNU libiconv) OK; 非法字节也被健壮忽略\n":"ICONV(GNU libiconv) OK; 非法字节返回 ".var_export($b,true)."\n");'

# ------------------------------
# 最终运行镜像 ubuntu:24.04
# ------------------------------
FROM ubuntu:24.04

LABEL maintainer="zhaohao731869706@163.com"

ENV LANG=C.UTF-8
ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND=noninteractive
ENV PATH="/usr/local/php84/bin:/usr/local/php84/sbin:${PATH}"

# 运行期依赖:直接安装 *-dev 库包,由 apt 自动解析出正确的运行时 .so
# 依赖包(避免 Ubuntu 24.04 t64 改名导致的 “找不到包” 问题,保证一次构建成功)
RUN set -ex; \
    ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime; \
    rm -f /etc/apt/sources.list.d/ubuntu.sources; \
    printf '%s\n' \
        'deb http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse' \
        'deb http://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse' \
        'deb http://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse' \
        > /etc/apt/sources.list; \
    apt-get update -y; \
    apt-get install -y --no-install-recommends \
        libssl-dev libcurl4-openssl-dev libsqlite3-dev unixodbc-dev \
        libgmp-dev libzip-dev libsodium-dev \
        libjpeg-turbo8-dev libfreetype-dev libpng-dev \
        libxml2-dev libxslt1-dev libicu-dev libonig-dev libreadline-dev \
        libbz2-dev libwebp-dev libxpm-dev libzstd-dev libpq-dev libsasl2-dev zlib1g-dev \
        libc-ares-dev ca-certificates tzdata; \
    apt-get clean; rm -rf /var/lib/apt/lists/*; \
    mkdir -p /usr/local/php84/var/log /usr/local/php84/var/run; \
    touch /etc/odbc.ini /etc/odbcinst.ini

COPY --from=builder /usr/local/libiconv /usr/local/libiconv
COPY --from=builder /usr/local/php84 /usr/local/php84
COPY --from=builder /etc/ld.so.conf.d/libiconv.conf /etc/ld.so.conf.d/libiconv.conf

RUN ldconfig \
    && sed -i 's/^user = .*/user = root/'   /usr/local/php84/etc/php-fpm.d/www.conf \
    && sed -i 's/^group = .*/group = root/' /usr/local/php84/etc/php-fpm.d/www.conf \
    && sed -i 's|^listen = .*|listen = 0.0.0.0:9000|' /usr/local/php84/etc/php-fpm.d/www.conf

RUN php -v \
    && php -m \
    && php -r 'foreach (["iconv","swoole","pdo_odbc","opcache","intl","gd","mbstring","redis","igbinary","apcu","mongodb","inotify","pgsql","pdo_pgsql","bz2","sodium","gmp","zip","grpc","protobuf","xlswriter"] as $e) printf("%-12s %s\n", $e, extension_loaded($e) ? "OK" : "MISSING");' \
    && echo '==== 运行镜像 iconv 校验 (implementation 标签为 glibc 属正常, 看 version 与实测) ====' \
    && php -i | grep -i 'iconv' \
    && php -i | grep -qiE 'iconv library version => 1\.' \
    && php -r '$a=iconv("UTF-8","GBK//IGNORE","a\xEF\xBF\xBDb"); $b=@iconv("UTF-8","GBK//IGNORE","a\xFFb"); var_dump($a,$b); if($a!=="ab"){fwrite(STDERR,"ICONV FAIL\n");exit(1);} echo ($b==="ab"?"ICONV(GNU libiconv) OK; 非法字节也被健壮忽略\n":"ICONV(GNU libiconv) OK; 非法字节返回 ".var_export($b,true)."\n");'

EXPOSE 9000
# -R (--allow-to-run-as-root):允许以 root 运行 pool worker(容器场景常见)
CMD ["/usr/local/php84/sbin/php-fpm", "-F", "-R"]
本作品采用《CC 协议》,转载必须注明作者和本文链接
codezhao
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!