newrelic-php-agent: Can not find newrelic.so module after installing on Alpine

When installing the PHP Agent manually (e.g. not via package manager, but via .tar.gz) on Alpine it after installation can not find the module.

Description

The newrelic.so module does seem to be located at the modules directory, but there are errors when trying to run php.

Manually sshing in the Docker image that gets build to run the installation manually leads to the same result.

Worth mentioning; the warning (see below) includes “Error loading shared library /usr/local/lib/php/extensions/no-debug-non-zts-20210902/newrelic.so.so

Steps to Reproduce

The installation script used (as suggested by the documentation) in the Dockerfile:

RUN cd ~ \
    && export NEWRELIC_VERSION="$(curl -sS https://download.newrelic.com/php_agent/release/ | sed -n 's/.*>\(.*linux-musl\).tar.gz<.*/\1/p')" \
    && curl -sS "https://download.newrelic.com/php_agent/release/${NEWRELIC_VERSION}.tar.gz" | gzip -dc | tar xf - \
    && cd "${NEWRELIC_VERSION}" \
    && NR_INSTALL_USE_CP_NOT_LN=true NR_INSTALL_SILENT=true ./newrelic-install install \
    && cd .. \
    && unset NEWRELIC_VERSION \
    && sed -i \
        -e "s/;\?newrelic.enabled =.*/newrelic.enabled = ${NEW_RELIC_ENABLED}/" \
        -e "s/newrelic.license =.*/newrelic.license = ${NRIA_LICENSE_KEY}/" \
        -e "s/newrelic.appname =.*/newrelic.appname = ${APP_NAME}/" \
        -e "s/newrelic.daemon.logfile =.*/newrelic.daemon.logfile = \/app\/var\/log\/newrelic-daemon\.log/" \
        -e "s/;\?newrelic.daemon.address =.*/newrelic.daemon.address = \/app\/var\/cache\/\.newrelic\.sock/" \
        -e 's/;newrelic.daemon.app_connect_timeout =.*/newrelic.daemon.app_connect_timeout=15s/' \
        -e 's/;newrelic.daemon.start_timeout =.*/newrelic.daemon.start_timeout=5s/' \
        /usr/local/etc/php/conf.d/newrelic.ini

Expected Behavior

Module should get found when running php -v after installation.

Relevant Logs / Console output

The actual warning when running php -v:

PHP Warning: PHP Startup: Unable to load dynamic library ‘newrelic.so’ (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20210902/newrelic.so (Error relocating /usr/local/lib/php/extensions/no-debug-non-zts-20210902/newrelic.so: unsupported relocation type 7), /usr/local/lib/php/extensions/no-debug-non-zts-20210902/newrelic.so.so (Error loading shared library /usr/local/lib/php/extensions/no-debug-non-zts-20210902/newrelic.so.so: No such file or directory)) in Unknown on line 0

PHP 8.1.2 (cli) (built: Jan 21 2022 21:44:09) (NTS) Copyright © The PHP Group Zend Engine v4.1.2, Copyright © Zend Technologies with Zend OPcache v8.1.2, Copyright ©, by Zend Technologies

Your Environment

Docker image with php:8.1-fpm-alpine as base image.

Additional context

image

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 2
  • Comments: 17 (5 by maintainers)

Most upvoted comments

The most important issue is that no exception is thrown or error code is returned while having an erroneous installation. Please do not silence failures.

We now took another approach; instead of using sed we copy our own newrelic.ini over the file in conf.d:

COPY ./docker/php/newrelic.ini /usr/local/etc/php/conf.d/newrelic.ini
extension = "newrelic.so"
[newrelic]
newrelic.enabled = ${NEW_RELIC_ENABLED}
newrelic.appname = ${APP_NAME}
newrelic.license = ${NEW_RELIC_LICENSE_KEY}

This does properly work, but the problem we faced with that relates to the warning @devwithu also gets:

PHP Warning: PHP Startup: Unable to load dynamic library ‘newrelic.so’ (tried: /usr/lib/php/20210902/newrelic.so (/usr/lib/php/20210902/newrelic.so: cannot open shared object file: No such file or directory), /usr/lib/php/20210902/newrelic.so.so (/usr/lib/php/20210902/newrelic.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0

Given that NR Agent does not allow installing the agent and extension on ARM, we make the installation conditional and do not install it on dev environments. Docker does not allow a COPY command to be conditional in a clean way, so the newrelic.ini file still gets copied.

We solved the warning above by removing the first line from the newrelic.ini, so the config is there but php will not load it. We consider splitting configuration and instantiation a good practice.

Given that PHP still has to get instructed to load / enable the newrelic extension, we expected this conditional enable to work. The problem is, it doesn’t:

ARG NEWRELIC_ENABLED=1
RUN if [ "$NEWRELIC_ENABLED" = "1" ] ; then \
     docker-php-ext-enable newrelic \
fi

The cli output php --ini " grep newrelic.enabled does not state that the extension is enabled, while it is when the 1st line is kept intact on the newrelic.ini.

We want to keep configuration and activation separate. How can we enable the newrelic extension after installation without putting the extension definition in the configuration?

In my case that worked fine;

RUN apk add gcompat