Oracle on Alpine linux - php

I am trying to install OCI8 extension on my Alpine Linux Docker environment. Although there are several places saying it won't work, there are some which say it actually does. I have a 3.4 version and for corporate reasons it is staying like that for now.
I have done this within my Docker conf:
# Install Oracle Client and build OCI8 (Oracel Command Interface 8 - PHP extension)
USER root
ENV LD_LIBRARY_PATH=/usr/local/instantclient
ENV ORACLE_HOME=/usr/local/instantclient
RUN apk update && apk upgrade
RUN apk add musl-dev libaio autoconf && apk add --update make
## Unzip Instant Client v12
RUN pecl channel-update pecl.php.net
COPY instantclient_12_2.zip /var/www/html/instantclient_12_2.zip
RUN unzip -d /usr/local/ /var/www/html/instantclient_12_2.zip
RUN ln -s /usr/local/instantclient_12_2 /${ORACLE_HOME} && \
ln -s /${ORACLE_HOME}/libclntsh.so.* /${ORACLE_HOME}/libclntsh.so && \
ln -s /${ORACLE_HOME}/libocci.so.* /${ORACLE_HOME}/libocci.so && \
ln -s /${ORACLE_HOME}/lib* /usr/lib && \
ln -s /${ORACLE_HOME}/sqlplus /usr/bin/sqlplus &&\
ln -s /usr/lib/libnsl.so.2.0.0 /usr/lib/libnsl.so.1
RUN apk add gcc; exit 0 # This has a history of failing sometimes
RUN echo "instantclient,/usr/local/instantclient" | pecl install oci8 &&\
echo 'extension=oci8.so' > /usr/local/etc/php/conf.d/30-oci8.ini &&\
rm -rf /tmp/*.zip /var/cache/apk/* /tmp/pear/
Now the build passes, and it looks okay, however when I do a php -v I am getting the following:
PHP Warning: PHP Startup: Unable to load dynamic library
'/usr/local/lib/php/extensions/no-debug-non-zts-20160303/oci8.so' -
Error loading shared library libnsl.so.1: No such file or directory
(needed by /usr/local/instantclient/libclntsh.so.12.1) in Unknown on
line 0
PHP version is 7.1.12.
What I've tried is doing apk add libnsl but this returns me this error:
ERROR: unsatisfiable constraints: so:libtirpc.so.3 (missing):
So I tried also adding apk add libtirpc-dev (the 'plain' libtirpc isn't available for my version or something), but that changed nothing.
Any clues?

I share my version of docker that I made to work with the latest version of alpine and instantclient basiclite. The size of the docker image is 124 mb.
I share my github where you can download it
Docker + alpine + Instantclient Basiclite
Or you can see below the content of the dockerfile
FROM alpine:latest
# Install Instantclient Basic Light Oracle and Dependencies
RUN apk --no-cache add libaio libnsl libc6-compat curl && \
cd /tmp && \
curl -o instantclient-basiclite.zip https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip -SL && \
unzip instantclient-basiclite.zip && \
mv instantclient*/ /usr/lib/instantclient && \
rm instantclient-basiclite.zip && \
ln -s /usr/lib/instantclient/libclntsh.so.19.1 /usr/lib/libclntsh.so && \
ln -s /usr/lib/instantclient/libocci.so.19.1 /usr/lib/libocci.so && \
ln -s /usr/lib/instantclient/libociicus.so /usr/lib/libociicus.so && \
ln -s /usr/lib/instantclient/libnnz19.so /usr/lib/libnnz19.so && \
ln -s /usr/lib/libnsl.so.2 /usr/lib/libnsl.so.1 && \
ln -s /lib/libc.so.6 /usr/lib/libresolv.so.2 && \
ln -s /lib64/ld-linux-x86-64.so.2 /usr/lib/ld-linux-x86-64.so.2
ENV ORACLE_BASE /usr/lib/instantclient
ENV LD_LIBRARY_PATH /usr/lib/instantclient
ENV TNS_ADMIN /usr/lib/instantclient
ENV ORACLE_HOME /usr/lib/instantclient

I might be late to answer this. I got the same problem of having a alpine base image and add oracle client to that. So i came up with this solution -
https://github.com/Shrinidhikulkarni7/OracleClient_Alpine
Here is the Dockerfile, but you would also need the shell script in it for it to work.
FROM alpine:latest
ENV LD_LIBRARY_PATH=/lib
RUN wget https://download.oracle.com/otn_software/linux/instantclient/193000/instantclient-basic-linux.x64-19.3.0.0.0dbru.zip && \
unzip instantclient-basic-linux.x64-19.3.0.0.0dbru.zip && \
cp -r instantclient_19_3/* /lib && \
rm -rf instantclient-basic-linux.x64-19.3.0.0.0dbru.zip && \
apk add libaio
ADD script.sh /root/script.sh
RUN /root/script.sh
Over here I'm directly downloading the oracle client inside image, setting the path, adding packages and finally using the shell script for creating symbolic link.

I'd recommend using an operating system supported by Oracle, thus avoiding the headache of hacking Alpine and the uncertainty that it won't fall over at a critical time. And thus giving you some confidence your business won't be negatively impacted. Try https://github.com/oracle/docker-images/tree/master/OracleInstantClient
Other comments
Don't set ORACLE_HOME when using Instant Client. That variable is
for full software installs.
Use ldconfig to set the system library path, see
the Instant Client installation instructions e.g. here.
Use Instant Client 19, which can connect to the same DB versions that 12.2 can. (19 is really the renamed terminal 12.2 release in the new versioning system)
Using Oracle Linux Docker images has the advantage that it will download and install the 19 Instant Client without you having to manually do the download.
See this blog for info about the 'slim' Oracle Linux container it uses.

Here is the Dockerfile For Golang With ORACLE-CLIENT
FROM golang:alpine
RUN apk update
ENV CLIENT_FILENAME instantclient-basic-linux.x64-12.1.0.1.0.zip
WORKDIR /opt/oracle/lib
ADD https://github.com/bumpx/oracle-instantclient/raw/master/${CLIENT_FILENAME} .
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
apk add --update libaio libnsl && \
ln -s /usr/lib/libnsl.so.2 /usr/lib/libnsl.so.1
RUN LIBS="*/libociei.so */libons.so */libnnz12.so */libclntshcore.so.12.1 */libclntsh.so.12.1" && \
unzip ${CLIENT_FILENAME} ${LIBS} && \
for lib in ${LIBS}; do mv ${lib} /usr/lib; done && \
ln -s /usr/lib/libclntsh.so.12.1 /usr/lib/libclntsh.so && \
rm ${CLIENT_FILENAME}
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN apk add git
RUN apk add libc-dev
RUN apk add gcc
RUN go mod tidy
RUN go build -o main .
CMD ["/app/main"]

I was just tackling a similar problem to this using the Godror Golang Driver for Oracle. I was never able to solve this on using an Alpine image. The problem eventually came that libint.sh, would never fully install to be recognized by the system. Even changing the docker file to using the Glibc library.
How i eventually fixed the issue was to use the images from Oracle itself. The full version not the slim images that can be seen here: https://github.com/oracle/docker-images/tree/master/OracleLinuxDevelopers
you then have to install golang and then your Instant client and Oracle dependencies if you need it.
FROM oraclelinux:7 as builder
RUN yum install -y oracle-golang-release-el7 && \
yum install -y git && \
yum install -y golang unzip
COPY . /app
RUN go version
WORKDIR /app
{Your Docker Specific Commands Here}
{Insert Build Specific Environment Variables here}
#Oracle Specific Environment Variables
{Insert Oracle Env Variables here}
WORKDIR /root/
#Install oracle dependencies
RUN yum install -y wget unzip libaio && \
rm -rf /var/cache/yum
#install Oracle Instant Client
RUN wget https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-basic-linux.x64-19.9.0.0.0dbru.zip -O /tmp/instantclient.zip && \
unzip /tmp/instantclient.zip -d /usr/lib/instantclient && \
rm /tmp/instantclient.zip
#Install Oracle SDK
RUN wget https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-sdk-linux.x64-19.9.0.0.0dbru.zip -O /tmp/instantclient-sdk-linux.x64-19.9.0.0.0.zip && \
unzip /tmp/instantclient-sdk-linux.x64-19.9.0.0.0.zip -d /usr/lib/ && \
rm /tmp/instantclient-sdk-linux.x64-19.9.0.0.0.zip
#Install Oracle Tools through SQLPlus
RUN wget https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-sqlplus-linux.x64-19.9.0.0.0dbru.zip -O /tmp/instantclient-sqlplus-linux.x64-19.9.0.0.0.zip && \
unzip /tmp/instantclient-sqlplus-linux.x64-19.9.0.0.0.zip -d /usr/lib/ && \
rm /tmp/instantclient-sqlplus-linux.x64-19.9.0.0.0.zip
WORKDIR /app
COPY --from=builder /app/cmd/svr .
EXPOSE 8000
CMD ["./app"]
Again this is how i solved the problem for a Golang API. There may be others that solved the Alpine issue but i was never able to get it to work, even using older version of the Oracle Instant Client.

Try this Docker file. Start from the basic alpine linux image and add the required packages.
FROM alpine:3.13
WORKDIR /project
RUN wget https://download.oracle.com/otn_software/linux/instantclient/211000/instantclient-basiclite-linux.x64-21.1.0.0.0.zip -qO- | busybox unzip -q - && \
wget https://download.oracle.com/otn_software/linux/instantclient/211000/instantclient-sqlplus-linux.x64-21.1.0.0.0.zip -qO- | busybox unzip -q - && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.33-r0/glibc-2.33-r0.apk -q
RUN apk add --allow-untrusted libaio glibc-2.33-r0.apk
RUN cd instantclient_21_1 && cp /usr/lib/libaio.so.1 /lib/libc.musl-x86_64.so.1 . && chmod +x sqlplus
ENV LD_LIBRARY_PATH=/project/instantclient_21_1

Related

Docker container takes 8 seconds to execute simple php comand in windows

I was using a docker container with php:8.1.6-cli and running my laravel aplication.
When i attach the terminal to the container and run a simple command php artisan inspire the docker takes 8 seconds to execute.
My php.ini config:
file_uploads = On
allow_url_fopen = On
memory_limit = 256M
upload_max_filesize = 100M
max_execution_time = 360
date.timezone = America/Sao_Paulo
My Dockerfile for this container:
FROM php:8.1.6-cli
LABEL maintainer="Crazynds"
WORKDIR /workspace
ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC-3
ENV NODE_VERSION=16
USER root
RUN apt-get update \
&& apt-get install -y libcurl4-openssl-dev libonig-dev libzip-dev libpq-dev build-essential gnupg gosu curl zip unzip git supervisor libcap2-bin libpng-dev python2 locales \
&& mkdir -p ~/.gnupg \
&& chmod 600 ~/.gnupg
RUN php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
&& curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -
RUN apt-get install -y nodejs nano wget dos2unix
RUN apt-get -y autoremove \
&& apt-get clean\
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN pecl install redis && docker-php-ext-enable redis; exit 0
RUN docker-php-ext-install pdo_mysql pdo_pgsql mbstring exif pcntl curl zip gd
ENTRYPOINT ["sleep","infinity"]
How i find the problem that takes most of the time to execute the php comands?
Is there any way to check what is consuming each part of time in the execution?
I find the solution. The docker with volumes mounted using Windows dirs are slow.
The solution for my problem is to create the vendor folder and the node_modules in separated volumes, instead of mounting them from Windows folder.
That alone gave a big performance boost, now the response time is around 1 second, but if I mounted my entire project on the volume instead of a folder, it would be much faster.

Powershell module import not persisting in docker container image

I installed powershell in the php debian docker image and now I am installing PowerCLI module in the docker image to access the vsphere info and display using laravel. The issue is with the PowerCLI installation. Powershell doesn't seem to persist the modules installed and imported. When I import module and use RUN pwsh -c connect-viserver, it seems working in the docker-image. But when I call the cmdlet in laravel container as $process = new Process(['pwsh', '-c','Connect-VIServer', 'SERVERNAME']); it fails. I check to see if it is imported iin the powershell by accessing container docker exec -it app bash But the module is not installed. I am manually keeping the modules in a folder powershell/Modules and adding it to $env:$PSModulePath
I do not understand what I'm missing.
Here's is my docker file.
FROM php:7.4-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
RUN pwd
# Set working directory
WORKDIR /var/www
RUN pwd
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libonig-dev \
locales \
libzip-dev \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
wget \
apt-utils
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl mysqli
RUN docker-php-ext-configure gd --enable-gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-enable mysqli
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
#########################
RUN pwd
# Download the Microsoft repository GPG keys
RUN wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb
# Register the Microsoft repository GPG keys
RUN dpkg -i packages-microsoft-prod.deb
# Update the list of products
RUN apt-get update
# Install PowerShell
RUN apt-get install -y powershell
# Start PowerShell
#RUN pwsh
# Allow installation from PSGallery
SHELL ["pwsh", "-command"]
RUN Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
#RUN Install-Module VMware.VimAutomation.Core -Confirm:$false
#RUN Import-Module VMware.VimAutomation.Core; Get-Module
#RUN Set-PowerCLIConfiguration -ParticipateInCEIP $false -Confirm:$false
#RUN Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
##RUN connect-viserver 10.21.24.9
RUN Get-Module -ListAvailable VMware.VimAutomation.Core | Import-Module
RUN $env:PSModulePath = $env:PSModulePath + ":/var/www/powershell/Modules"
RUN mkdir -p /root/.config/powershell
RUN touch /root/.config/powershell/Microsoft.PowerShell_profile.ps1
RUN echo "Get-Module -ListAvailable PowerCLI* | Import-Module" >> /root/.config/powershell/Microsoft.PowerShell_profile.ps1
RUN $PSHome
RUN Get-Module
SHELL ["/bin/sh", "-c"]
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
RUN pwd
RUN ls -la && ls -la /var/www/powershell/Modules/

How to install pdo_odbc in Docker php image

I'm trying to connect to mssql with PDO and Laravel but I think I'm having issues installing the driver. There are no build errors, but I've looked around everywhere to try to find a solution, and they produce either an error or just does not work. When attempting to make a connection to a mssql server, it gives this error:
Illuminate\Database\QueryException: could not find driver (SQL: SELECT * FROM SAMPLE_VIEW_SM1 WHERE STUDENTS_ID=1) in file /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 664
Caused by
PDOException: could not find driver in file /var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php on line 70
Here is my dockerfile:
FROM php:7.3-fpm-buster
ENV DEBIAN_FRONTEND=noninteractive
RUN rm /etc/apt/preferences.d/no-debian-php
RUN apt-get update -y && apt-get install -y \
openssl \
zip \
unzip \
git \
curl \
freetds-common \
freetds-bin \
unixodbc \
unixodbc-dev \
php-smbclient \
php7.3-sybase
RUN docker-php-ext-configure pdo_odbc --with-pdo-odbc=unixodbc,/usr
RUN docker-php-ext-install pdo_odbc
RUN docker-php-ext-enable pdo_odbc
# Install node and dependencies
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
RUN mkdir /cache
WORKDIR /cache
COPY package.json ./
COPY package-lock.json ./
RUN npm install
# Set file size limits
RUN echo "post_max_size=50M" >> /usr/local/etc/php/php.ini-production
RUN echo "upload_max_filesize=10M" >> /usr/local/etc/php/php.ini-production
RUN echo "memory_limit=6400M" >> /usr/local/etc/php/php.ini-production
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Create application's working directory
WORKDIR /var/www
COPY . .
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install
RUN cp -r ./vendor/. /cache/vendor/
RUN chmod -R a+rwX /var/www/storage
RUN chmod -R +x ./entrypoint.sh
EXPOSE 9000
ENTRYPOINT [ "./entrypoint.sh" ]
I just published a solution related to this, I hope it serves you, greetings.
https://stackoverflow.com/a/68536444/5639865

Execute a build-in PHP server file with Docker

I have a php application in Github, and I want to create a Docker image to, automaticaly, clone this application and run a custom server php file (react-php implemented).
This is my point of start.
FROM php:7.1-cli
RUN apt-get update && \
apt-get install -y \
libzip-dev \
zip \
&& docker-php-ext-configure zip --with-libzip \
&& docker-php-ext-install zip bcmath
RUN apt-get install -y \
git-core \
curl && \
git clone https://github.com/xxx/xxx.git myfolder && \
cd myfolder && \
curl -sS https://getcomposer.org/installer | php && \
php composer.phar install
EXPOSE 8000
CMD ["php bin/server"]
This code allows me to build the image, but when I run this image in a container, then I'm not being able to execute the file.
/usr/local/bin/docker-php-entrypoint: 9: exec: php bin/server: not
found
Maybe it's because I don't barely understand some bases of Docker, but it's getting hard for me to make this happen.
Any help on that, please?
According to the official docker documentation for CMD, you should try to modify the last line of your Dockerfile to either CMD php bin/server or CMD ["php", "bin/server"]
Furthermore if you want your commands to be executed with a relative path, you should consider setting the working directory with the WORKDIR directory command before using RUN, CMD, ENTRYPOINT, COPY or ADD.

How to install PHP soap extension on Alpine 3.6

I'm having issues trying to install and enable the PHP soap extension. I'm running the base image php:7.2-fpm-alpine3.6 inside a Docker container that has instructions like below in the Dockerfile. It's unclear to me how extensions are installed on Alpine. It seems to use docker-php-ext-install from what I can infer.
Dockerfile (I adopted this from somewhere):
RUN apk --no-cache add \
freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev \
wget \
git \
nginx \
ca-certificates \
supervisor \
bash \
nano \
&& docker-php-ext-install \
mysqli \
pdo_mysql \
opcache \
...
So, I tried
docker-php-ext-install soap
which told me configure: error: xml2-config not found. Please check your libxml2 installation. I tried a bunch of stuff, but
apk add --no-cache libxml2-dev
seemed to do something. I followed this again with docker-php-ext-install soap, which outputted
Build complete.
Don't forget to run 'make test'.
Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20170718/
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la modules/* libs/*
At this point, I did not run make test, as it's unclear where I'm suppose to go find this Makefile. I searched under /usr/local/lib/php/extensions/no-debug-non-zts-20170718/, and soap.so was already there. Furthermore, my commands already enabled it for PHP-FPM. php -i showed /usr/local/etc/php/conf.d/docker-php-ext-soap.ini,.
I'm not entirely sure what I did. Is this (docker-php-ext-install) how you install extensions on this OS?
The PHP SOAP extension requires the PHP XML extension, as documented here: http://php.net/manual/en/soap.requirements.php
I expect you need to install that first.
Presumably docker-php-ext-install xml.
You shouldn't need to compile the XML library yourself as it will be part of the extension.
The solution is:
RUN set -ex && apk --no-cache add libxml2-dev
RUN docker-php-ext-install soap
You can add a utility to your image using this package
Example:
FROM php:7.2-cli
ADD https://raw.githubusercontent.com/mlocati/docker-php-extension-installer/master/install-php-extensions /usr/local/bin/
RUN chmod uga+x /usr/local/bin/install-php-extensions && sync && \
install-php-extensions gd xdebug
If you want, you can remove the last line and enter the container to play around with adding packages.
docker exec -it <container_id> bash # (swap bash for sh if using alpine)
Then you can just type install-php-extensions <ext>
Not every alpine distribution contains docker-php-ext commands etc, and I don't know how to add them easily, it did not look simple at all to me.
Anyway, any php extension can be easily installed by issuing this alpine install command
to find any php extension
apk search -v 'php' |grep ldap
result
phpldapadmin-1.2.3-r4 - Web front-end for managing OpenLDAP
php7-ldap-7.2.22-r0 - PHP7 extension: LDAP
php5-ldap-5.6.40-r0 - ldap extension for PHP
to further install the extension, one must supply its name in a form without the suffix version part , eg. without -7.2.22-r0 in php7-ldap-7.2.22-r0 so it's php7-ldap
like this
apk install php7-ldap

Categories