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

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.

Related

Problem: Different encoding in two equal docker containers

Currently I have a very weird docker behavior and I really hope someone has an idea.
Here are some information about the setup:
My Dockerfile is based on php:7.4.27-apache-buster.
The container is build on two Kubernetes clusters (Staging and Productive).
The PHP application fetches data by a curl request two a third party system and tries to process this data and store it into a mariaDB database.
The mariaDB databases on staging and productive are equally setup.
The third party system responds with same data and encoding on both environments.
The weird behavior is, the staging container works as expected but the production container doesn't encode unicode characters properly.
Because both containers are build with the same Dockerfile, use the same application code, receive the same data and work with equally configured databases, I have no clue how this problem can be even possible. We also already tried to rebuild the container for both environments but nothing changed.
Did anybody experience something like that? Or has anybody any idea what the reason of this difference could be?
Application description:
The PHP application runs on a cron job. Every 15 minutes, a request is sent to a third party system, which response with a dataset in json format. This data is decoded processed by the application. While processing, the application checks for data validity and removes invalid data from the set. As a last step, the data is stored in the database.
MariaDB version:
Prod: 10.1.1
Dev: 10.5.17
PHP version: 7.4.27
Docker version: 20.10.18
Kubernetes version: 1.20.6
Go version: 1.18.6
Dockerfile:
FROM php:7.4.27-apache-buster
RUN curl -sL https://deb.nodesource.com/setup_17.x | bash -
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs
RUN apt-get remove -y libstdc++-8-dev && \
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
apt-get install -y fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf && \
apt-get install -y libx11-xcb1 libxtst6 libnss3 libxss1 libasound2 libatk-bridge2.0-0 libgtk-3-0 && \
apt-get install -y xvfb
RUN apt-get install -y cron sendmail && \
apt-get install -y libzip-dev && \
apt-get install -y chromium && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /var/cache/*
RUN docker-php-ext-install pdo pdo_mysql mysqli zip
RUN apt-get update -y && apt-get install -y zlib1g-dev libpng-dev libjpeg-dev libfreetype6-dev imagemagick && \
docker-php-ext-configure gd --with-jpeg --with-freetype && \
docker-php-ext-install gd
COPY container/policy.xml /etc/ImageMagick-6/policy.xml
RUN apt-get update -y && \
apt-get install -y libmagickwand-dev && \
pecl install imagick && \
docker-php-ext-enable imagick
RUN groupadd -g 118 myapp
RUN useradd -d /myapp -G audio,video -g myapp -u 113 myapp
RUN chsh -s /bin/bash myapp
COPY --chown=myapp . .
COPY container/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod a+rx /usr/local/bin/entrypoint.sh
WORKDIR /app
EXPOSE 80
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

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 run cron and web application in same container?

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
...

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

Using the official php docker image and running memcached on start

I have a docker file that I am basing from the php:5.5.36-apache image, for creating image expressly for development. My Dockerfile installs memcached but I am having no luck getting memcached to start on boot. If I ssh into the container and start memcached manually, it starts just fine.
FROM php:5.5.36-apache
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
default-jdk
RUN apt-get install -y --no-install-recommends autoconf
RUN apt-get install -y --no-install-recommends python python-pip
RUN apt-get update && apt-get install -y libmemcached-dev \
apt-utils re2c g++ memcached \
zlib1g zlib1g-dbg zlib1g-dev zlibc mysql-client php5-mysql \
&& pecl install memcached \
&& docker-php-ext-enable memcached\
&& pecl install memcache \
&& docker-php-ext-enable memcache
RUN docker-php-ext-install pdo pdo_mysql
RUN apt-get install -y gettext
RUN pip install hgapi
RUN a2enmod headers \
&& a2enmod rewrite
COPY ./apache2.conf /etc/apache2/apache2.conf
RUN mkdir /var/www/content
EXPOSE 11211
RUN systemctl enable memcached.service
The base image is based on debian:jessie
This link worked for me for the same issue with php5, apache2 and memcached in a Dockerfile based on ubuntu:
https://github.com/moby/moby/issues/5137
Install supervisor
RUN apt-get install -y supervisor
and config that in Dockerfile:
RUN touch /etc/supervisor/conf.d/supervisord.conf && \
echo "[supervisord]" >> /etc/supervisor/conf.d/supervisord.conf && \
echo "nodaemon=true" >> /etc/supervisor/conf.d/supervisord.conf
RUN touch /etc/supervisor/conf.d/memcached.conf && \
echo "[program:memcache]" >> /etc/supervisor/conf.d/memcached.conf && \
echo "command=/usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -DFOREGROUND" >> /etc/supervisor/conf.d/memcached.conf && \
echo "autostart=true" >> /etc/supervisor/conf.d/memcached.conf && \
echo "autorestart=true" >> /etc/supervisor/conf.d/memcached.conf
RUN touch /etc/supervisor/conf.d/apache2.conf && \
echo "[program:apache2]" >> /etc/supervisor/conf.d/apache2.conf && \
echo 'command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"' >> /etc/supervisor/conf.d/apache2.conf && \
echo "autostart=true" >> /etc/supervisor/conf.d/apache2.conf && \
echo "autorestart=true" >> /etc/supervisor/conf.d/apache2.conf
CMD ["/usr/bin/supervisord"]
This link also explains how to run multiple services in a container:
https://docs.docker.com/engine/admin/multi-service_container/
php:5.5.36-apache has a bash script called apache2-foreground which uses exec to launch apache, that script is called with CMD ["apache2-foreground"] at the end of the Dockerfile. This is the one script that will be executed by Docker on start and the exec command passes execution off to the system.
My solution which my very well be inelegant and I would not suggest doing this with any kind of production server is to copy the apache2-foreground script and start memcached before apache is started. Since this is an image to use as a local development server this meets my needs.
The updated apache2-foreground:
#!/bin/bash
set -e
# Apache gets grumpy about PID files pre-existing
rm -f /var/run/apache2/apache2.pid
/etc/init.d/memcached start
exec apache2 -DFOREGROUND
Then I replaced:
RUN systemctl enable memcached.service
with:
COPY apache2-foreground /usr/local/bin/

Categories