اگر به تازگی با داکر آشنا شدهاید و قصد دارید پروژه PHP خودتون رو داکرایز کنید؛ این پست خیلی بدردتون میخوره.
احتمالا میدونید که وقتی از image خام PHP استفاده میکنید خیلی از ماژولها یا وجود ندارند یا فعال نیستند. پس در راهاندازی خیلی از پروژهها به مشکل خواهید خورد.
توی این پست، میخواهیم با ایجاد یک Dockerfile در شاخه روت پروژه، پیکر بندی یک PHP Image را انجام دهیم که بتواند بسیار از پروژههای PHP را بدون مشکل اجرا کند و در نهایت با استفاده از docker-compose از آن استفاده خواهیم کرد.
شروع سریع
خب، میخواهیم کار را به سرعت و بدون توضیحات اضافه انجام دهیم.
پیکربندی Dockerfile:
۱- در شاخه اصلی پروژه یک فایل جدید ایجاد کنید با نام Dockerfile و محتویات زیر را در آن Paste کنید:
FROM php:7.4-apache
# persistent dependencies
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
# Ghostscript is required for rendering PDF previews
ghostscript \
; \
rm -rf /var/lib/apt/lists/*
# install the PHP extensions we need
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libfreetype6-dev \
libicu-dev \
libjpeg-dev \
libmagickwand-dev \
libpng-dev \
libwebp-dev \
libzip-dev \
; \
\
docker-php-ext-configure gd \
--with-freetype \
--with-jpeg \
--with-webp \
; \
docker-php-ext-install -j "$(nproc)" \
bcmath \
exif \
gd \
intl \
mysqli \
pdo_mysql \
zip \
; \
# https://pecl.php.net/package/imagick
pecl install imagick-3.6.0; \
docker-php-ext-enable imagick; \
rm -r /tmp/pear; \
\
# some misbehaving extensions end up outputting to stdout
out="$(php -r 'exit(0);')"; \
[ -z "$out" ]; \
err="$(php -r 'exit(0);' 3>&1 1>&2 2>&3)"; \
[ -z "$err" ]; \
\
extDir="$(php -r 'echo ini_get("extension_dir");')"; \
[ -d "$extDir" ]; \
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$extDir"/*.so \
| awk '/=>/ { print $3 }' \
| sort -u \
| xargs -r dpkg-query -S \
| cut -d: -f1 \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*; \
\
! { ldd "$extDir"/*.so | grep 'not found'; }; \
# check for output like "PHP Warning: PHP Startup: Unable to load dynamic library 'foo' (tried: ...)
err="$(php --version 3>&1 1>&2 2>&3)"; \
[ -z "$err" ]
# set recommended PHP.ini settings
RUN set -eux; \
docker-php-ext-enable opcache; \
{ \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
RUN { \
# https://www.php.net/manual/en/errorfunc.constants.php
echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR'; \
echo 'display_errors = Off'; \
echo 'display_startup_errors = Off'; \
echo 'log_errors = On'; \
echo 'error_log = /dev/stderr'; \
echo 'log_errors_max_len = 1024'; \
echo 'ignore_repeated_errors = On'; \
echo 'ignore_repeated_source = Off'; \
echo 'html_errors = Off'; \
echo 'max_input_vars = 3000'; \
echo 'post_max_size = 1024M'; \
echo 'upload_max_filesize = 1024M'; \
echo 'max_execution_time = 300'; \
echo 'memory_limit = 1024M'; \
} > /usr/local/etc/php/conf.d/error-logging.ini
RUN set -eux; \
a2enmod rewrite expires; \
\
# https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html
a2enmod remoteip; \
{ \
echo 'RemoteIPHeader X-Forwarded-For'; \
# these IP ranges are reserved for "private" use and should thus *usually* be safe inside Docker
echo 'RemoteIPTrustedProxy 10.0.0.0/8'; \
echo 'RemoteIPTrustedProxy 172.16.0.0/12'; \
echo 'RemoteIPTrustedProxy 192.168.0.0/16'; \
echo 'RemoteIPTrustedProxy 169.254.0.0/16'; \
echo 'RemoteIPTrustedProxy 127.0.0.0/8'; \
} > /etc/apache2/conf-available/remoteip.conf; \
a2enconf remoteip; \
# https://github.com/docker-library/wordpress/issues/383#issuecomment-507886512
# (replace all instances of "%h" with "%a" in LogFormat)
find /etc/apache2 -type f -name '*.conf' -exec sed -ri 's/([[:space:]]*LogFormat[[:space:]]+"[^"]*)%h([^"]*")/\1%a\2/g' '{}' +
# Install and enable IonCube loader
RUN PHP_VERSION=$(php -v | head -n1 | cut -d' ' -f2 | cut -d. -f1-2) \
&& mkdir -p /tmp/ioncube \
&& cd /tmp/ioncube \
&& curl -Os https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_$(uname -m).tar.gz \
&& tar xzf ioncube_loaders_lin_$(uname -m).tar.gz \
&& cp ioncube/ioncube_loader_lin_${PHP_VERSION}.so "$(php -i | grep '^extension_dir =' | cut -d' ' -f3)/ioncube_loader.so" \
&& docker-php-ext-enable ioncube_loader \
&& rm -rf /tmp/ioncube
######## Other configs ########
VOLUME /var/www/html
CMD ["apache2-foreground"]
اگر در پروژه خود نیاز به فعال سازی Memcached داشته باشید می توانید تکه کد زیر را نیز به پایان فایل اضافه پس از قسمت Other configs اضافه کنید:
# Install Memcached
RUN set -eux; \
apt-get update; \
apt-get install -y \
libmemcached-dev \
zlib1g-dev \
&& pecl install memcached \
&& docker-php-ext-enable memcached
همچنین اگر میخواهید Ioncube را روی پروژه خود فعال کنید میتوانید کد زیر را به انتهای فایل پس از Other configs اضافه کنید:
# Install and enable IonCube loader
RUN PHP_VERSION=$(php -v | head -n1 | cut -d' ' -f2 | cut -d. -f1-2) \
&& mkdir -p /tmp/ioncube \
&& cd /tmp/ioncube \
&& curl -Os https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_$(uname -m).tar.gz \
&& tar xzf ioncube_loaders_lin_$(uname -m).tar.gz \
&& cp ioncube/ioncube_loader_lin_${PHP_VERSION}.so "$(php -i | grep '^extension_dir =' | cut -d' ' -f3)/ioncube_loader.so" \
&& docker-php-ext-enable ioncube_loader \
&& rm -rf /tmp/ioncube
پیکربندی Docker Compose:
در شاخه اصلی پروژه یک فایل جدید ایجاد کنید و نام آن را docker-compose.yml ایجاد کنید و محتویات زیر را داخل آن قراردهید:
version: '3.9'
services:
php:
container_name: yoursite.app
build:
context: .
dockerfile: Dockerfile
image: myphp:7.4-apache
restart: always
volumes:
- ./:/var/www/html/
db:
image: mariadb
container_name: yoursite.db
restart: always
environment:
MYSQL_DATABASE: yoursite.rm
MYSQL_ROOT_PASSWORD: root
volumes:
- ../data/yoursite.rm/mysql:/var/lib/mysql
ports:
- 3314:3306
networks:
default:
name: mynet
بر اساس پیکربندی فوق، دو سرویس PHP و Mariadb فعال میشوند که محتویات شاخه اصلی پروژه به شاخه /var/www/html مونت میشوند و دادههای ایمیج Mariadb در آدرس ../data/yoursite.rm/mysql ذخیره میشود.
همچنین یک شبکه جدید به نام mynet ایجاد میشود که سرویسهای فوق در آن شبکه قرار میگیرند.
اجرای پروژه
حال برای اجرای پروژه میتوانید دستور زیر را در کامند لاین اجرا نمایید:
docker compose up -d
احتمال دارد بر اساس نحوه نصب docker compose، دستور اجرای آن متفاوت باشد، اگر دستور بالا اجرا نشد، دستور زیر را اجرا نمایید:
docker-compose up -d
برای حذف پروژه داکر نیز میتوانید آن را با دستور زیر Down کنید:
docker compose down