Docker with built LNMP

Programmers often say: in my machine is normal, is certainly a problem with your machine. Therefore, Docker was born, it put everything needed for applications are packaged so that it is easy to deploy.

Docker's main purpose, there are three main categories:

  1. One-off environment. For example, local people's software testing, continuous integration when providing unit test and build environment.
  2. Provide flexible cloud services. Because Docker can open with the container closed, it is suitable for dynamic expansion and volume reduction.
  3. The formation of micro-services architecture. By a plurality of containers, the machine can run a plurality of services, the machine can be simulated in the micro-service architecture.

Let's start to experience Docker, operating system win10, Docker installation please refer to the official documentation , here ignored.

Hello World

Official provides a programmer favorite hello world mirror, we start in order to Docker tour, feel the power of Docker it:

docker run hello-world

If you see the output Hello from Docker!, I congratulate you, Docker installation was successful.

image和container

Mirror and containers may be understood as object-oriented classes and objects inside.

The above example is a direct mirror to get the official run, we can also be processed on the basis of official mirror, to build a new image, of course, can not be built on any mirror.

All content (code, software, environment, etc.) can be constructed by Dockerfile image configuration, you can run through a specific example of image container.

View mirror list:docker image ls

View the container list:docker container ls

To see a complete list, in lsthe back to add -aoptions like:docker container ls -a

Installing Linux

The following add difficulty, installing Linux, a small alpine volume, many open-source image is based on it (such as Nginx), it is suitable for experience:

docker run -it --rm alpine

Found run back a few more options, -itin fact, is the -i -tacronym, meaning that is interactive terminal, interactive terminal, without which we are not into the interactive terminal container.

Plus --rm, said they would automatically deleted container after container quit, we are here to experience, do not want to take up after running out of disk space, plus a delete option, note that this is not mirrored delete, delete a container.

Now we come to the end of the alpine system, enter the command to view system version to try:

cat /etc/os-release

Experience is completed, this time as long as the input exitPress Enter to exit the container.

If you want to run when the container is directly output system version, so to play:

docker run --rm alpine cat /etc/os-release

In order to keep up directly behind the image name you want to run, the output system version information after container is automatically closed and deleted.

Run PHP

Well, now the Linux system installed, intuition told me that, if run PHP, we directly into the container just inside the alpine installed just fine, then I am sorry, your posture is wrong. To not explain, take a look at the correct posture:

Our first experience in CLI mode PHP, before that, we can look at the official php-cli: 7.2 mirroring Dockerfile is how definitions:

FROM debian:stretch-slim
...此处省略若干行...

FROM specify which image-based, may not be based on any image: FROM scratchsuch as the official alpine Dockerfile :

FROM scratch
ADD alpine-minirootfs-3.10.0-x86_64.tar.gz /
CMD ["/bin/sh"]

Thus, PHP image is built on this foundation mirrored on debian, so we do not like PHP installed in a virtual machine the same as above, with iso must first install a Linux operating system.

Project location in D: \ www \ php-cli -demo, after a good build folder, create a project following index.phpdocuments:

<?php
echo phpversion();

Then create a new Dockerfilefile:

FROM php:7.2-cli
WORKDIR /var/www/php-cli-demo
COPY . .
CMD ["php", "index.php"]

WORKDIR working directory is specified container, we need to copy the current project code to the container where the operating system's directory, so we use COPY, the first point means the current directory, and the second point means that the container the current directory, meaning to my win10 system D: current directory \ www \ All files php-cli-demo this folder copied to all the container Debian system (has passed the working directory as / var / www / php-cli-demo) below.

CMD is the command after the container up and running to be performed, and where we want to directly run the php file.

In the current folder, press and hold the Shiftkey, then press the right mouse button, right-click menu appears, which occur when one of the "open Powershell window (s) in here," At this time we only need to press sto get into the command line and positioned directly to the current folder.

Then we establish the mirror just Dockerfile according to the configuration file:

docker build -t php-cli-demo .

t is the tag, tagging means.

Finally that point, specifying which directory is to be packaged, docker build command after learning this path, all content will be packaged under the path, and then uploaded to the Docker engine. After such Docker context engine receives the packet, it will expand to obtain all necessary papers to build a mirror, and then Docker engine when parsing the COPY command above you can see which files you want to COPY, so the first parameter of the COPY path is expanded in the packaging path, the path is relative.

Docker default will find Dockerfile, it may also be another file name, such as your Dockerfile called build.conf, by -fspecifying parameters:

docker build -t php-cli-demo -f build.conf .

Well, mirroring successfully constructed, and now to immediately run it:

docker run --rm php-cli-demo

We can see the correct output of the PHP version number: 7.2.19.

The time to build a project code packaged into a mirror image file, and that if I want to run another project it? To re-build it again? In fact, this image can be re-used, but when running the specified item position on the line:

docker run --rm -v ${PWD}:/var/www/php-cli-demo php-cli-demo

Volume is v, meaning data volume, $ {PWD} host is the current directory, the directory after the colon is the container, meaning that the current directory is mounted to the container / var / www / php-cli-demo directory.

But not recommended, because cache mirroring is done layer by layer, so repeated build will not take up too much space, but if the mirror made changes, it will affect another container, they still alone build better. Interested friends can test yourself to do something, then docker system dfoccupancy viewing space.

If, as in the base image, not related to any process above this, just need to project mapped to a container on the line, so you can directly play:

docker run --rm -v ${PWD}:/var/www/demo -w /var/www/demo php:7.2-cli php index.php

Now, step back and analyze just the question, why not recommend PHP installed directly in the alpine container inside.

When constructing the mirror, will be constructed layer by layer, the previous layer is the base layer, which can achieve multiplexing.

The process is the essence of container, but in a different process and direct the implementation of the host, the container processes running in their own namespace independent. Therefore, the container can have their own root file system, your network configuration, its own process space, or even their own user ID space. Process in the container is run in an isolated environment, use up, as though it were operating under a system independent of the host. This feature allows direct application of the packaged safer operation than in the host.

Mirroring the tiered storage container as well. Each container run-time, based on the mirror as a base layer, a storage layer to create the current container thereon.

Lifetime of the storage layer and the container as the container, the container die, the container also will die of the memory layer. Therefore, any container stored in the storage layer information will be deleted with the container lost.

So, you just install the alpine container inside PHP, if you do not accidentally delete a container, run again next time, PHP will lose. And this is a black box, people do not know what the inside of the container, it is best to build the mirror through Dockerfile, and then to run the container according to the mirror slightly.

Build LNMP

Well, after the above thoroughly understand we have to run a real PHP project it. We need to use PHP-FPM, Nginx, MySQL. The project structure is so arranged:

  • docker-php-demo
    • app
      • index.html
      • index.php
    • mysql
      • Dockerfile
    • nginx
      • conf.d
        • site.conf
    • php
      • Dockerfile

Nginx we first loaded up, try to run a static page. Official Mirror ran directly:

docker run --name nginx -d --rm nginx:1.16

Open your browser and enter localhost, you can see the Welcome to nginx! Static pages. This is the default page Nginx, we need to add a specially configured for this project. Nginx into the vessel, view the configuration file path:

docker exec -it nginx bash
nginx -V

See the configuration file path:

--conf-path=/etc/nginx/nginx.conf

View profile:

cat /etc/nginx/nginx.conf

You can see the default configuration also to load other configuration files:

include /etc/nginx/conf.d/*.conf;

So we just need to configure the project by -vmapping to the next conf.d directory container on it. The current container Nginx stopped:

docker stop nginx

Then write site.conf:

server {
    listen 80;
    server_name local.docker-php-demo.com;
    root /var/www/docker-php-demo;
}

In the app directory into the index.html:

Hello Docker

Nginx itself because we do not process, so do not Dockerfile, the direct use of official mirror like, and then were the project site and Nginx configuration maps in the past, the implementation of the project root directory:

docker run --name dpd-nginx -d -v ${PWD}/app:/var/www/docker-php-demo -v ${PWD}/nginx/conf.d:/etc/nginx/conf.d -p 80:80 nginx:1.16

Finally, the present machine configuration hosts done on it, Win + R open the Run window, enter Drivers, open etc / hosts file on a line configuration domain:

127.0.0.1 local.docker-php-demo.com

Browser opens local.docker-php-demo.com, here, we've had to make Nginx run a static page configuration. Our project is PHP, the fpm loaded up, then let even on the line Nginx, written in php directory Dockerfile:

FROM php:7.2-fpm
RUN cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini \
    && docker-php-ext-install pdo_mysql

Above we used the method of operation of the extension is installed mirroring provides quick installation pdo_mysql to expand.

In the app directory into index.php:

<?php
phpinfo();

Construction of the Operation:

cd php
docker build -t dpd-php .
cd ..
docker run --name dpd-php -d -v ${PWD}/app:/var/www/docker-php-demo -p 9000:9000 dpd-php

The nginx php and connected via LAN:

docker network create --driver bridge dpd # 新建一个桥接网卡,名字叫dpd
docker network connect dpd dpd-php
docker network connect dpd dpd-nginx
docker network ls # 列出docker当前有哪些网卡
docker network inspect dpd # 查看dpd网卡详情

Nginx configuration modifications, forwarded to the PHP script fpm, fpm address by name dpd-php container can be identified:

server {
    listen 80;
    server_name local.docker-php-demo.com;
    root /var/www/docker-php-demo;
    
    location ~ \.php$ {
        fastcgi_pass dpd-php:9000;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Let Nginx to reload the configuration file:

docker exec -it dpd-nginx nginx -s reload

Here, we'll take Nginx and php-fpm up. Here let us build Mysql, New test.sql in the mysql directory, storage and basic data table structure:

CREATE TABLE `user` (
    `id` int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `name` varchar(20) NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';

INSERT INTO `user` VALUES (null, 'a1');

Dockerfile:

FROM mysql:5.7
ENV MYSQL_ROOT_PASSWORD=123 MYSQL_DATABASE=test
COPY ./test.sql /var/data/test.sql

Construction and launch container, directly where --networkthe parameter is added to the container dpd network:

cd mysql
docker build -t dpd-mysql .
docker run --name dpd-mysql -d --network dpd -p 3306:3306 dpd-mysql

Into the test container and the table data import into:

docker exec -it dpd-mysql bash
mysql -uroot -p
mysql> use test;
mysql> source /var/data/test.sql

Modify index.php:

<?php
$dsn = 'mysql:dbname=test;host=dpd-mysql';
$user = 'root';
$password = '123';

try {
    $dbh = new PDO($dsn, $user, $password);
    $sql = 'SELECT * FROM user WHERE id=?';
    $sth = $dbh->prepare($sql);
    $sth->execute(array(1));
    $result = $sth->fetch(PDO::FETCH_ASSOC);
    var_dump($result);
} catch (PDOException $e) {
    echo 'Error: ' . $e->getMessage();
}

Browser input http://local.docker-php-demo.com/index.php , PHP successfully obtain data from the database to the user:

array(2) { ["id"]=> string(1) "1" ["name"]=> string(2) "a1" }

Reference material

Guess you like

Origin www.cnblogs.com/justlikeheaven/p/11110671.html