grpc
grpc copied to clipboard
PHP: `pecl install` is still slow and still produces massive binaries
What version of gRPC and what language are you using?
- All versions of gRPC
- PHP
What operating system (Linux, Windows,...) and version?
- Linux (all versions)
What runtime / compiler are you using (e.g. python version or version of gcc)
- pecl (all versions)
What did you do?
Please provide either 1) A unit test for reproducing the bug or 2) Specific steps for us to follow to reproduce the bug. If there’s not enough information to debug the problem, gRPC team may close the issue at their discretion. You’re welcome to re-open the issue once you have a reproduction.
time sudo pecl install grpc
What did you expect to see?
The extension install in a reasonable timeframe and at a reasonable size
What did you see instead?
The extension install takes on the order of 30 minutes, and produces a ~50MB binary that is ~10x larger than intended due to the inclusion of debug symbols (which should not be present in builds created or distributed this way).
Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).
See TROUBLESHOOTING.md for how to diagnose problems better.
Anything else we should know about your project / environment?
Please see the existing discussion at #23626.
I'm opening this as a new Issue because the previous one was closed seemingly by accident (and I lack the permissions to reopen it). If that Issue can be reopened, this one can be closed as a duplicate. Until then, the problem risks not being tracked or mitigated.
I confirm. The problem is relevant. I get 30 minutes to install the extension. Exactly because of this problem, I’m already thinking about rewriting my application into another programming language, just so as not to encounter this extension again.
i confirm too. Install grpc with pecl takes more then 30 Minutes. in Docker environment.
But even the build from source, explained here https://github.com/grpc/grpc/tree/master/src/php#build-from-source takes about 20 Minutes with make -j 4 in a docker environment.
So i thinks its not only with pecl.
during build i can see that the most time is used by building all the third_party extensions
the library is really big i think:
ls -lah /usr/local/lib/php/extensions/no-debug-non-zts-20210902/grpc.so
-rw-r--r-- 1 root root 217.3M Oct 23 11:14 /usr/local/lib/php/extensions/no-debug-non-zts-20210902/grpc.so
setting ENV MAKEFLAGS=" -j 4" with pecl speeds it up to about 15 Minutes build time
You can strip the debug symbols using strip --strip-debug /usr/local/lib/php/extensions/*/grpc.so, which will reduce the size of the binary considerably. Make sure to do it in the same container layer where you built the binary, to get the benefits.
I can also confirm we are dealing with 30 min. build times. However, we are extending FROM base image, which is also built by us. This way, it's not affecting the actual SDLC of applications.
I would also like to say we are experiencing 30 minute build times when installing into Docker and running on Bitbucket Pipelines. Current Dockerfile uses the commands:
FROM php:8.2.12-fpm
RUN pecl install grpc \
&& docker-php-ext-enable grpc
I have the same issue here, the build process takes ~2 hours and produces a 235MB binary.
I am using API Platform 2.7.
Counter measures I used are in the following Dockerfile (I followed solutions in previous comments):
ARG PHP_VERSION=8.2
FROM php:${PHP_VERSION}-fpm-alpine
RUN set -eux; \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
zlib-dev \
linux-headers \
;
# isolate gRPC as the build times are problematic, see https://github.com/grpc/grpc/issues/34278
RUN set -eux; \
MAKEFLAGS="-j $(nproc)" pecl install \
grpc \
;
RUN set -eux; \
apk add --no-cache \
libstdc++ \
;
# strip php extensions to decrease container size
RUN set -eux; \
find "$(php-config --extension-dir)" -name '*.so' -type f -exec strip --strip-all {} ';' \
;
RUN set -eux; \
pecl clear-cache \
; \
docker-php-ext-enable \
grpc \
;
RUN set -eux; \
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)" \
; \
apk add --no-cache --virtual .api-phpexts-rundeps $runDeps \
; \
apk del .build-deps
If you are using alpine with Docker. Checkout this:
RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \
GRPC_VERSION=$(apk info grpc -d | grep grpc | cut -d- -f2) && \
git clone --depth 1 -b v${GRPC_VERSION} https://github.com/grpc/grpc /tmp/grpc && \
cd /tmp/grpc/src/php/ext/grpc && \
phpize && \
./configure && \
make && \
make install && \
rm -rf /tmp/grpc && \
apk del --no-cache git grpc-dev $PHPIZE_DEPS && \
echo "extension=grpc.so" > /usr/local/etc/php/conf.d/grpc.ini
It installs in few seconds
If you are using alpine with Docker. Checkout this:
RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \ GRPC_VERSION=$(apk info grpc -d | grep grpc | cut -d- -f2) && \ git clone --depth 1 -b v${GRPC_VERSION} https://github.com/grpc/grpc /tmp/grpc && \ cd /tmp/grpc/src/php/ext/grpc && \ phpize && \ ./configure && \ make && \ make install && \ rm -rf /tmp/grpc && \ apk del --no-cache git grpc-dev $PHPIZE_DEPS && \ echo "extension=grpc.so" > /usr/local/etc/php/conf.d/grpc.iniIt installs in few seconds
It worked nicely! ❤️
@shyim Do you know of any way to work with a multi-stage build? I'm building gRPC in one stage and copying the binary result, but I'm facing an issue with Unable to load dynamic library 'grpc' even though the library path is correct and the binary was successfully copied.
FROM php:8.2-fpm-alpine AS php-ext
# Install packages and remove default server definition
RUN apk update && apk add --no-cache --virtual \
build-essentials \
linux-headers \
curl \
git \
grep \
build-base \
imagemagick-dev \
pcre-dev \
libtool \
make \
autoconf \
g++ \
libpq-dev \
icu-dev \
icu-libs \
zlib-dev \
automake \
libzip-dev \
libpng-dev \
libwebp-dev \
libjpeg-turbo-dev \
freetype-dev \
libxml2-dev
RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \
git clone --depth 1 -b v1.59.4 https://github.com/grpc/grpc /tmp/grpc && \
cd /tmp/grpc/src/php/ext/grpc && \
phpize && \
./configure && \
make && \
make install && \
rm -rf /tmp/grpc && \
apk del --no-cache git grpc-dev $PHPIZE_DEPS
RUN docker-php-source extract \
# ext-opache
&& docker-php-ext-enable opcache \
# ext-igbinary
&& mkdir -p /usr/src/php/ext/igbinary \
&& curl -fsSL https://github.com/igbinary/igbinary/archive/refs/tags/3.2.15.tar.gz | tar xvz -C /usr/src/php/ext/igbinary --strip 1 \
&& docker-php-ext-install igbinary \
# ext-redis
&& mkdir -p /usr/src/php/ext/redis \
&& curl -fsSL https://github.com/phpredis/phpredis/archive/refs/tags/6.0.2.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \
&& docker-php-ext-configure redis --enable-redis-igbinary \
&& docker-php-ext-install redis \
# ext-apcu
&& mkdir -p /usr/src/php/ext/apcu \
&& curl -fsSL https://github.com/krakjoe/apcu/archive/refs/tags/v5.1.23.tar.gz | tar xvz -C /usr/src/php/ext/apcu --strip 1 \
&& docker-php-ext-install apcu \
# ext-bcmath, ext-sockets
&& docker-php-ext-install bcmath sockets \
## cleanup
&& docker-php-source delete
RUN docker-php-source extract \
&& git clone --branch 1.17.2 --depth 1 https://github.com/mongodb/mongo-php-driver.git /usr/src/php/ext/mongodb \
&& cd /usr/src/php/ext/mongodb && git submodule update --init \
&& docker-php-ext-install mongodb
RUN docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install gd
RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install pdo pdo_pgsql pgsql
RUN docker-php-ext-install xml soap exif
RUN pecl install imagick \
&& docker-php-ext-enable imagick
FROM php:8.2-fpm-alpine
WORKDIR /var/www/html
ARG USERNAME=pilot
ARG USER_UID=1000
ARG USER_GID=$USER_UID
# Install packages and remove default server definition
RUN apk update && apk add --no-cache --virtual \
curl \
git \
supervisor \
openssh \
nginx
# Create system user to run Composer and Artisan Commands
RUN addgroup -g $USER_GID $USERNAME \
&& adduser -u $USER_UID -G $USERNAME -s /bin/bash -h /home/$USERNAME -D $USERNAME
RUN mkdir -p /home/$USERNAME/.composer && \
chown -R $USERNAME:$USERNAME /home/$USERNAME
# Setup document root
RUN mkdir -p /var/www/html \
&& mkdir -p /var/lib/nginx \
&& mkdir -p /var/lib/nginx/tmp \
&& mkdir -p /var/log/nginx
# Make sure files/folders needed by the processes are accessable when they run under the nobody user
RUN chown -R $USERNAME:$USERNAME /var/www/html \
&& chown -R $USERNAME:$USERNAME /run \
&& chown -R $USERNAME:$USERNAME /var/lib/nginx \
&& chown -R $USERNAME:$USERNAME /var/log/nginx
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Copy grpc extension from php-ext stage
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/grpc.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/grpc.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/apcu.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/apcu.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/igbinary.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/igbinary.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/opcache.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/opcache.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/redis.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sockets.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sockets.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sodium.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sodium.so
COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/mongodb.so
# Enable grpc extension
RUN docker-php-ext-enable grpc apcu igbinary opcache redis sockets sodium mongodb
# Configure nginx
COPY config/nginx.conf /etc/nginx/nginx.conf
# Configure PHP-FPM
COPY config/fpm-pool.conf /etc/php8/php-fpm.d/www.conf
COPY config/php.ini "$PHP_INI_DIR/php.ini"
# Configure supervisord
COPY config/supervisord.conf /etc/supervisord.conf
# Add application
COPY --chown=$USERNAME:$USERNAME src/ /var/www/html/
# Switch to use a non-root user from here on
USER $USERNAME
# Expose the port nginx is reachable on
EXPOSE 8080
# Let supervisord start nginx & php-fpm
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
# Configure a healthcheck to validate that everything is up&running
HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-ping
I would try to install grpc-cpp package with apk and try out if that helps
If you are using alpine with Docker. Checkout this:
RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \ GRPC_VERSION=$(apk info grpc -d | grep grpc | cut -d- -f2) && \ git clone --depth 1 -b v${GRPC_VERSION} https://github.com/grpc/grpc /tmp/grpc && \ cd /tmp/grpc/src/php/ext/grpc && \ phpize && \ ./configure && \ make && \ make install && \ rm -rf /tmp/grpc && \ apk del --no-cache git grpc-dev $PHPIZE_DEPS && \ echo "extension=grpc.so" > /usr/local/etc/php/conf.d/grpc.iniIt installs in few seconds
It worked nicely! ❤️
@shyim Do you know of any way to work with a multi-stage build? I'm building gRPC in one stage and copying the binary result, but I'm facing an issue with
Unable to load dynamic library 'grpc'even though the library path is correct and the binary was successfully copied.FROM php:8.2-fpm-alpine AS php-ext # Install packages and remove default server definition RUN apk update && apk add --no-cache --virtual \ build-essentials \ linux-headers \ curl \ git \ grep \ build-base \ imagemagick-dev \ pcre-dev \ libtool \ make \ autoconf \ g++ \ libpq-dev \ icu-dev \ icu-libs \ zlib-dev \ automake \ libzip-dev \ libpng-dev \ libwebp-dev \ libjpeg-turbo-dev \ freetype-dev \ libxml2-dev RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \ git clone --depth 1 -b v1.59.4 https://github.com/grpc/grpc /tmp/grpc && \ cd /tmp/grpc/src/php/ext/grpc && \ phpize && \ ./configure && \ make && \ make install && \ rm -rf /tmp/grpc && \ apk del --no-cache git grpc-dev $PHPIZE_DEPS RUN docker-php-source extract \ # ext-opache && docker-php-ext-enable opcache \ # ext-igbinary && mkdir -p /usr/src/php/ext/igbinary \ && curl -fsSL https://github.com/igbinary/igbinary/archive/refs/tags/3.2.15.tar.gz | tar xvz -C /usr/src/php/ext/igbinary --strip 1 \ && docker-php-ext-install igbinary \ # ext-redis && mkdir -p /usr/src/php/ext/redis \ && curl -fsSL https://github.com/phpredis/phpredis/archive/refs/tags/6.0.2.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \ && docker-php-ext-configure redis --enable-redis-igbinary \ && docker-php-ext-install redis \ # ext-apcu && mkdir -p /usr/src/php/ext/apcu \ && curl -fsSL https://github.com/krakjoe/apcu/archive/refs/tags/v5.1.23.tar.gz | tar xvz -C /usr/src/php/ext/apcu --strip 1 \ && docker-php-ext-install apcu \ # ext-bcmath, ext-sockets && docker-php-ext-install bcmath sockets \ ## cleanup && docker-php-source delete RUN docker-php-source extract \ && git clone --branch 1.17.2 --depth 1 https://github.com/mongodb/mongo-php-driver.git /usr/src/php/ext/mongodb \ && cd /usr/src/php/ext/mongodb && git submodule update --init \ && docker-php-ext-install mongodb RUN docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg --with-webp \ && docker-php-ext-install gd RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-install pdo pdo_pgsql pgsql RUN docker-php-ext-install xml soap exif RUN pecl install imagick \ && docker-php-ext-enable imagick FROM php:8.2-fpm-alpine WORKDIR /var/www/html ARG USERNAME=pilot ARG USER_UID=1000 ARG USER_GID=$USER_UID # Install packages and remove default server definition RUN apk update && apk add --no-cache --virtual \ curl \ git \ supervisor \ openssh \ nginx # Create system user to run Composer and Artisan Commands RUN addgroup -g $USER_GID $USERNAME \ && adduser -u $USER_UID -G $USERNAME -s /bin/bash -h /home/$USERNAME -D $USERNAME RUN mkdir -p /home/$USERNAME/.composer && \ chown -R $USERNAME:$USERNAME /home/$USERNAME # Setup document root RUN mkdir -p /var/www/html \ && mkdir -p /var/lib/nginx \ && mkdir -p /var/lib/nginx/tmp \ && mkdir -p /var/log/nginx # Make sure files/folders needed by the processes are accessable when they run under the nobody user RUN chown -R $USERNAME:$USERNAME /var/www/html \ && chown -R $USERNAME:$USERNAME /run \ && chown -R $USERNAME:$USERNAME /var/lib/nginx \ && chown -R $USERNAME:$USERNAME /var/log/nginx # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Copy grpc extension from php-ext stage COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/grpc.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/grpc.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/apcu.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/apcu.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/igbinary.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/igbinary.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/opcache.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/opcache.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/redis.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sockets.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sockets.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sodium.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sodium.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/mongodb.so # Enable grpc extension RUN docker-php-ext-enable grpc apcu igbinary opcache redis sockets sodium mongodb # Configure nginx COPY config/nginx.conf /etc/nginx/nginx.conf # Configure PHP-FPM COPY config/fpm-pool.conf /etc/php8/php-fpm.d/www.conf COPY config/php.ini "$PHP_INI_DIR/php.ini" # Configure supervisord COPY config/supervisord.conf /etc/supervisord.conf # Add application COPY --chown=$USERNAME:$USERNAME src/ /var/www/html/ # Switch to use a non-root user from here on USER $USERNAME # Expose the port nginx is reachable on EXPOSE 8080 # Let supervisord start nginx & php-fpm CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] # Configure a healthcheck to validate that everything is up&running HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-ping
Also had the same errors on build - felt like it was all to good to be true.. did you figure out a fix?
If you are using alpine with Docker. Checkout this:
RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \ GRPC_VERSION=$(apk info grpc -d | grep grpc | cut -d- -f2) && \ git clone --depth 1 -b v${GRPC_VERSION} https://github.com/grpc/grpc /tmp/grpc && \ cd /tmp/grpc/src/php/ext/grpc && \ phpize && \ ./configure && \ make && \ make install && \ rm -rf /tmp/grpc && \ apk del --no-cache git grpc-dev $PHPIZE_DEPS && \ echo "extension=grpc.so" > /usr/local/etc/php/conf.d/grpc.iniIt installs in few seconds
It worked nicely! ❤️ @shyim Do you know of any way to work with a multi-stage build? I'm building gRPC in one stage and copying the binary result, but I'm facing an issue with
Unable to load dynamic library 'grpc'even though the library path is correct and the binary was successfully copied.FROM php:8.2-fpm-alpine AS php-ext # Install packages and remove default server definition RUN apk update && apk add --no-cache --virtual \ build-essentials \ linux-headers \ curl \ git \ grep \ build-base \ imagemagick-dev \ pcre-dev \ libtool \ make \ autoconf \ g++ \ libpq-dev \ icu-dev \ icu-libs \ zlib-dev \ automake \ libzip-dev \ libpng-dev \ libwebp-dev \ libjpeg-turbo-dev \ freetype-dev \ libxml2-dev RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \ git clone --depth 1 -b v1.59.4 https://github.com/grpc/grpc /tmp/grpc && \ cd /tmp/grpc/src/php/ext/grpc && \ phpize && \ ./configure && \ make && \ make install && \ rm -rf /tmp/grpc && \ apk del --no-cache git grpc-dev $PHPIZE_DEPS RUN docker-php-source extract \ # ext-opache && docker-php-ext-enable opcache \ # ext-igbinary && mkdir -p /usr/src/php/ext/igbinary \ && curl -fsSL https://github.com/igbinary/igbinary/archive/refs/tags/3.2.15.tar.gz | tar xvz -C /usr/src/php/ext/igbinary --strip 1 \ && docker-php-ext-install igbinary \ # ext-redis && mkdir -p /usr/src/php/ext/redis \ && curl -fsSL https://github.com/phpredis/phpredis/archive/refs/tags/6.0.2.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \ && docker-php-ext-configure redis --enable-redis-igbinary \ && docker-php-ext-install redis \ # ext-apcu && mkdir -p /usr/src/php/ext/apcu \ && curl -fsSL https://github.com/krakjoe/apcu/archive/refs/tags/v5.1.23.tar.gz | tar xvz -C /usr/src/php/ext/apcu --strip 1 \ && docker-php-ext-install apcu \ # ext-bcmath, ext-sockets && docker-php-ext-install bcmath sockets \ ## cleanup && docker-php-source delete RUN docker-php-source extract \ && git clone --branch 1.17.2 --depth 1 https://github.com/mongodb/mongo-php-driver.git /usr/src/php/ext/mongodb \ && cd /usr/src/php/ext/mongodb && git submodule update --init \ && docker-php-ext-install mongodb RUN docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg --with-webp \ && docker-php-ext-install gd RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-install pdo pdo_pgsql pgsql RUN docker-php-ext-install xml soap exif RUN pecl install imagick \ && docker-php-ext-enable imagick FROM php:8.2-fpm-alpine WORKDIR /var/www/html ARG USERNAME=pilot ARG USER_UID=1000 ARG USER_GID=$USER_UID # Install packages and remove default server definition RUN apk update && apk add --no-cache --virtual \ curl \ git \ supervisor \ openssh \ nginx # Create system user to run Composer and Artisan Commands RUN addgroup -g $USER_GID $USERNAME \ && adduser -u $USER_UID -G $USERNAME -s /bin/bash -h /home/$USERNAME -D $USERNAME RUN mkdir -p /home/$USERNAME/.composer && \ chown -R $USERNAME:$USERNAME /home/$USERNAME # Setup document root RUN mkdir -p /var/www/html \ && mkdir -p /var/lib/nginx \ && mkdir -p /var/lib/nginx/tmp \ && mkdir -p /var/log/nginx # Make sure files/folders needed by the processes are accessable when they run under the nobody user RUN chown -R $USERNAME:$USERNAME /var/www/html \ && chown -R $USERNAME:$USERNAME /run \ && chown -R $USERNAME:$USERNAME /var/lib/nginx \ && chown -R $USERNAME:$USERNAME /var/log/nginx # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Copy grpc extension from php-ext stage COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/grpc.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/grpc.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/apcu.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/apcu.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/igbinary.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/igbinary.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/opcache.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/opcache.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/redis.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sockets.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sockets.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sodium.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/sodium.so COPY --from=php-ext /usr/local/lib/php/extensions/no-debug-non-zts-20220829/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20220829/mongodb.so # Enable grpc extension RUN docker-php-ext-enable grpc apcu igbinary opcache redis sockets sodium mongodb # Configure nginx COPY config/nginx.conf /etc/nginx/nginx.conf # Configure PHP-FPM COPY config/fpm-pool.conf /etc/php8/php-fpm.d/www.conf COPY config/php.ini "$PHP_INI_DIR/php.ini" # Configure supervisord COPY config/supervisord.conf /etc/supervisord.conf # Add application COPY --chown=$USERNAME:$USERNAME src/ /var/www/html/ # Switch to use a non-root user from here on USER $USERNAME # Expose the port nginx is reachable on EXPOSE 8080 # Let supervisord start nginx & php-fpm CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] # Configure a healthcheck to validate that everything is up&running HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-pingAlso had the same errors on build - felt like it was all to good to be true.. did you figure out a fix?
This is what my Dockerfile looks like.
https://gist.github.com/luishgp/873a9b4759457169b6c6cd7aaea19707
Hope it helps you
@luishgp I did try that, but this morning, I figured it out. I removed grpc-dev from apk del .. it seems without it the so file doesn't load
I have the same issue here, the build process takes ~2 hours and produces a 235MB binary.
I am using API Platform 2.7.
Counter measures I used are in the following Dockerfile (I followed solutions in previous comments):
ARG PHP_VERSION=8.2 FROM php:${PHP_VERSION}-fpm-alpine RUN set -eux; \ apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ zlib-dev \ linux-headers \ ; # isolate gRPC as the build times are problematic, see https://github.com/grpc/grpc/issues/34278 RUN set -eux; \ MAKEFLAGS="-j $(nproc)" pecl install \ grpc \ ; RUN set -eux; \ apk add --no-cache \ libstdc++ \ ; # strip php extensions to decrease container size RUN set -eux; \ find "$(php-config --extension-dir)" -name '*.so' -type f -exec strip --strip-all {} ';' \ ; RUN set -eux; \ pecl clear-cache \ ; \ docker-php-ext-enable \ grpc \ ; RUN set -eux; \ runDeps="$( \ scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ | tr ',' '\n' \ | sort -u \ | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ )" \ ; \ apk add --no-cache --virtual .api-phpexts-rundeps $runDeps \ ; \ apk del .build-deps
I'd guess that unless you're using that in a multi-stage build and copying things over, the final image's layers sum up to the layer size from that step alone + whatever size differences before and after it... If you want the image pullers to have a "good time", you'll either need to split it in a multi-stage build and include the specific files via COPY, or use a single RUN command doing all the dependency-installs, compiling, cleanup. Keep in mind that every Dockerfile RUN or COPY directive produces a new layer ON TOP of the previous ones, containing the differences - it doesn't affect whatever differences were added by previous layers, and when one pulls an image's tag or version, the container engine also has to pull all the previous layers that lead to it!
@grassdionera I think I may be doing something wrong, on my part... I've tried RUN export MAKEFLAGS="-j 8"; pecl install grpc (and also $(nproc) in place of a static 8 for this and all other cases) and RUN MAKEFLAGS="-j 8" pecl install grpc, but both gave me the same final build time as a plain pecl install grpc on a 4-core builder...
I have the same issue here, the build process takes ~2 hours and produces a 235MB binary. I am using API Platform 2.7. Counter measures I used are in the following Dockerfile (I followed solutions in previous comments):
ARG PHP_VERSION=8.2 FROM php:${PHP_VERSION}-fpm-alpine RUN set -eux; \ apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ zlib-dev \ linux-headers \ ; # isolate gRPC as the build times are problematic, see https://github.com/grpc/grpc/issues/34278 RUN set -eux; \ MAKEFLAGS="-j $(nproc)" pecl install \ grpc \ ; RUN set -eux; \ apk add --no-cache \ libstdc++ \ ; # strip php extensions to decrease container size RUN set -eux; \ find "$(php-config --extension-dir)" -name '*.so' -type f -exec strip --strip-all {} ';' \ ; RUN set -eux; \ pecl clear-cache \ ; \ docker-php-ext-enable \ grpc \ ; RUN set -eux; \ runDeps="$( \ scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ | tr ',' '\n' \ | sort -u \ | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ )" \ ; \ apk add --no-cache --virtual .api-phpexts-rundeps $runDeps \ ; \ apk del .build-depsI'd guess that unless you're using that in a multi-stage build and copying things over, the final image's layers sum up to the layer size from that step alone + whatever size differences before and after it... If you want the image pullers to have a "good time", you'll either need to split it in a multi-stage build and include the specific files via
COPY, or use a singleRUNcommand doing all the dependency-installs, compiling, cleanup. Keep in mind that every DockerfileRUNorCOPYdirective produces a new layer ON TOP of the previous ones, containing the differences - it doesn't affect whatever differences were added by previous layers, and when one pulls an image's tag or version, the container engine also has to pull all the previous layers that lead to it!
Quite the same solution, I have finally used the builds from https://github.com/spiral/docker-php-grpc with the following:
COPY --from=ghcr.io/spiral/php-grpc:8.1 /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini
COPY --from=ghcr.io/spiral/php-grpc:8.1 /usr/local/etc/php/conf.d/docker-php-ext-protobuf.ini /usr/local/etc/php/conf.d/docker-php-ext-protobuf.ini
COPY --from=ghcr.io/spiral/php-grpc:8.1 /usr/local/lib/php/extensions/no-debug-non-zts-20210902/grpc.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/grpc.so
COPY --from=ghcr.io/spiral/php-grpc:8.1 /usr/local/lib/php/extensions/no-debug-non-zts-20210902/protobuf.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/protobuf.so
Any chance of solving this at the pecl pack level?
I made a PR to fix it 9 months ago, nothing happened yet https://github.com/grpc/grpc/pull/35404
maybe Google has no interest in maintaining PHP extension anymore 😅
I made a PR to fix it 9 months ago, nothing happened yet #35404
maybe Google has no interest in maintaining PHP extension anymore 😅
Are you sure you linked the correct PR? That one has unanswered/unaddressed unresolved comments...
I wouldn't expect anything to happen if I just opened a PR and left it unattended - it's still my PR, their responsibility is to evaluate and eventually merge it when they see it as fit, not to fix it themselves with no further feedback from me and then merge it...
I can't talk for the project maintainers, but in my view, I'd expect the PR owner to at least reply to the member's comments if they have any expectation of getting it merged, or close it if it's no longer going to be worked on.
If you are using alpine with Docker. Checkout this:
RUN apk add --no-cache git grpc-cpp grpc-dev $PHPIZE_DEPS && \ GRPC_VERSION=$(apk info grpc -d | grep grpc | cut -d- -f2) && \ git clone --depth 1 -b v${GRPC_VERSION} https://github.com/grpc/grpc /tmp/grpc && \ cd /tmp/grpc/src/php/ext/grpc && \ phpize && \ ./configure && \ make && \ make install && \ rm -rf /tmp/grpc && \ apk del --no-cache git grpc-dev $PHPIZE_DEPS && \ echo "extension=grpc.so" > /usr/local/etc/php/conf.d/grpc.iniIt installs in few seconds
Hi all,
It's a bit surprising that the grpc extension compiles in less than 30 secs with this instruction, while it can take more than 20 min to compile with the install-php-extensions command. Looks like something weird is happening there, maybe not related with the package itself.
@feuzeu pecl compiles grpc, abseil and all depending c packages. the snippet there uses dynamic linking against operating system gRPC, therefore only php specific code needs to be compiled
@feuzeu pecl compiles grpc, abseil and all depending c packages. the snippet there uses dynamic linking against operating system gRPC, therefore only php specific code needs to be compiled
OK thanks. I know understand what's happening under the hood, and why the output is much more bigger and takes so much time.
Now the question is what's the point of compiling all those depending packages. The binary is supposed to be installed locally, and not to be distributed on the pecl network, where it could be installed on other hosts with different versions of the packages, for example. They have already been compiled, and are already installed. I guess the grpc extension wouldn't compile in case of version incompatibilities. Is there any issue that could be caused by the above command?
Hey everyone,
I know firsthand how frustrating it is to wait ages for the gRPC PHP extension to install via PECL—it can really slow down your workflow. To help out, I've put together a repository with pre-compiled gRPC binaries for Debian-based PHP versions 8.3 and 8.4. You can check it out here: https://github.com/redfieldchristabel/php_grpc/pkgs/container/php_grpc. Hopefully, this makes things quicker and easier for you.
To use it, you can copy the pre-built gRPC extension and its configuration into your PHP image using a multi-stage build in your Dockerfile. For example, for PHP 8.3, you can add the following lines:
# Copy all PHP extension files (including grpc.so) from our pre-built image
COPY --from=ghcr.io/redfieldchristabel/php_grpc:8.3 /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
# Copy the gRPC PHP configuration file
COPY --from=ghcr.io/redfieldchristabel/php_grpc:8.3 /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini
For those using PHP 8.1 and 8.2, I'd suggest taking a look at the pre-built images available at ghcr.io/spiral/php-grpc.
Feel free to try these out, and I'm open to any feedback or suggestions you might have.
Following my post from Sep 10th 2024, and for those who require ZTS variants of the extension (eg. if you use FrankenPHP).
I have made a fork of Spiral Scout's repository here: https://github.com/php-etl/docker-php-grpc
FROM ghcr.io/php-etl/php-grpc:8.4-zts AS php-grpc
FROM dunglas/frankenphp:1-php8.4 AS frankenphp_upstream
# Install gRPC, see https://github.com/grpc/grpc/issues/34278
COPY --from=php-grpc /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini
COPY --from=php-grpc /usr/local/etc/php/conf.d/docker-php-ext-protobuf.ini /usr/local/etc/php/conf.d/docker-php-ext-protobuf.ini
COPY --from=php-grpc /usr/local/lib/php/extensions/no-debug-zts-20240924/grpc.so /usr/local/lib/php/extensions/no-debug-zts-20240924/grpc.so
COPY --from=php-grpc /usr/local/lib/php/extensions/no-debug-zts-20240924/protobuf.so /usr/local/lib/php/extensions/no-debug-zts-20240924/protobuf.so
Hi, php:8.X-fpm Images for Debian-based (non alpine) - https://hub.docker.com/r/citizen4our/php-fpm-grpc/tags
gRPC 1.63
FROM php:8.4-fpm
ARG DEBSECSCAN_SUITE=bullseye
LABEL Description="Base php-fpm image + base php extentions + security fixes + grpc"
# Install all dependencies needed for gRPC compilation
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
make \
libgrpc-dev \
protobuf-compiler \
build-essential \
pkg-config \
libssl-dev \
zlib1g-dev \
autoconf \
automake \
libtool \
git \
cmake \
&& rm -rf /var/lib/apt/lists/*
# Install additional dependencies for gRPC
RUN apt-get update && \
apt-get install -y --no-install-recommends \
git \
libgrpc++-dev \
build-essential \
autoconf \
libtool
# Compile and install gRPC extension
RUN git clone --depth 1 -b v1.63.0 https://github.com/grpc/grpc /tmp/grpc && \
cd /tmp/grpc/src/php/ext/grpc && \
phpize && \
./configure && \
make && \
make install && \
rm -rf /tmp/grpc && \
apt-get purge -y \
git \
build-essential \
autoconf \
libtool && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
echo "extension=grpc.so" > /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini
@Citizen4our Thanks for the Dockerfile example. How long does this take for you to complete when building?
@AndrewCustomSumIT about ~4 min, on Mac with M4 pro chip. 2 architecture - arm64, amd64