πŸ“œ ⬆️ ⬇️

Another article about Docker for a beginner [nginx + php-fpm + postgresql + mongodb]

image

Good day to all. Inspired by a whole set of articles on the topic of raising the environment at Docker, I decided to share my experience on this issue.

At once I will make a reservation, this article is so to say β€œfrom a beginner to a beginner,” so I will try to tell in detail about all the difficulties and issues that I had in the process of setting up the environment in Docker.

Welcome under the cut!

So, everything that I will describe below, I will do on a laptop of a well-known β€œfruit company”, but since I previously did the same on VDS running Centos 7, then I will make small lyrical digressions with the description, as I did on VDS .
')
We start naturally in the registration at docker hub , which will act as a version control system, but only for our containers. Docker hub with free use allows you to have only 1 private repository, so we will mark each individual image with the corresponding tags - nginx, php7-fpm. I will not describe the creation of a repository, I think no one with this problem will arise.

Now we can install docker itself on our workstation - in my case this description is here .

When installing Docker on a Mac, we immediately install the docker toolbox , which has the docker-compose tool we need. We will use it to combine our containers about the general environment.

Installing docker-compose on Centos 7
Unfortunately, on VDS I had to install it separately through pip .
yum -y install python-pip pip install docker-compose 

Further we log in in our Docker:

 docker login 

Now we have access to our private repositories (although it’s still empty there), the truth is now empty, but we will fix this soon :)

For my project, I made the following file structure:

 β”œβ”€β”€ contaners #      docker β”‚  β”œβ”€β”€ fpm β”‚  β”‚  β”œβ”€β”€ Dockerfile β”‚  β”‚  └── conf β”‚  β”‚  └── fpm.conf #   fpm,    :) β”‚  └── nginx β”‚  β”œβ”€β”€ Dockerfile β”‚  └── conf β”‚  └── nginx.conf β”œβ”€β”€ database #      β”œβ”€β”€ docker-compose.yml β”œβ”€β”€ logs #     └── php-code #   php  β”œβ”€β”€ html └── index.php 

Why do you need php-code / html
In the absence of the html directory, the nginx container image does not start, somewhere I found that the problem is solved by specifying WORKDIR in the Dockerfile, but this directory is still needed.

For the project I will use custom images for nginx and fpm, so I brought them into separate directories. Custom images are described using Dockerfile . Here are mine:

./contaners/fpm/Dockerfile
 FROM php:fpm MAINTAINER nickname <my-email@domain> RUN apt-get update && apt-get install -y \ libmcrypt-dev \ && apt-get install -y libpq-dev \ && docker-php-ext-install -j$(nproc) mcrypt \ && pecl install mongodb && docker-php-ext-enable mongodb RUN docker-php-ext-install mbstring RUN docker-php-ext-install exif RUN docker-php-ext-install opcache RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-install pgsql pdo_pgsql COPY conf/ /usr/local/etc/php-fpm.d/ CMD ["php-fpm"] 


./contaners/nginx/Dockerfile
 FROM nginx:latest MAINTAINER nickname <my-email@domain> COPY ./conf /etc/nginx/conf.d/ 


./contaners/nginx/conf/nginx.conf
 server { listen 80; index index.php index.html; server_name localhost; error_log /etc/logs/nginx/nginx_error.log; access_log /etc/logs/nginx/nginx_access.log; root /var/www; location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } 

The script from the official PHP image from Docker Hub makes it easy to install the necessary extensions:
 docker-php-ext-install 

or

 docker-php-ext-enable #  ,     (    pecl) 

All the preparatory work has been done; now we need to describe how our containers will interact. As I already wrote, we will do this through docker-compose and the interaction rules should be described in the docker-compose.yml file . Here is my:

./docker-compose.yml
 nginx: dockerfile: ./Dockerfile #         build build: ./contaners/nginx ports: - 80:80 volumes: - ./logs:/etc/logs/nginx volumes_from: - fpm:rw environment: - NGINX_HOST=localhost - NGINX_PORT=80 command: nginx -g "daemon off;" #     -,    ) links: - fpm fpm: dockerfile: ./Dockerfile build: ./contaners/fpm volumes: - ./php-code:/var/www:rw 

Note on specifying relative paths
If we specify relative paths to files and directories, they must necessarily begin with a dot (as an indication of the current directory), that is, for example, such a path contaners / nginx / Dockerfile will be interpreted incorrectly .

Now you can run our containers:

 docker-compose up -d 

argument -d
the -d argument is specified in order to decouple the work of the containers from the console, i.e. run in daemon mode

Everything, our containers work and link, but I did something wrong, namely, we always refer to the Dockerfile to launch the container, this is not very convenient. Let's do this:

 docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2d6263b52380 test_nginx "nginx -g 'daemon off" 8 minutes ago Up 8 minutes 443/tcp, 0.0.0.0:8080->80/tcp test_nginx_1 04370a9e1c73 test_fpm "php-fpm" 8 minutes ago Up 8 minutes 9000/tcp test_fpm_1 docker tag 2d6263b52380 my-login/repo:nginx docker tag 2d6263b52380 my-login/repo:fpm docker push my-login/repo:nginx docker push my-login/repo:php7-fpm 

Now our containers are managed through docker hub and we no longer need Dockerfile.
Fix docker-compose.yml:

./docker-compose.yml
 nginx: image: my-login/repo:nginx ports: - 80:80 volumes: - ./logs:/etc/logs/nginx volumes_from: - fpm:rw environment: - NGINX_HOST=localhost - NGINX_PORT=80 command: nginx -g "daemon off;" #     -,    ) links: - fpm fpm: image: my-login/repo:php7-fpm volumes: - ./php-code:/var/www:rw 

But now I realized that I forgot to add the pcntl extension for php. But it is easy to fix.
First, let's connect to the required container:

 docker exec -it 04370a9e1c73 bash 

And add the necessary extension:

 docker-php-ext-install pcntl 

Well, they added it to the container, but we wanted to use the docker hub as a VCS - it means we need to commit the changes:

 docker commit -m "added pcntl ext" 04370a9e1c73 my-login/repo:php7-fpm 

and push to the repository:

 docker push my-login/repo:php7-fpm 

Add more database containers (postgresql and mongodb):

./docker-compose.yml
 nginx: image: my-login/repo:nginx ports: - 80:80 volumes: - ./logs:/etc/logs/nginx volumes_from: - fpm:rw environment: - NGINX_HOST=localhost - NGINX_PORT=80 command: nginx -g "daemon off;" links: - fpm fpm: image: my-login/repo:php7-fpm volumes: - ./php-code:/var/www:rw links: - mongo - postgres mongo: image: mongo ports: - 27017:27017 #      volumes: - ./database/mongo:/data/db postgres: image: postgres:latest ports: - 5432:5432 #      volumes: - ./database/postgres:/data/postgres environment: POSTGRES_PASSWORD: <myPassword> POSTGRES_USER: postgres PGDATA : /data/postgres 

And now we execute:

 docker-compose up -d 

Docker will add us new containers to those already running. But I opened ports for external access, but we specified a password only for PostgreSql, you need to do the same for mongodb - how to do it (and not only) is described in detail here .

For the MongoDB
 docker exec -it some-mongo mongo admin connecting to: admin > db.createUser({ user: 'jsmith', pwd: 'some-initial-password', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] }); Successfully added user: { "user" : "jsmith", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } 


Php databases are now accessible by postgres and mongo hosts, respectively. to connect, for example, to mongodb, we need to write the following:

 $manager = new MongoDB\Driver\Manager("mongodb://mongo:27017"); 

That's all, thank you for your attention. Please note that everything described is solely my own experience and does not claim to be the ideal approach to setting up an environment through docker.

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


All Articles