-
-
Notifications
You must be signed in to change notification settings - Fork 128
Update OCI8 layer for Bref 3 #647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+94
−41
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,48 +1,54 @@ | ||
| ARG PHP_VERSION | ||
| ARG BREF_VERSION | ||
| FROM bref/build-php-$PHP_VERSION:$BREF_VERSION AS ext | ||
| ARG OL_VERSION=8 | ||
| ARG IC_VERSION=21 | ||
| # Oracle Instant Client image | ||
| FROM public.ecr.aws/docker/library/oraclelinux:$OL_VERSION AS oracle_base | ||
| ARG OL_VERSION | ||
| RUN dnf -y install oracle-instantclient-release-el${OL_VERSION} | ||
|
|
||
| FROM oracle_base AS oracle_devel | ||
| RUN dnf -y install oracle-instantclient-devel && \ | ||
| mkdir -p /opt/oracle && \ | ||
| cp -r /usr/lib/oracle/*/client64/lib/* /opt/oracle/ && \ | ||
| cp -r /usr/include/oracle/*/client64/* /opt/oracle/ | ||
|
|
||
| FROM oracle_base AS oracle_client | ||
| RUN dnf -y install oracle-instantclient-basiclite && \ | ||
| mkdir -p /opt/oracle && \ | ||
| cp -r /usr/lib/oracle/*/client64/lib/* /opt/oracle/ | ||
|
|
||
| # Redeclare for scope | ||
| ARG PHP_VERSION | ||
|
|
||
| # Specify library path | ||
| ENV LD_LIBRARY_PATH=/usr/lib:/usr/lib64:$LD_LIBRARY_PATH | ||
| ENV ORACLE_BUILD_DIR=${BUILD_DIR}/oracle | ||
|
|
||
| # Install libaio | ||
| RUN dnf install -y libaio | ||
|
|
||
| # Instant Client newer than 21.x requires glibc 2.28+ which is not available on Amazon Linux 2 | ||
| RUN mkdir -p ${ORACLE_BUILD_DIR}; \ | ||
| cd ${ORACLE_BUILD_DIR}; \ | ||
| curl -o oci-basic.zip https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-basiclite-linux.x64-21.16.0.0.0dbru.zip && \ | ||
| unzip oci-basic.zip -d src -x META-INF/* && \ | ||
| curl -o oci-sdk.zip https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip && \ | ||
| unzip oci-sdk.zip -d src -x META-INF/* | ||
|
|
||
| RUN if [ "$PHP_VERSION" = "80" ] ; then \ | ||
| echo "instantclient,${ORACLE_BUILD_DIR}/src/instantclient_21_16" | pecl install oci8-3.0.1; \ | ||
| elif [ "$PHP_VERSION" = "81" ] ; then \ | ||
| echo "instantclient,${ORACLE_BUILD_DIR}/src/instantclient_21_16" | pecl install oci8-3.2.1; \ | ||
| else \ | ||
| echo "instantclient,${ORACLE_BUILD_DIR}/src/instantclient_21_16" | pecl install oci8; \ | ||
| fi | ||
|
|
||
| RUN cp /usr/lib64/libaio.so.1 /tmp/libaio.so.1 | ||
| RUN cp ${ORACLE_BUILD_DIR}/src/instantclient_21_16/libclntshcore.so.21.1 /tmp/libclntshcore.so.21.1 | ||
| RUN cp ${ORACLE_BUILD_DIR}/src/instantclient_21_16/libclntsh.so.21.1 /tmp/libclntsh.so.21.1 | ||
| RUN cp ${ORACLE_BUILD_DIR}/src/instantclient_21_16/libocci.so.21.1 /tmp/libocci.so.21.1 | ||
| RUN cp ${ORACLE_BUILD_DIR}/src/instantclient_21_16/libnnz21.so /tmp/libnnz21.so | ||
| RUN cp ${ORACLE_BUILD_DIR}/src/instantclient_21_16/libociicus.so /tmp/libociicus.so | ||
| RUN cp `php-config --extension-dir`/oci8.so /tmp/oci8.so | ||
| RUN echo 'extension=oci8.so' > /tmp/ext.ini | ||
|
|
||
| RUN php /bref/lib-copy/copy-dependencies.php /tmp/oci8.so /tmp/extension-libs | ||
| # Missing these two | ||
| RUN cp /tmp/libocci.so.21.1 /tmp/extension-libs | ||
| RUN cp /tmp/libociicus.so /tmp/extension-libs | ||
| ARG BREF_VERSION | ||
| FROM bref/build-php-$PHP_VERSION:$BREF_VERSION AS ext | ||
| ARG IC_VERSION | ||
| ENV ORACLE_DEVEL_DIR=/opt/oracle-devel | ||
| ENV ORACLE_CLIENT_DIR=/opt/oracle-client | ||
| ENV LD_LIBRARY_PATH=/usr/lib:/usr/lib64:$ORACLE_CLIENT_DIR:$ORACLE_DEVEL_DIR:$LD_LIBRARY_PATH | ||
|
|
||
| COPY --from=oracle_devel /usr/lib64/libaio.so.1 /usr/lib64/libaio.so.1 | ||
| COPY --from=oracle_devel /opt/oracle $ORACLE_DEVEL_DIR | ||
| COPY --from=oracle_client /opt/oracle $ORACLE_CLIENT_DIR | ||
|
|
||
| RUN echo "instantclient,${ORACLE_DEVEL_DIR}" | pecl install oci8 | ||
|
|
||
| RUN cp /usr/lib64/libaio.so.1 /tmp/libaio.so.1 && \ | ||
| cp ${ORACLE_CLIENT_DIR}/libclntshcore.so.${IC_VERSION}.1 /tmp && \ | ||
| cp ${ORACLE_CLIENT_DIR}/libclntsh.so.${IC_VERSION}.1 /tmp && \ | ||
| cp ${ORACLE_CLIENT_DIR}/libnnz${IC_VERSION}.so /tmp && \ | ||
| cp ${ORACLE_CLIENT_DIR}/libocci.so.${IC_VERSION}.1 /tmp && \ | ||
| cp ${ORACLE_CLIENT_DIR}/libociicus.so /tmp && \ | ||
| cp `php-config --extension-dir`/oci8.so /tmp/oci8.so && \ | ||
| echo 'extension=oci8.so' > /tmp/ext.ini | ||
|
|
||
| RUN php /bref/lib-copy/copy-dependencies.php /tmp/oci8.so /tmp/extension-libs && \ | ||
| cp /tmp/libocci.so.${IC_VERSION}.1 /tmp/extension-libs && \ | ||
| cp /tmp/libociicus.so /tmp/extension-libs | ||
|
|
||
| # Build the final image from the scratch image that contain files you want to export | ||
| FROM scratch | ||
|
|
||
| COPY --from=ext /tmp/oci8.so /opt/bref/extensions/oci8.so | ||
| COPY --from=ext /tmp/ext.ini /opt/bref/etc/php/conf.d/ext-oci8.ini | ||
| COPY --from=ext /tmp/extension-libs /opt/lib | ||
| COPY --from=ext /tmp/extension-libs /opt/lib | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,7 @@ | ||
| { | ||
| "php": [ | ||
| "83", | ||
| "84", | ||
| "85" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| services: | ||
| db: | ||
| image: container-registry.oracle.com/database/free:latest-lite | ||
| ports: | ||
| - "1521:1521" | ||
| environment: | ||
| - ORACLE_PWD=testing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,45 @@ | ||
| <?php | ||
|
|
||
| if (!function_exists($func = 'oci_connect')) { | ||
| if (! extension_loaded('oci8')) { | ||
| echo 'FAIL: Extension "oci8" is not loaded.'.PHP_EOL; | ||
| exit(1); | ||
| } | ||
|
|
||
| if (! function_exists($func = 'oci_connect')) { | ||
| echo sprintf('FAIL: Function "%s" does not exist.', $func).PHP_EOL; | ||
| exit(1); | ||
| } | ||
|
|
||
| $clientVersion = oci_client_version(); | ||
| if (empty($clientVersion) || $clientVersion === '0.0.0.0.0') { | ||
| echo 'FAIL: Extension loaded, but can\'t find Oracle Instant Client libraries.'.PHP_EOL; | ||
| exit(1); | ||
| } | ||
|
|
||
| // Test live connection assuming db container is started (see docker-compose.yml for example). | ||
| // You may need to add --add-host=host.docker.internal:host-gateway to Makefile test: docker run if | ||
| // you are on Linux | ||
| /* | ||
| $conn = oci_connect('SYSTEM', 'testing', 'host.docker.internal/FREE'); | ||
| if (! $conn) { | ||
| echo 'FAIL: Can\'t connect to Oracle database: '.oci_error()['message'].PHP_EOL; | ||
| exit(1); | ||
| } | ||
|
|
||
| $stid = oci_parse($conn, 'SELECT 1 FROM DUAL'); | ||
| if (! $stid) { | ||
| echo 'FAIL: Can\'t parse SQL statement: '.oci_error($conn)['message'].PHP_EOL; | ||
| oci_close($conn); | ||
| exit(1); | ||
| } | ||
|
|
||
| if (! oci_execute($stid)) { | ||
| echo 'FAIL: Can\'t execute SQL statement: '.oci_error($conn)['message'].PHP_EOL; | ||
| oci_close($conn); | ||
| exit(1); | ||
| } | ||
| $stid = null; | ||
| oci_close($conn); | ||
| */ | ||
|
|
||
| exit(0); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested the layer? Here the library is installed in an image that is not the one used in AWS Lambda, there's high risk the library is incompatible when running in Lambda.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did. I created a custom layer and ran it with
arn:aws:lambda:us-west-2:873528684822:layer:php-84:16. It connected and queried an Oracle database happily. I even tried it with the v2 layer (al.2) - which failed due to an incompatible lib. I totally get if you're not comfortable approving this PR. It could certainly have some sneaky issues. I'm happy to keep using my custom layer until you or the previous maintainer can get around to updating it :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes — I tested this in a real AWS Lambda environment and it works correctly.
I built a custom OCI8 layer and deployed it in a Lambda running Bref 3 on Amazon Linux 2023. The function successfully connects and executes queries against an Oracle database using oci_connect().
The Dockerfile is parameterized, so the same build works for PHP 8.3+ (8.3 / 8.4 / 8.5) by simply changing the PHP_VERSION build argument.
Example:
docker build
–build-arg PHP_VERSION=83
–build-arg BREF_VERSION=v3
-t oci8-layer .
Then the /opt directory is extracted and packaged as a Lambda layer.
After attaching the layer to the Lambda function and setting:
LD_LIBRARY_PATH=/opt/lib
OCI8 works correctly in the Lambda runtime.
One important thing I discovered during testing:
Oracle Instant Client 23.26 caused PHP-FPM crashes in Lambda.
The extension loaded correctly (it appeared in phpinfo()), but any call to oci_connect() triggered:
Error communicating with PHP-FPM to read the HTTP response.
Bref will restart PHP-FPM now.
CloudWatch logs showed the PHP-FPM worker exiting.
After switching to Oracle Instant Client 21.12, the problem disappeared and OCI8 worked perfectly.
Another small issue was that the runtime layer must include libociicus.so, otherwise OCI8 fails with:
OCIEnvNlsCreate() failed
Once that library was added to the layer, everything worked as expected.
This setup also works correctly with Laravel using the yajra/laravel-oci8 package, so applications using that driver can run without problems on Lambda.
So yes — this solution has been tested in a real Lambda environment and works correctly with:
• Bref 3
• Amazon Linux 2023
• PHP 8.3+ (8.3 / 8.4 / 8.5)
• Oracle Instant Client 21.12