I am working on a PHP API and I would like to disable unused php Modules inside my PHP-FPM image, such as "sqlite3, pdo ..".
I am a docker beginner and I would like to know if is there anything similar to docker-php-ext-enable if not what is the best practice for disabling unused php modules.
Finally I found the key point.
Inside docker php container, all the registered modules holds by a configuration file under the below path.
/usr/local/etc/php/conf.d/*.ini
bash into the container:
docker exec -it php_container_name bash
You can list all the enabled modules by php -m:
And cd into that folder, you can see the relating config files:
cd /usr/local/etc/php/conf.d/
ls
# output
docker-php-ext-mcrypt.ini docker-php-ext-mysqli.ini
docker-php-ext-opcache.ini opcache-recommended.ini
docker-php-ext-zip.ini
To disable some extension module, make a dir disabled, and move that .ini file inside it, for example:
mkdir disabled
mv docker-php-ext-opcache.ini disabled
mv opcache-recommended.ini
Finally, press Ctrl+D to exit the container, and then restart the container to make changes work.
docker restart php_container_name
You can get into the container and run php -m to see, the relating extension is gone.
Piggybacking off Alfred's answer but I made these today.
alias disDebugCust="docker exec -it xdebugContainer bash -c 'cd /usr/local/etc/php/conf.d/ && mkdir -p disabled && mv xdebug.ini disabled && /etc/init.d/apache2 reload'"
alias enDebugCust="docker exec -it xdebugContainer bash -c 'cd /usr/local/etc/php/conf.d/disabled && mv xdebug.ini /usr/local/etc/php/conf.d/ && /etc/init.d/apache2 reload'"
First we exec into the container.
Then we go to the config folder.
Then we make a new directory called disabled if one doesn't exist.
Then we move the ini file.
Finally we restart apache.
The second command just moves it back and restarts apache.
In my case i had to enable/disable xdebug extension. I appears that there's some 'magic' that works by (de-)suffixing extensions ini file with -disabled.
Once the suffix changes, php somehow magically loads/unloads module. You can check that by running php -m command. (maybe this behaviour is only alpine-linux related??)
I wrote additional docker-php-ext-disable-xdebug script by taking example from /usr/local/bin/docker-php-ext-enable-xdebug:
#!/bin/sh
if test -f '/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini'; then
echo 'Disabling extension xdebug'
mv '/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini' '/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini-disabled'
else
echo 'The extension xdebug is not enabled'
fi
Yes that's possible.
Taken from https://hub.docker.com/_/php/
For example, if you want to have a PHP-FPM image with iconv, mcrypt and gd extensions, you can inherit the base image that you like, and write your own Dockerfile like this:
FROM php:7.0-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
&& docker-php-ext-install -j$(nproc) iconv mcrypt \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd
Remember, you must install dependencies for your extensions manually. If an extension needs custom configure arguments, you can use the docker-php-ext-configure script like this example.
Related
I am new to docker. Hardly I have containerized my php application to run it in the web interface. But I have some cron to run with it. I learnt how to create separate cron image and run it from How to run a cron job inside a docker container?. But my use case is different. I need to use the php files from my php application container which seems not possible from my way. I tried creating the docker-compose.yml as follow to see if it would work
docker-compose.yml:
version: "3"
services:
app:
build:
context: ./docker/php
container_name: 'app'
restart: 'always'
ports:
- "80:80"
- "443:443"
links:
- db
volumes:
- ${DOCUMENT_ROOT-./src}:/var/www/html
- ${PHP_INI-./docker/php/php.ini}:/usr/local/etc/php/php.ini
- ${VHOSTS_DIR-./docker/apache2/vhosts}:/etc/apache2/sites-enabled
- ${LOG_DIR-./docker/logs/apache2}:/var/log/apache2
extra_hosts:
- "test.local:127.0.0.1"
hostname: cloudservice.local
domainname: local
#entrypoint: sh /var/www/html/cron.sh
As I have commented entry point here and if I do docker-compose up, everything works perfectly fine, My Dockerfile is as under
Dockerfile:
FROM php:7.2.27-apache
RUN apt-get update
RUN apt-get install -y cron
RUN apt-get -y update --fix-missing
RUN apt-get upgrade -y
# Install useful tools
RUN apt-get -y install apt-utils nano wget dialog
# Install important libraries
RUN apt-get -y install --fix-missing apt-utils build-essential git curl libcurl4 libcurl4-openssl-dev zip
# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install xdebug
#RUN pecl install xdebug-2.5.0
#RUN docker-php-ext-enable xdebug
# Other PHP7 Extensions
RUN apt-get -y install libsqlite3-dev libsqlite3-0 default-mysql-client
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install pdo_sqlite
RUN docker-php-ext-install mysqli
RUN docker-php-ext-install curl
RUN docker-php-ext-install tokenizer
RUN docker-php-ext-install json
RUN apt-get -y install zlib1g-dev
RUN docker-php-ext-install zip
RUN apt-get -y install libicu-dev
RUN docker-php-ext-install -j$(nproc) intl
RUN docker-php-ext-install mbstring
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 pecl install redis-5.1.1 \
&& docker-php-ext-enable redis
# Enable apache modules
RUN a2enmod rewrite headers
My cron.sh file is as under
#!/usr/bin/env bash
# Ensure the log file exists
touch /var/www/html/logs/crontab.log
# Ensure permission on the command
chmod a+x /var/www/html/cron-local/hn-shc-rapid-daily.sh
# Added a cronjob in a new crontab
echo "* * * * * bash /var/www/html/cron-local/hn-shc-rapid-daily.sh >> /var/www/html/logs/crontab.log 2>&1" > /etc/crontab
# Registering the new crontab
crontab /etc/crontab
# Starting the cron
/usr/sbin/service cron start
# Displaying logs
# Useful when executing docker-compose logs mycron
tail -f /var/www/html/logs/crontab.log
But with the entry point commented, i cannot run cron. If i don't comment entrypoint, then cron runs, my web application doesn't. Is there any possibility to fix this?
Thanks
At the end of the docker file i added the following code after removing
RUN a2enmod rewrite headers
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron #just any name
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Enable apache modules
RUN a2enmod rewrite headers
CMD cron && /usr/sbin/apache2ctl -D FOREGROUND
and cron.sh was changed to
* * * * * echo "hello world" >> /var/www/html/logs/crontab.log 2>&1
This worked for me. I need not have to add entry neither on docker-compose nor on docker file, but I guess entry also would work.
I don't know if this is the right way to do. If anyone would give me more advance idea, I would be happy to give it a try.
Thanks
I think it's better if you specify the entry point in the docker-compose file without "sh" in front of it. Remember that declaring a new entrypoint in the docker-compose file overwrites the entrypoint in the dockerfile. Link
I would advise you to create your own Entrypoint Script which will execute your crons in the container CMD ["/entrypoint.sh"]
Example:
Create an file and named "entrypoint.sh" or whatever and save it in the same folder where your Dockerfile is located. In this file push your Content from your cron.sh.
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 pecl install redis-5.1.1 \
&& docker-php-ext-enable redis
# Enable apache modules
RUN a2enmod rewrite headers
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
CMD ["/entrypoint.sh"]
But you could also just add your cron directly in the docker file.
...
# Enable apache modules
RUN a2enmod rewrite headers
COPY your-cron.cron /
RUN crontab /your-cron.cron
...
I have set up a Symfony4 project with in a Docker container.
I followed the Jobeet-Tutorial where they use the phpdocker.io - generator.
All works perfect but very slow. So I want to speed up and enable the opcache and configure it.
I found helpful links in the net. So I added to my Dockerfile this:
RUN docker-php-ext-configure opcache --enable-opcache \
&& docker-php-ext-install opcache
# Copy configuration
COPY config/opcache.ini $PHP_INI_DIR/conf.d/
The problem is that I don't have this helperscripts:
docker-php-ext-configure
docker-php-ext-install
docker-php-ext-enable
So I decided to search it in the internet and copy it into my project.
Now I have it in the php-fpm folder of my docker directory.
My directory looks like this now - the scripts are in the beneath the Dockerfile:
Is there any other step I forgot to do, like registering these scripts somewhere?
The most immediate answer to your question is that you need to copy those scripts into the Docker image you are building. To do that, you should create a subdirectory within the php-fpm directory named bin and put all of those scripts in that directory. Then, in your Dockerfile:
COPY bin /usr/local/bin
Now when you try to use that image, the scripts will be within your executable PATH.
However
Those docker-php-ext-* scripts you found are from the PHP project's official Docker images and are intended to be used with those images.
You are using the phpdockerio/php73-fpm:latest image, which seems to use ubuntu:bionic as a base image. These scripts depend heavily on the PHP Dockerfiles, which do a bunch of preparatory steps, such as downloading the source code for the PHP interpreter itself to /usr/src. Making these scripts run directly in a phpdockerio container would be a very involved process.
That leaves you with 2 options:
Forgo the scripts and install Ubuntu's prebuilt packages. You seem to already have the apcu, apcu-bc, cli, curl, json, mbstring, opcache, readline, xml, and zip PHP extensions installed. You can see the full list of packages that are available from the default repos this way by running
docker run --rm -it phpdockerio/php73-fpm:latest bash -c 'apt-get update && apt search ^php7.3-';
When you know which packages you want, you can add them to your Dockerfile.
Switch to using an official PHP image instead so you can use the docker-php-ext-* scripts. The phpdocker-io image you are using is essentially PHP7.3-FPM on Ubuntu, and the closest official PHP image to that is php:7.3-fpm-stretch (Debian 9). You can build and install the extensions listed in Option 1 by changing your PHP-FPM Dockerfile to:
FROM php:7.3-fpm-stretch
# Run in Bash instead of Bourne shell to get lists
RUN ["bash", "-c", " \
#Exits on error or unbound variable. Now we can use semicolons instead of
#ampersands
set -eu; \
\
ext_build_dependencies=( \
#Needed to build php-curl
libcurl4-gnutls-dev \
\
#Needed to build php-mbstring
libedit-dev \
\
#Needed to build php-xml \
libxml2-dev \
\
#Needed to build php-zip
zlib1g-dev libzip-dev \
); \
\
apt-get update; \
apt-get install -y ${ext_build_dependencies[#]}; \
\
#Build the extensions
docker-php-ext-install curl json mbstring readline xml zip ; \
pecl install apcu apcu_bc; \
\
apt-get purge -y ${ext_build_dependencies[#]}; \
apt-get autoremove -y; \
apt-get clean -y; \
"]
If Ubuntu 18 and Debian were binary-compatible (they're not), you could try a third option, which would be building the extensions using a PHP image, then copying over the built extensions as the second stage of a multi-stage build. This would be possible if your image uses the same Linux flavor as as the PHP image does. For example, if your image were based on alpine:3.8, you could use php:7.3-fpm-alpine3.8 to build your extensions and copy them over.
[Fri Jul 27 03:08:18.935217 2018] [:error] [pid 11] [client 172.18.0.1:54146] PHP Fatal error: Cannot redeclare CreateUniqeSlugOfuser() (previously declared in /var/www/public_html/livesite/application/helpers/MY_url_helper.php:111) in /var/www/public_html/livesite/application/helpers/my_url_helper.php on line 111
Above is the error, I thought maybe this was a simple rename the file in my directory to MY_url_helper with the uppercase but this did not fix the error as some sites have said. As it stands I have no idea how to fix this but I do have some clues.
I'm not a code igniter expert, I took on this project from another developer, but it currently works on their server. It does not work on my server however. Seeing as the issue is probably with autoloading, what could be the thing I'm doing wrong? Could a different version in PHP be causing this issue?
Another hunch is maybe it's some cache I have to change? I'm not sure though... any ideas are appreciated.
I will say after changing the file name the error still thinks I'm using the lowercase version? I know it's reading the file cause I can throw phpinfo in the file and it seems to trigger hence the image I uploaded as a result of that.
Update:: Did echo CI_VERSION command to find this (2.2.0). Maybe this version is not compatible with PHP 7.0?
php56 is for sure the version on the other server... I will see if I can get a docker image of this somehow.
Well 5.6 still error.
Dockerfile
FROM php:5.6-apache
MAINTAINER Joe Astrahan <jastrahan#poolservice.software>
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y \
bzip2 curl git less mysql-client sudo unzip zip \
libbz2-dev libfontconfig1 libfontconfig1-dev \
libfreetype6-dev libjpeg62-turbo-dev libpng-dev libzip-dev && \
rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install bz2 && \
docker-php-ext-configure gd \
--with-freetype-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ && \
docker-php-ext-install gd && \
docker-php-ext-install iconv && \
docker-php-ext-install opcache && \
docker-php-ext-install pdo_mysql && \
docker-php-ext-install zip
RUN curl -sS https://getcomposer.org/installer \
| php -- --install-dir=/usr/local/bin --filename=composer
# Set environment variables for Apache so we know its user and group names
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
# Configure Apache SSL and Standard Virtualhosts
COPY config/apache_default.conf /etc/apache2/sites-available/000-default.conf
COPY config/apache_default-ssl.conf /etc/apache2/sites-available/default-ssl.conf
COPY config/run /usr/local/bin/run
# Configure SSL Directories & Create Temporary SSL Keys
RUN mkdir /etc/apache2/ssl
RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt -subj "/C=US/ST=Florida/L=Fort Lauderdale/O=Pool Service Software LLC/OU=IT Department/CN=dev.poolservice.software.local"
RUN chmod +x /usr/local/bin/run
RUN a2enmod rewrite
#Configure SSL On Apache2 & Headers Mod
RUN a2enmod ssl
RUN a2enmod headers
RUN service apache2 restart
RUN a2ensite default-ssl.conf
RUN service apache2 restart
#Install Zip & Unzip
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install zip unzip -y
#Install NodeJS
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
software-properties-common
EXPOSE 80
EXPOSE 443
CMD ["/usr/local/bin/run"]
Maybe you already loaded the helper either in autoload or a class that was initialized before you attempted to load it again. CI is able to prevent duplicates with classes but not pure php helper files. That is why they surround their functions with:
if (!function_exists('functionname')) { ... }
I would suggest you do the same.
So I solved the issue. Turns out PHP version didn't really make a difference, my docker file was changed to PHP 7.0 since it worked with that, I'll attach it below.
It turns out that CodeIgniter 2.x was using mysql instead of mysqli, so I changed all references in the code accordingly. Also I had to rename the file my_url_helper to just urlhelper_helper and then in the autoload file change it accordingly so it would load the correct file. For some reason even though it worked on the old server, I had to do this to get it to work with either version of PHP.
These fixes were all that were necessary to fix it.
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.
I want to add Zend Guard Loader support on my php instance.
http://www.zend.com/en/products/loader/downloads#Linux
Normally, I will download the package, and then add the following settings into php.ini
[Zend Guard Loader]
zend_extension="/usr/local/webserver/php/ext/ZendGuardLoader.so"
zend_loader.enable=1
zend_loader.disable_licensing=0
zend_loader.obfuscation_level_support=3
zend_loader.license_path="/var/developer.zl"
But, now I'm running the instance within docker.
docker run --name php_instance php:5-fpm
And I tried to get into the shell:
docker exec -it php_instance bash
But I cannot find the php.ini, how can I make it work?
Did you add a command in your Dockerfile to copy the php.ini file from local to docker container?
Similar to
FROM php:7.1-fpm
# Install system packages
RUN apt-get update && apt-get install -y \
openssl \
libssh2-1 \
libssh2-1-dev \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
RUN pecl install xdebug
# Enable php extensions
RUN docker-php-ext-install mysqli pdo_pgsql
RUN pecl install ssh2-1.1.2
# Copy custom php.ini file
ADD ./deployment/my.php.ini /usr/local/etc/php/