Запуск програми на PHP Docker контейнерах (PHP-FPM, Nginx, 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 \
&& апк --no-cache add --update openssl \
&& openssl dhparam -out /etc/pki/nginx/dhparams.pem 4096 \
&& sed -i -e 's/user\s*nginx;/user www-data www-data;/g' /etc/nginx/nginx.conf \
&& sed -i -e 's/worker_processes\s*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 \
&& апк --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/;daemonize\s*=\s*yes/daemonize = no/g". /etc/php7/php-fpm.conf \
&& sed -i -e "s/listen\s*=\s*127.0.0.1:9000/listen = [::]:9000/g". /etc/php7/php-fpm.d/www.conf \
&& sed -i -e "s/;chdir\s*=\s*\/var\/www/chdir = \usr\/src\/app/g". /etc/php7/php-fpm.d/www.conf \
&& sed -i -e "s/user\s*=\s*nobody/user = www-data/g". /etc/php7/php-fpm.d/www.conf \
&& sed -i -e "s/group\s*=\s*nobody/group = www-data/g". /etc/php7/php-fpm.d/www.conf \
&& sed -i -e "s/;clear_env\s*=\s*no/clear_env = no/g". /etc/php7/php-fpm.d/www.conf \
&& sed -i -e "s/;catch_workers_output\s*=\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.

Всім бажаю успіхів в освоєнні нових технологій!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.