Запуск PHP приложения на Docker контейнерах (PHP-FPM, Nginx, PostgreSQL)

в 14:49, , рубрики: devops, docker, dockerfile, nginx, php, php-fpm, postgresql, Серверное администрирование

За последний год программное обеспечение для автоматизации развертывания в среде виртуализации на уровне операционной системы набирает большие обороты. Эта статья послужит новичкам в этой сфере примером, как нужно упаковывать свое приложение в Docker контейнеры.

В классическом виде, PHP приложение представляет из себя следующие составляющие:

  1. Веб-сервер
  2. СУБД
  3. PHP приложение

В нашем примере мы будем использовать Nginx, PostgreSQL и PHP-FPM.

1. Установка Docker

Для начала работы, нам потребуется Docker. Скачать его можно на официальном сайте Docker.

2. Создание образов

Docker создает образы на основе DockerFile файлов, в котором описывается функционал. Мы создадим 3 образа для наших составляющих.

DockerFileNginx

FROM nginx:mainline-alpine

RUN set -ex 
 && addgroup -g 82 -S www-data 
 && adduser -u 82 -D -S -G www-data www-data 
    && mkdir -p /etc/pki/nginx/ 
    && apk update 
    && apk --no-cache add --update openssl 
    && openssl dhparam -out /etc/pki/nginx/dhparams.pem 4096 
    && sed -i -e 's/users*nginx;/user  www-data www-data;/g' /etc/nginx/nginx.conf 
    && sed -i -e 's/worker_processess*1;/worker_processes  auto;/g' /etc/nginx/nginx.conf 
    && rm -rf /var/cache/apk/*

COPY config/website.conf /etc/nginx/conf.d/website.conf

В данном DockerFile мы создаем пользователя www-data с группой 82 и устанавливаем Nginx. Последняя строка COPY предполагает, что у вас конфигурация приложения лежит в папке config/website.conf. Она скопируется в /etc/nginx/conf.d/website.conf.

DockerFilePostgresql

FROM postgres:9.5.2

RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8

В этом образе, мы будем отталкиваться от образа postgres:9.5.2 и выполним команду для определения локали и языка.

DockerFile

FROM alpine:edge

# Timezone
ENV TIMEZONE Europe/Moscow
ENV PHP_MEMORY_LIMIT 1024M
ENV MAX_UPLOAD 128M
ENV PHP_MAX_FILE_UPLOAD 128
ENV PHP_MAX_POST 128M</blockquote>

RUN set -ex 
	&& addgroup -g 82 -S www-data 
	&& adduser -u 82 -D -S -G www-data www-data 
	&& echo "@testing http://dl-4.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories 
    && apk update 
    && apk upgrade 
    && apk add --update tzdata 
	&& cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime 
	&& echo "${TIMEZONE}" > /etc/timezone 
    && apk --update add --no-cache php7-fpm@testing php7-mcrypt@testing php7-openssl@testing php7-json@testing php7-mysqli@testing php7-session@testing php7-gd@testing php7-xmlreader@testing php7-xmlrpc@testing 
    php7-zip@testing php7-iconv@testing php7-curl@testing php7-zlib@testing php7@testing php7-ctype@testing php7-pgsql@testing php7-pdo_pgsql@testing bash rsync 
    && sed -i -e "s/;daemonizes*=s*yes/daemonize = no/g" /etc/php7/php-fpm.conf 
    && sed -i -e "s/listens*=s*127.0.0.1:9000/listen = [::]:9000/g" /etc/php7/php-fpm.d/www.conf 
    && sed -i -e "s/;chdirs*=s*/var/www/chdir = /usr/src/app/g" /etc/php7/php-fpm.d/www.conf 
    && sed -i -e "s/users*=s*nobody/user = www-data/g" /etc/php7/php-fpm.d/www.conf 
    && sed -i -e "s/groups*=s*nobody/group = www-data/g" /etc/php7/php-fpm.d/www.conf 
    && sed -i -e "s/;clear_envs*=s*no/clear_env = no/g" /etc/php7/php-fpm.d/www.conf 
    && sed -i -e "s/;catch_workers_outputs*=s*yes/catch_workers_output = yes/g" /etc/php7/php-fpm.d/www.conf 
    && sed -i "s|;date.timezone =.*|date.timezone = ${TIMEZONE}|" /etc/php7/php.ini 
    && sed -i "s|memory_limit =.*|memory_limit = ${PHP_MEMORY_LIMIT}|" /etc/php7/php.ini 
    && sed -i "s|upload_max_filesize =.*|upload_max_filesize = ${MAX_UPLOAD}|" /etc/php7/php.ini 
    && sed -i "s|max_file_uploads =.*|max_file_uploads = ${PHP_MAX_FILE_UPLOAD}|" /etc/php7/php.ini 
    && sed -i "s|post_max_size =.*|post_max_size = ${PHP_MAX_POST}|" /etc/php7/php.ini 
    && sed -i "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/" /etc/php7/php.ini 
    && apk del tzdata 
    && rm -rf /var/cache/apk/*

COPY . /usr/src/app

RUN chown -R www-data:www-data /usr/src/app

EXPOSE 9000

CMD ["php-fpm7"]

Этот образ послужит нам основным образом для нашего приложения. Сначала мы устанавливаем все необходимое для PHP и PHP-FPM. Далее, мы копируем текущую папку приложения в /usr/src/app, где будет распологаться наше приложение. В самом конце мы запускаем PHP-FPM.

Создание образов на основе DockerFile'ов

И так, у нас есть есть DockerFile'ы, на основе которых мы должны создать образы. Образы создаются очень просто. Достаточно выполнить следующие команды:

docker build -t myusername/myproject-nginx:latest -f DockerfileNginx .

docker build -t myusername/myproject-postgresql:latest -f DockerfilePostgreSql .

docker build -t myusername/myproject:latest .

В дальнейшем советую добавить к этим командам --no-cache, чтобы каждый раз не компилировать составляющие.

Мы создаем образы, прикрепляем их к нашему аккаунту на Docker Hub. Теперь, нам нужно отправить наши образы на репозиторий в Docker Hub. Выполняем следующие команды:

docker push myusername/myproject-nginx:latest

docker push myusername/myproject-postgresql:latest

docker push myusername/myproject:latest

Запуск образов на сервере

Мы почти у цели! Нам осталось загрузить образы из репозитория и запустить их. Загружаем их с помощью следующих команд:

docker pull myusername/myproject-nginx:latest

docker pull myusername/myproject-postgresql

docker pull myusername/myproject

Осталось их запустить. Делается это так же просто.

docker run —name myproject-nginx -d -p 80:80 myusername/myproject-nginx:latest

docker run —name myproject-postgresql9.5.2 -d -p 5432:5432 myusername/myproject-postgresql9.5.2:latest

docker run —name myproject -d -p 9000:9000 myusername/myproject:latest

Вуаля! Наше приложение запущено на Docker контейнерах. И тем не менее, всем читателям-новичкам я бы обязательно ознакомиться с документацией Docker.

Всем желаю успехов в освоении новых технологий!

Автор: EmotionTigran

Источник

Поделиться

* - обязательные к заполнению поля