This post will cover “cannot open shared object file: no such file or directory” messages seen at startup for PHP applications.
IMPORTANT: Make sure App Service Logs are enabled first. You can then view logging in a few different ways:
- Retrieving logs directly from the Kudu site, or directly view/download via an FTP client
- Diagnose and Solve Problems -> Application Logs detector, Container Crash detector, or Container Issues detector
If App Service Logs are not enabled, only
docker.log files will be generated, which will not show application related stdout / stderr and will make troubleshooting issues more complicated.
Sometimes, certain PHP packages may rely on “shared object files” (
.so extension files) thay may not be present in the current environment - on PHP with App Service Linux, that environment would be a Debian-based Docker Container. This may look something like this:
cannot open shared object file: no such file or directory) /usr/local/lib/php/extensions/no-debug-non-zts-20200930/opache.so
PHP Startup: Unable to load dynamic library '/home/site/ext/rdkafka-6.0.3/rdkafka.so' (tried: /home/site/ext/rdkafka-6.0.3/rdkafka.so (/home/site/ext/rdkafka-6.0.3/rdkafka.so: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20220829//home/site/ext/rdkafka-6.0.3/rdkafka.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20220829//home/site/ext/rdkafka-6.0.3/rdkafka.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
The message about which
.so file is not present will depend on your application. Below is some reasons why this may appear and how to resolve them.
Bad syntax or misconfigured .ini file
Assuming that you know the extension you need to install, but it is failing with the above message, it is likely to be one of these scenarios:
- Following the
PHP_INI_SCAN_DIRApp Setting (documentation), you may have created a custom
.inifile with the
extension=property pointing to the wrong
/home/site/ext/libgomp/modules/libgomp.sois the full path that contains a needed
- However, your
.iniis pointing to
- The location name may have been mispelled
- There may be a syntax error in your path
- If using a custom startup script, the package may be failing to install
If installing via Pecl - this may install to directories outside of
/home. If you then have your
.ini pointing to an
.so, eg., simply
extension=mysharedlib.so - this would obviously likely fail:
- Because of the path difference locations and the possibility this does not fall under one of the paths that PHP tries to use for dynamic libraries
- After any container restart, changes outside of
- After any container restart, changes outside of
You can validate where Pecl will install extensions with the
pear config-show command and looking at the
ext_dir column with
PEAR extension directory.
root@b37f5b3aca46:/home# pear config-show Configuration (channel pear.php.net): ===================================== Auto-discover new Channels auto_discover 0 Default Channel default_channel pear.php.net HTTP Proxy Server Address http_proxy <not set> PEAR server [DEPRECATED] master_server pear.php.net Default Channel Mirror preferred_mirror pear.php.net Remote Configuration File remote_config <not set> PEAR executables directory bin_dir /usr/local/bin PEAR documentation directory doc_dir /usr/local/lib/php/doc PHP extension directory ext_dir /usr/local/lib/php/extensions/no-debug-non-zts-20220829 PEAR directory php_dir /usr/local/lib/php
If installing extensions this way, ensure to copy the contents from ` /usr/local/lib/php/extensions/no-debug-non-zts-yyymmdd
to /home/site/ext` (or your relevant extension direcotry), for example:
cp /usr/local/lib/php/extensions/no-debug-non-zts-20220829/rdkafka.so /home/site/ext
NOTE: If you’re manually uploading
.gz packages from Pecl, or, their extracted contents, ensure that if these are being manually built with
./make - that these properly build. Packages that are incorrectly built, or fail to build, may show the same
Unable to load dynamic library message.
Additionally, attempting to use a Shared Library that is not compatible with the application package (eg., a package under
vendor/) may also show
Unable to load dynamic library.
Aside from the potential of a misconfiguration - there may be a chance that the PHP libraries being used may rely on
.so files that can be installed through a Custom Startup Script instead of configuring it as an PHP extension.
NOTE: In some cases, you may have to use both a configured PHP extension and also install commands via custom startup file/script - this however depends on the application and packages being used
This will require reviewing which
.so package is missing and seeing which Linux packages need to be installed on startup to resolve this. Typically, doing a quick google search of the missing
.so file will normally show which package(s) need to be installed.
An an example of a startup command could just be:
apt-get install -y librdkafka-dev
Or a startup file:
#!/bin/bash apt-get install -y librdkafka-dev
Note that, in either case, for a PHP image using Apache or NGINX - we don’t need to explicitly invoke any
nginx commands as they’re implicitly ran to start after the startup command or file is done.
These below resources can help properly set up installing PHP extensions.
- Configure PHP applications - Customize php.ini settings
- Pecl - PHP extension repository
- Pecl can be used as a simple way to find and install extensions
You can use the
php -mcommand to view the currently loaded modules. Below is example output:
root@2a4e1b76038d:/home# php -m [PHP Modules] bcmath calendar Core ctype curl date dom exif fileinfo filter ftp ... more modules ...
You can use the
php -i | grep inicommand to view all the
.ini'scurrently loaded. For example:
root@2a4e1b76038d:/home# php -i | grep ini Configuration File (php.ini) Path => /usr/local/etc/php Scan this dir for additional .ini files => /usr/local/etc/php/conf.d Additional .ini files parsed => /usr/local/etc/php/conf.d/20-sqlsrv.ini, /usr/local/etc/php/conf.d/30-pdo_sqlsrv.ini, /usr/local/etc/php/conf.d/docker-php-ext-bcmath.ini, /usr/local/etc/php/conf.d/docker-php-ext-calendar.ini, /usr/local/etc/php/conf.d/docker-php-ext-exif.ini, /usr/local/etc/php/conf.d/docker-php-ext-gd.ini, /usr/local/etc/php/conf.d/docker-php-ext-gettext.ini, ...more inis...
- Lastly, creating a
.phppage with a
phpinfo()function in it can potentially be helpful for additional information on loaded extensions.