📜 ⬆️ ⬇️

Running PHP applications on Docker containers (PHP-FPM, Nginx, PostgreSQL)

Over the past year, software to automate deployment in a virtualization environment at the operating system level is gaining momentum. This article will serve newcomers in this area as an example of how to package your application in Docker containers.

In the classical form, PHP application consists of the following components:

  1. Web server
  2. DBMS
  3. Php application

In our example, we will use Nginx, PostgreSQL and PHP-FPM.

1. Installing Docker


To get started, we need a Docker. You can download it on the official Docker website.
')

2. Creating images


Docker creates images based on DockerFile files, which describes the functionality. We will create 3 images for our components.

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

In this DockerFile, we create a user www-data with a group of 82 and install Nginx. The last COPY line assumes that your application configuration is in the config / website.conf folder. It will be copied to /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 

In this image, we will build on the postgres image: 9.5.2 and execute the command to determine the locale and language.

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/;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"] 

This image will serve us in the main way for our application. First we install everything you need for PHP and PHP-FPM. Next, we copy the current application folder to / usr / src / app, where our application will be located. At the very end, we run PHP-FPM.

Creating images based on DockerFile


And so, we have DockerFiles, on the basis of which we have to create images. Images are created very simply. It is enough to execute the following commands:

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

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

 docker build -t myusername/myproject:latest . 

In the future, I advise you to add - no-cache to these commands in order not to compile the components each time.

We create images, attach them to our account on Docker Hub. Now, we need to send our images to the repository in the Docker Hub. We execute the following commands:

 docker push myusername/myproject-nginx:latest 

 docker push myusername/myproject-postgresql:latest 

 docker push myusername/myproject:latest 

Running images on the server


We are almost there! It remains for us to download images from the repository and run them. Load them with the following commands:

 docker pull myusername/myproject-nginx:latest 

 docker pull myusername/myproject-postgresql 

 docker pull myusername/myproject 

It remains to run them. This is done just as easily.

 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 

Voila! Our application is running on Docker containers. And yet, to all novice readers, I would definitely get acquainted with the Docker documentation.

I wish you all success in mastering new technologies!

Source: https://habr.com/ru/post/316802/


All Articles