I am building an app (PHP/Laravel) that is supposed to be deployed on Google's App Engine. One of the components of the app is to be able to connect to an MSSQL server. Everything worked fine when I was debugging it, but as soon as I deployed it to the App Engine - guess what? It does not work (error: could not find driver).
I went through the Google documentation and I found out that the MSSQL drivers (pdo_sqlsrv, sqlsrv) are not enabled nor available in the standard environment. I checked the flexible environment, but that's the same. The difference is that I can use my own runtime using Dockerfile.
I changed two lines of my app.yaml in the root directory:
runtime: custom
env: flex
Then I created my Dockerfile also in the root directory that was supposed to install sqlsrv and pdo_sqlsrv using PECL and enable it:
FROM gcr.io/google-appengine/php72:latest
ARG COMPOSER_FLAGS='--prefer-dist --ignore-platform-reqs --optimize-autoloader'
ENV COMPOSER_FLAGS=${COMPOSER_FLAGS}
ENV SWOOLE_VERSION=4.3.4
ENV DOCUMENT_ROOT=/app/public
ENV ACCEPT_EULA=Y
COPY . $APP_DIR
RUN apt-get update -y \
&& curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -\
&& curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update -y \
&& apt-get install -y \
unzip \
autoconf \
build-essential \
libmcrypt-dev \
libmpdec-dev \
libpq-dev \
unixodbc-dev \
msodbcsql17 \
mssql-tools \
php-common \
&& apt-get update \
&& pecl install \
decimal \
sqlsrv \
pdo_sqlsrv \
xdebug \
&& apt-get update \
&& phpenmod sqlsrv pdo_sqlsrv \
&& curl -o /tmp/swoole.tar.gz https://github.com/swoole/swoole-src/archive/v$SWOOLE_VERSION.tar.gz -L \
&& tar zxvf /tmp/swoole.tar.gz \
&& cd swoole-src* \
&& phpize \
&& ./configure \
--enable-coroutine \
--enable-async-redis \
--enable-coroutine-postgresql \
--enable-sqlsrv=static --with-pdo_sqlsrv=static \
&& make \
&& make install \
&& chown -R www-data.www-data $APP_DIR \
&& /build-scripts/composer.sh;
ENTRYPOINT ["/build-scripts/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
EXPOSE 8080
I also have my own php.ini with two lines in the root directory:
extension = pdo_sqlsrv.so
extension = sqlsrv.so
According to the Google documentation, having this file in the root of an app will extend/replace their default php.ini with my configuration. However, I only found this statement in the docs for non-custom runtimes. I tested it out by changing the value of display_errors and then phpinfo(). The display_errors was still set to the default value and get_loaded_extensions() didn't display sqlsrv nor pdo_sqlsrv.
I checked the build-log and it seems that the drivers were properly installed, because in the 3714 lines I found:
Installing '/opt/php72/lib/x86_64-linux-gnu/extensions/no-debug-non-zts-20170718/sqlsrv.so'
install ok: channel://pecl.php.net/sqlsrv-5.8.1
.....
Installing '/opt/php72/lib/x86_64-linux-gnu/extensions/no-debug-non-zts-20170718/pdo_sqlsrv.so'
install ok: channel://pecl.php.net/pdo_sqlsrv-5.8.1
.....
configuration option "php_ini" is not set to php.ini location
You should add "extension=sqlsrv.so" to php.ini
configuration option "php_ini" is not set to php.ini location
You should add "extension=pdo_sqlsrv.so" to php.ini
Does anybody have any experience with this, please? What do I need to change in the Dockerfile to make Google App Engine enable the PHP extensions?
TL;DR: Add COPY php.ini /opt/php/lib/conf.d/ to Dockerfile.
Google documentation for GAE Standard environment says that you can place php.ini into the root directory, but I didn't find anything like that about Flexible env. Indeed, if you check Configuration File in phpinfo, and related. fields, they show other paths they're looking for php.ini, so you need to place the file there.
When I try that, the custom php.ini is loaded and allows overwriting display_errors, which you mentioned didn't work for you.
Multi-stage build
To avoid shipping C compiler and other build tools to production, which is wasteful and may slow down deployment of your app, you should also use docker's multi-stage build. Basically, you'll build the extensions in one "builder" container and copy the compiled result to the production container.
You Dockerfile will look sth like this:
FROM gcr.io/google-appengine/php72:latest AS builder
RUN apt-get update -y \
&& apt-get install -y \
unzip \
autoconf \
build-essential \
libmcrypt-dev \
libmpdec-dev \
libpq-dev \
unixodbc-dev \
php-common \
&& pecl install \
sqlsrv \
pdo_sqlsrv
FROM gcr.io/google-appengine/php72:latest
# Copy extensions from builder above
ENV PHP_EXT_DIR=/opt/php/lib/x86_64-linux-gnu/extensions/no-debug-non-zts-20170718/
COPY --from=builder $PHP_EXT_DIR/sqlsrv.so $PHP_EXT_DIR/
COPY --from=builder $PHP_EXT_DIR/pdo_sqlsrv.so $PHP_EXT_DIR/
# Install runtime dependencies
ENV ACCEPT_EULA=Y
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -\
&& curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update -y \
&& apt-get install -y \
msodbcsql17 \
mssql-tools
...
Related
I'm developing a Laravel application using Docker. I use multiple containers for different services; App (PHP), Webserver (Nginx), Relational Database (MySql) and In-Memory Database (Redis).
I've written a Dockerfile for App service using php:8.1-fpm as the base image. The problem is when I bring up the container and go to /usr/local/etc/php folder to check the installed extensions (I tried to use FFI extension and it turned out that it is disabled), I found two files: php.ini-development and php.ini-production. When I executed cat command on them, I found out that almost all the extensions are disabled by default in both of them.
So my question is do I need to enable them myself each time I bring up the container? Isn't there a better way?
Here is my Dockerfile:
FROM php:8.1-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get upgrade -y && apt-get install apt-utils procps -y \
&& apt-get install -y build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libonig-dev \
libxml2-dev \
locales \
libzip-dev \
libpq-dev \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl libgmp-dev libevent-dev libssl-dev libnghttp2-dev libffi-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install sockets gd mysqli pdo pdo_mysql mbstring zip exif pcntl soap gmp bcmath ffi
# Install additional extension
RUN mkdir -p /usr/src/php/ext/ && cd /usr/src/php/ext/ \
&& pecl bundle ev \
&& docker-php-ext-install -j$(nproc) ev
# Install PrimeModule for AuthKey generation speedup
RUN git clone https://github.com/danog/PrimeModule-ext \
&& cd PrimeModule-ext && make -j$(nproc) \
&& make install \
&& cd ../ \
&& rm -rf PrimeModule-ext/
RUN pecl install -o -f redis \
&& rm -rf /tmp/pear \
&& docker-php-ext-enable redis \
&& docker-php-source delete \
&& apt-get autoremove --purge -y && apt-get autoclean -y && apt-get clean -y \
&& rm -rf /usr/src
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install nodejs
# RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
# RUN apt-get update && apt-get install -y nodejs
# 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"]
And Here is the first part of php.ini-development file (As it is a long file, I didn't copy all lines of the file):
; Be sure to appropriately set the extension_dir directive.
;
;extension=bz2
;extension=curl
;extension=ffi
;extension=ftp
;extension=fileinfo
;extension=gd
;extension=gettext
;extension=gmp
;extension=intl
;extension=imap
;extension=ldap
;extension=mbstring
;extension=exif ; Must be after mbstring as it depends on it
;extension=mysqli
;extension=oci8_12c ; Use with Oracle Database 12c Instant Client
;extension=oci8_19 ; Use with Oracle Database 19 Instant Client
;extension=odbc
;extension=openssl
;extension=pdo_firebird
;extension=pdo_mysql
;extension=pdo_oci
;extension=pdo_odbc
;extension=pdo_pgsql
;extension=pdo_sqlite
;extension=pgsql
;extension=shmop
; The MIBS data available in the PHP distribution must be installed.
; See https://www.php.net/manual/en/snmp.installation.php
;extension=snmp
;extension=soap
;extension=sockets
;extension=sodium
;extension=sqlite3
;extension=tidy
;extension=xsl
;zend_extension=opcache
This question already has answers here:
ADD failed : No such file/Directory while building docker image
(3 answers)
Closed 2 years ago.
I got this error when building docker php image
Step 13/25 : ADD php.ini /usr/local/etc/php/php.ini
ERROR: Service 'phpt3' failed to build: ADD failed: stat
/var/lib/docker/tmp/docker-builder310748204/php.ini: no
such file or directory
Below is the docker file:
FROM php:7.3-fpm
# install the PHP extensions we need
RUN apt-get update \
&& apt-get install -y --no-install-recommends msmtp mailutils vim curl debconf subversion git apt-transport-https apt-utils \
build-essential locales acl mailutils wget nodejs \
gnupg gnupg1 gnupg2 \
zlib1g-dev zlib1g-dev libicu-dev g++ \
sudo
# Install GD
RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install -j$(nproc) gd
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install gd
# MYSQLI
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
# Install ext-zip
RUN apt-get install -y unzip libzip-dev
RUN docker-php-ext-install zip
RUN docker-php-ext-configure intl
RUN docker-php-ext-install pdo_mysql json calendar intl
ADD php.ini /usr/local/etc/php/php.ini
COPY additionnal.ini /usr/local/etc/php/conf.d/
COPY php-fpm-pool.conf /usr/local/etc/php/pool.d/www.conf
RUN rm -rf /var/lib/apt/lists/* \
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
echo "fr_FR.UTF-8 UTF-8" >> /etc/locale.gen && \
locale-gen
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer --version
# set up sendmail config, see http://linux.die.net/man/5/ssmtp.conf for options
RUN echo "hostname=localhost.localdomain" > /etc/msmtp/msmtp.conf
RUN echo "mailhub=maildevt3" >> /etc/msmtp/msmtp.conf
# The above 'maildevt3' is the name you used for the link command
# in your docker-compose file or docker link command.
# Docker automatically adds that name in the hosts file
# of the container you're linking MailDev to.
# Set up php sendmail config
RUN echo "sendmail_path=sendmail -i -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini
# Fully qualified domain name configuration for sendmail on localhost.
# Without this sendmail will not work.
# This must match the value for 'hostname' field that you set in ssmtp.conf.
RUN echo "localhost localhost.localdomain" >> /etc/hosts
WORKDIR /var/www/
EXPOSE 9000
CMD ["php-fpm"]
Can anyone help me to overcome this bug.
I'm doing this tutorial
https://passions.miary.dev/2019/08/30/docker-maildev-fr/
It looks like the image installer does not have the rights to write to the installation directory.
-> How to fix:
ADD failed : No such file/Directory while building docker image
If that doesn't work: test if the folder, which is shown in the error exists.
Give enough permissions to the directory with chmod -> https://wiki.ubuntuusers.de/chmod/
Currently , i need to build a custom image that should contain jenkins and php 7.2 .
I have tried this shot :
FROM jenkins/jenkins:lts as jenkins
USER root
ARG TIMEZONE
# update
RUN apt update
# dependencies
RUN apt install -qqy \
tzdata \
wget \
curl \
...
# Timezone
RUN echo "Europe/Paris" > /etc/timezone
FROM php:7.2-apache
WORKDIR /var/jenkins
COPY --from=build-env /app/_site ./
RUN apt-get update && apt-get install -y \
openssl \
git \
unzip vim \
libfreetype6-dev \
...
The second FROM (FROM php:7.2-apache) crush the whole above . And it's normal as docker behavior .
Using the Copy command like COPY --from=jenkins /app/site ./ still blurred since there is not idea what to copy-paste .
Is there any solution to resolve that issue ?
Is there a way to assign a specific PHP version to a drupal Docker container?
I have a docker-compose file to link Drupal with MariaDB.
Everything works so far, but I want to assign a specific PHP version for migration purposes.
Since you are using the official image, they only come with specific php versions. Consider the below docker file of the official image
https://github.com/docker-library/drupal/blob/a8e09f524b89b61534f376e45b885d433d867c88/7/apache/Dockerfile
# from https://www.drupal.org/requirements/php#drupalversions
FROM php:7.0-apache
RUN a2enmod rewrite
# install the PHP extensions we need
RUN set -ex \
&& buildDeps=' \
libjpeg62-turbo-dev \
libpng12-dev \
libpq-dev \
' \
&& apt-get update && apt-get install -y --no-install-recommends $buildDeps && rm -rf /var/lib/apt/lists/* \
&& docker-php-ext-configure gd \
--with-jpeg-dir=/usr \
--with-png-dir=/usr \
&& docker-php-ext-install -j "$(nproc)" gd mbstring pdo pdo_mysql pdo_pgsql zip \
# PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/extensions/no-debug-non-zts-20151012/gd.so' - libjpeg.so.62: cannot open shared object file: No such file or directory in Unknown on line 0
# PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/extensions/no-debug-non-zts-20151012/pdo_pgsql.so' - libpq.so.5: cannot open shared object file: No such file or directory in Unknown on line 0
&& apt-mark manual \
libjpeg62-turbo \
libpq5 \
&& apt-get purge -y --auto-remove $buildDeps
WORKDIR /var/www/html
# https://www.drupal.org/node/3060/release
ENV DRUPAL_VERSION 7.56
ENV DRUPAL_MD5 5d198f40f0f1cbf9cdf1bf3de842e534
RUN curl -fSL "https://ftp.drupal.org/files/projects/drupal-${DRUPAL_VERSION}.tar.gz" -o drupal.tar.gz \
&& echo "${DRUPAL_MD5} *drupal.tar.gz" | md5sum -c - \
&& tar -xz --strip-components=1 -f drupal.tar.gz \
&& rm drupal.tar.gz \
&& chown -R www-data:www-data sites
Now create a copy of this. And change the top FROM php:7.0-apache to the the version you are interested in. You can see all the available versions below
https://hub.docker.com/r/library/php/tags/
And then rebuild the image to create your own drupal image with specific php version
I have a web application on IBM Bluemix. I would like to speed up the app by precompiling the PHP by using Facebook's HHVM. How can this be done? Is this possible on Bluemix?
Thank you,
--
Yeah this actually would be. It would be a little work to do this but with a build pack you can basically run any executable file. You would just need to bind to the port that is assigned by environment variable $PORT. Check out the Cloud Foundry Docs on implementing one. I would take a peak at the C buildpack as well.
The binary buildpack will probably be your best starting place.
You can compile your code using HHVM, I pulled out the relevant pieces from here below. This needs to be done on Ubuntu 14.04 as that is what Bluemix runs on.
Install deps:
sudo apt-get install autoconf automake binutils-dev build-essential cmake g++ gawk git \
libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-regex-dev \
libboost-system-dev libboost-thread-dev libboost-context-dev libbz2-dev libc-client-dev libldap2-dev \
libc-client2007e-dev libcap-dev libcurl4-openssl-dev libdwarf-dev libelf-dev \
libexpat-dev libgd2-xpm-dev libgoogle-glog-dev libgoogle-perftools-dev libicu-dev \
libjemalloc-dev libmcrypt-dev libmemcached-dev libmysqlclient-dev libncurses-dev \
libonig-dev libpcre3-dev libreadline-dev libtbb-dev libtool libxml2-dev zlib1g-dev \
libevent-dev libmagickwand-dev libinotifytools0-dev libiconv-hook-dev libedit-dev \
libiberty-dev libxslt1-dev ocaml-native-compilers libsqlite3-dev libyaml-dev libgmp3-dev \
gperf libkrb5-dev libnotify-dev
Downloading the HHVM source-code:
git clone git://github.com/facebook/hhvm.git --depth=1
cd hhvm
git submodule update --init --recursive
Build HHVM:
cmake -DMYSQL_UNIX_SOCK_ADDR=/var/run/mysqld/mysqld.sock .
make -j [number_of_processor_cores] # eg. make -j 4
sudo make install
The installed hhvm binary can be found in /usr/local/bin
That's easy to do with the built-in PHP buildpack. Simply specify a dependency on HHVM in your composer.json file, like below:
{
"require": {
"hhvm": ">=3.5"
}
}