serversideup/docker-php

Alpine version of NGINX Unit does not exist: no PHP embed SAPI found

jaydrogers opened this issue · 3 comments

Affected Docker Images

  • *-unit-alpine

Current Behavior

When attempting to build an Alpine version of Unit, the build fails with this error:

23.87 creating build/Makefile
24.03 
24.03 Unit configuration summary:
24.03 
24.03   bin directory: ............. "/usr/bin"
24.03   sbin directory: ............ "/usr/sbin"
24.03   lib directory: ............. "/usr/lib"
24.03   include directory: ......... "/usr/include"
24.03   pkgconfig directory: ....... "/usr/share/pkgconfig"
24.03   man pages directory: ....... "/usr/share/man"
24.03   modules directory: ......... "/usr/lib/unit/debug-modules"
24.03   state directory: ........... "/var/lib/unit"
24.03   tmp directory: ............. "/var/tmp"
24.03 
24.03   pid file: .................. "/var/run/unit.pid"
24.03   log file: .................. "/dev/stdout"
24.03 
24.03   control API socket: ........ "unix:/var/run/control.unit.sock"
24.03 
24.03   non-privileged user: ....... "www-data"
24.03   non-privileged group: ...... "www-data"
24.03 
24.03   IPv6 support: .............. YES
24.03   Unix domain sockets support: YES
24.03   TLS support: ............... YES
24.03   Regex support: ............. YES
24.03   NJS support: ............... NO
24.03 
24.03   process isolation: ......... USER NS PID NET UTS CGROUP
24.03   cgroupv2: .................. YES
24.03 
24.03   debug logging: ............. YES
24.03 
24.03 + ./configure php
24.03 configuring PHP module
24.03 checking for PHP ... found
24.04  + PHP SAPI: [cli phpdbg cgi]
24.04 checking for PHP version ... not found
24.12 checking for PHP embed SAPI ... not found
24.19 
24.19 ./configure: error: no PHP embed SAPI found.

Reason why this is failing

PHP excluded embed for the Alpine versions

Expected Behavior

Unit should be able to compile and deliver an Alpine version.

Steps To Reproduce

Attempt to build an Alpine version locally:

bash scripts/dev.sh --variation unit --version 8.2.12 --os alpine

👉 Next Steps & Proposed Solution

Notes on how development works

https://serversideup.net/open-source/docker-php/docs/getting-started/contributing

Add Embed support

Example: 358f225

Update installer to support Debian and Alpine

mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules && \
cd /usr/src/ && \
hg clone -u ${NGINX_UNIT_VERSION} https://hg.nginx.org/unit && \
cd unit && \
NCPU="$(getconf _NPROCESSORS_ONLN)" && \
DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" && \
CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" && \
LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" && \
CONFIGURE_ARGS_MODULES="--prefix=/usr \
--statedir=/var/lib/unit \
--control=unix:/var/run/control.unit.sock \
--runstatedir=/var/run \
--pid=/var/run/unit.pid \
--logdir=/var/log \
--log=/dev/stdout \
--tmpdir=/var/tmp \
--user=www-data \
--group=www-data \
--openssl \
--libdir=/usr/lib/$DEB_HOST_MULTIARCH" && \
CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES --njs" && \
make -j $NCPU -C pkg/contrib .njs && \
export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build && \
./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug && \
make -j $NCPU unitd && \
install -pm755 build/sbin/unitd /usr/sbin/unitd-debug && \
make clean && \
./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules && \
make -j $NCPU unitd && \
install -pm755 build/sbin/unitd /usr/sbin/unitd && \
make clean && \
/bin/true && \
./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug && \
./configure php && \
make -j $NCPU php-install && \
make clean && \
./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules && \
./configure php && \
make -j $NCPU php-install && \
mkdir -p /var/lib/unit/

  • Break the scripts into two separate files
  • Load the script based on the OS installing

Features to support

  • Compile NGINX Unit from source with the provided PHP version from the base image
  • Enable the copying of unitd for "production use"
  • Enable the copying of unitd-debug for debug use

Important notes on current functionality

  • We will continue to use the "Docker CMD Override" currently in place

https://github.com/serversideup/docker-php/blob/main/src/variations/unit/etc/entrypoint.d/10-init-unit.sh#L192

Validating functionality

  • Ensure 8.3.12 works with bookworm
bash scripts/dev.sh --variation unit --version 8.3.13 --os bookworm
  • Ensure 8.3.12 works with alpine
bash scripts/dev.sh --variation unit --version 8.3.13 --os  alpine
  • Ensure 7.4.33 works with bullseye
bash scripts/dev.sh --variation unit --version 7.4.33 --os bullseye
  • Ensure 7.4.33 works with alpine
bash scripts/dev.sh --variation unit --version 7.4.33 --os  alpine
beeyev commented

Also have the same problem

EDIT 2

Sorry, now I see you use the official php image as the base image.

But the php zts build includes SAPI:
https://github.com/docker-library/php/blob/6c4b77d14c604deefd63fd6d39133f9a1f7a83c3/8.3/alpine3.18/zts/Dockerfile#L166


EDIT

Now I see that you build it from source code, I don't know if you've tried it yet, but there is such an option:
./configure --enable-embed


This is what I used when I first tried with the nginx unit, it's not perfect, but maybe it helps. I haven't dealt with it since then, maybe SAPI has been removed from it since then.

FROM alpine:3.14

# Install packages and remove default server definition
RUN apk --no-cache add php7 php7-zip php7-intl php7-opcache php7-json php7-openssl php7-curl php7-tokenizer php7-exif php7-pcntl \
    php7-zlib php7-xml php7-phar php7-dom php7-xmlreader php7-ctype php7-session php7-fileinfo php7-pdo_mysql \
    php7-mbstring php7-gd php7-bcmath php7-gd php7-mcrypt php7-iconv unit unit-openrc unit-php7 curl \
    git \
    libpng-dev \
    libxml2-dev \
    zip \
    unzip \
    && ln -sf /dev/stdout /var/log/unit.log \
    && ln -sf /dev/stdout /var/log/access.log

# Configure unit
COPY docker/nginx-unit/config.json /var/lib/unit/conf.json

# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Make sure files/folders needed by the processes are accessable when they run under the unit user
RUN mkdir -p /.composer && \
    mkdir -p /run/php && \
    mkdir -p /var/www && \
    chown -R unit:unit /var/www && \
    chown -R unit:unit /.composer

# Set working directory
WORKDIR /var/www

# install all PHP dependencies
COPY --chown=unit src/composer.lock .
COPY --chown=unit src/composer.json .
RUN composer install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader

# Add application
COPY --chown=unit src/ .

COPY --chown=unit ./docker/.env ./.env

RUN composer dump-autoload

RUN php artisan optimize && php artisan config:cache && php artisan route:cache

EXPOSE 8080

CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]

# TODO: Implement HEALTHCHECK
# HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost/fpm-ping || exit 1

Thanks for posting your solution @draxvint.

Update on this issue

I just got off the call with the extremely helpful and knowledgeable @tippexs from the NGINX Unit team.

Timo will be helping us out on getting a solution here: #259

Stay tuned 😃