Writing in the front

A few days ago I wrote a blog about docker building nginx+ PHP +mysql development environment. At that time, it was mainly based on a blog to build records.

However, there are some problems with this construction, the specific reasons I haven’t found out. Of course that article still has some reference value.

So I built a new one, stepped on a lot of pits, fortunately, all solved.

This article is to record my building process, the pit I stepped on, and some of the problems combined with thinkPHP project solutions.

I won’t mention the benefits of Docker, just like Git, you know who uses it.

The article referred to in this article will be placed at the end of the reference. Some references will be linked to in this article.


Set up

Environment introduction

Operating system Ubuntu 16.04 LTS Docker version Docker Version 17.05.0- CE


Project structure Reference

The reference tree chart of the project structure is given here first. Some of the content is generated in the construction process, so it is only for reference and combined with the content of the following article.

sail@codeBetter:~$tree www-l 1 WWW ├─ default. Conf ├─ Dockerfile ├─ HTML ├─ PHPCopy the code

sail@codeBetter:~$tree www-l 2 WWW ├─ default. Conf ├─ Dockerfile ├─ HTML │ ├─ coalball │ ├─ index Index.php │ └ ─ ─ mysql, PHP ├ ─ ─ mysql │ ├ ─ ─ auto. The CNF │ ├ ─ ─ ca - key. Pem │ ├ ─ ─ ca. Pem │ ├ ─ ─ the client - cert. Pem │ ├ ─ ─ Client.key.pem │ ├─ coalball │ ├─ coalball. SQL │ ├─ IBDatA1 │ ├─ IB_LogFile0 │ ├─ IB_LogFile1 │ ├── bass exercise-ibtmp1 │ ├── mysql │ ├─ performance_schema │ ├─ private_key.pem │ ├─ server-cert.pem │ ├── ├── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─ │ ├─ ├─ ├─ coalball │ ├─ ├─ mysql. PHP │ ├─ coalball │ ├─ ├─ coalball │ ├─ mysql. PHP │ ├─ coalball │ ├─ mysql. www.confCopy the code

MySQL

Pull MySQL image from Dockerhub:

$ docker pull mysqlCopy the code

Instance container, start the database

$ docker run -p 3306:3306 --name mysql -v ~/www/mysql/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d --privileged=true Mysql # # # command description: -p 3306-3306: the container port 3306 is mapped to the host port 3306 - v ~ / WWW/mysql / : / var/lib/mysql: -e MYSQL_ROOT_PASSWORD=123456: /var/lib/mysql/MYSQL_ROOT_PASSWORD=123456: --name -- Privileged =true -- Privileged =true -- Privileged =true -- Privileged =trueCopy the code


Nginx

Pull Nginx image from Dockerhub:

$ docker pull nginxCopy the code

Instance container, start Nginx

$docker run --name nginx -p 80:80 -d nginx -- docker run --name nginx -p 80:80 -d nginx Specifies the name of the container (if left blank, Docker will automatically assign a name) -p: exports the container port to the local server in the format of -p <local-port>:<container-port>. In this case, we map port 80 of the container to port 80 of the local server. Nginx: is the name of the nginx image downloaded from Dockerhub (if there is no local image available, Docker will automatically download one) -d: background boot.Copy the code

Browse in your browser: http://localhost to see the Nginx welcome screen.

Introduction to several commands

$docker ps -a # View the running container $docker ps # View the running container $docker stop nginx # Stop the running container $docker start nginx # Start a stopped container $ $docker rm nginx # Delete containerCopy the code

Mapping HTML paths

By default, the HTML path of the Docker nginx server is in the /usr/share/nginx/ HTML directory. Now you need to map this directory to the ~/ WWW/HTML directory of the local server. Add -v to the command as follows:

# # first remove containers before $docker rm nginx $docker run - name nginx -p 80:80 - d - v ~ / WWW/HTML: / usr/share/nginx/HTML nginxCopy the code

The format of the -v parameters is :< local-volumes>:

.

Create an index. HTML file under ~/ WWW/HTML

Such as hello world

Go to http://localhost in your browser and refresh to see the new content.

Configure Nginx

Much of the power of Nginx lies in configuration files. For advanced applications, customizing Nginx is very important. So, we need to copy the Nginx configuration file to the local server directory:

$ cd ~/www
$ docker cp nginx:/etc/nginx/conf.d/default.conf default.confCopy the code

Add a -v parameter to map the local configuration file to the container before restarting the container:

$ docker stop nginx
$ docker rm nginx
$ docker run --name nginx -p 80:80 -v ~/www/html:/usr/share/nginx/html -v ~/www/default.conf:/etc/nginx/conf.d/default.conf -d nginxCopy the code

If the configuration file is modified, restart the container to take effect:

$ docker restart nginxCopy the code

This allows you to modify the configuration file directly locally.


PHP-FPM

Pull phP-FPM image from Dockerhub:

$ docker pull php:fpmCopy the code

Instance container, start PHP: FPM

$ docker run --name php-fpm -p 9000:9000 -d php:fpmCopy the code

Copy configuration file to local:

$ cd ~/www
$ docker cp php-fpm:/usr/local/etc/php-fpm.d/www.conf www.conf
$ docker cp php-fpm:/usr/src/php/php.ini-production php.iniCopy the code

Php-fpm: /usr/src/php.ini -production; /usr/ SRC /php.ini-production; /usr/ SRC /php.ini-production;

You can view the php.ini path like this

$docker exec it PHP -fpm bash $CD /usr/src/&&ls Tar # tar -xvf php.tar # tar -xvf php.tar # tar -xvf php.tar # tar -xvf php.tar # tar -xvf php.tarCopy the code

Php.ini -production = /usr/ SRC /php-7.1.9/php.ini-production = /usr/ SRC /php-7.1.9/php.ini-production

$docker cp php-fpm: /usr/src/php.ini -production php.ini $docker cp php-fpm: /usr/src/php.ini -production php.ini PHP - FPM: / usr/SRC / - 7.1.9 / PHP. PHP ini - production PHP. IniCopy the code

Change the contents of php.ini on the local server and set cgi.fix_pathinfo=1 (delete the previous; Comment).


The previous series of operations on phP-fPM was mainly to get the configuration file, and did not mount the local directory into the container, so the next step is to delete the container and instantiate it again

$ docker stop php-fpm $ docker rm php-fpm $ docker run --name php-fpm -p 9000:9000 --link mysql:mysql -v ~/www/html:/var/www/html -v ~/www/www.conf:/usr/local/etc/php-fpm.d/www.conf -v ~/www/php.ini:/usr/local/etc/php/php.ini  -d php:fpmCopy the code

Configure Nginx

Modify the Nginx configuration file, which we copied from the container earlier, default.conf

server { listen 80; server_name _; root /usr/share/nginx/html; index index.php index.html index.htm; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { #root /usr/share/nginx/html; #index index.php index.html index.htm; try_files $uri $uri/ =404; } error_page 404 /404.html; location = /40x.html { root /user/share/nginx/html; } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php${# proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php${root /var/www/html/; fastcgi_pass php-fpm:9000; fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; }}Copy the code

There is one caveat about configuration files

location ~ \.php$ { root /var/www/html/; fastcgi_pass php-fpm:9000; fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } include fastcgi_params; Fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; In the front of theCopy the code

Delete the nginx container and create a new one

$ docker stop nginx
$ docker rm nginx
$ docker run --name nginx -p 80:80 --link php-fpm -v ~/www/html:/usr/share/nginx/html -v ~/www/default.conf:/etc/nginx/conf.d/default.conf -d nginxCopy the code

Create index.php under ~/ WWW/HTML

<? php phpinfo();Copy the code

Browser visit http://localhost


PHP +nginx+mysql

However, in practice, there are still problems, such as PHP needs to install a series of extensions, such as pdo_mysql, we can write a Dockerfile to customize the image

Write Dockerfile

Here we look again at the project structure shown earlier

WWW ├─ ├─ ├─ coalball │ ├─ index.html │ ├─ ├─ mysql.php │ ├─ mysql │ ├─ WWW ├─ Default ├─ coalball. SQL ├─ ph. ├─ www.confCopy the code

Dockerfile as follows

FROM PHP :5.6-fpm ADD www.conf /usr/local/etc/php-fpm.d/www.conf ADD php.ini /usr/src/php.ini RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng12-dev \ && docker-php-ext-install -j$(nproc) iconv mcrypt \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/  \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install pdo_mysql EXPOSE 9000Copy the code

Delete the previous phP-fPM container

$docker stop PHP -fpm $docker rm PHP -fpm $docker build -t php-fpm:v1 ./ $ docker run --name php-fpm -p 9000:9000 --link mysql:mysql -v ~/www/html:/var/www/html -v ~ ~ / WWW/WWW/www.conf:/usr/local/etc/php-fpm.d/www.conf - v/PHP ini: / usr/local/etc/PHP/PHP. PHP ini - d: FPMCopy the code

Of course, the specific needs of which extensions or according to their own needs to write Dockerfile.


Combining with the thinkphp

The previous content basically set up the development environment, here I only talk about running TP project encountered some potholes (including some container potholes), do some records and share

Because this part of the pit is more, maybe I don’t remember very clearly, just for reference, the end of the article will leave some reference links

How to install the locate command?

If downloading something in the container fails and you are prompted that there is no locate command

$ apt-get update
$ apt-get install mlocateCopy the code

However, executing locate to find some files at this point has some problems

Locate: can not stat () ` / var/lib/mlocate/mlocate db ‘: No to the file or directory

Update the database

$updatedb # Run this command several timesCopy the code

Undefined class constant ‘MYSQL_ATTR_INIT_COMMAND’

Modify the configuration file php.ini

Enable all of the following, if not in your configuration file (php.ini), add them yourself

extension=php_mysqli.dll extension=php_pdo.dll extension=php_pdo_mysql.dll extension=pdo.so extension=pdo_mysql.so # If the pdo_mysql extension fails to be installed, do docker-php-ext-install pdo_mysqlCopy the code

No such file or directory

If you visit the site and this error occurs, take a look at your PHPInfo page and see if

Pdo_mysql. default_socket Whether the socket has a Local Value and a Master Value

If not, go to mysql in the mysql container

$ docker exec -it mysql bash
$ mysql -u root -p
# enter your passwordCopy the code

Perform mysql > STATUS;

Record the value of the UNIX socket

Configure the following values as UNIX socket values in your php.ini file without adding them

Default_socket mysqli. Default_socket ## demonstrate mysqli. Default_socket = /var/run/mysqld/mysqld.sockCopy the code

If you still have questions, refer to this question on StackOverflow

### this can be skipped, personal record creating a symbolic link in: /var/mysql (create the directory if it does not exist) cd /var/mysql && sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock This fixed it for me. I'm not using MAMP though, so it was cd /var/mysql && sudo ln -s /tmp/mysql.sockCopy the code

SQLSTATE[HY000]: General error

SQLSTATE[HY000] [2002]

SQLSTATE[HY000] [2002] Connection refused

Finally, if the project has such problems, you need to modify the configuration of the data in the project configuration file

'DB_HOST'=>' XXX ',// data server address

If you are using a virtual host or container, ‘DB_HOST’ => ‘ ‘, this should be the host address of the database, not localhost or 127.0.0.1 for the local address

Perform docker inspect - format = '{{. NetworkSettings. IPAddress}}' $CONTAINER_ID can obtain containers IP but IP changes every time they start, know container IP doesn't make sense! But the IP of the container changes every time it is started, so knowing the IP of the container is meaningless! But the IP of the container changes every time it is started, so knowing the IP of the container is meaningless!Copy the code

This configuration is ok if your container is named mysql

'DB_HOST'=>'mysql',// data server addressCopy the code


Write in the last

The above is the general record of the setup.

Of course, you can write your own docker-comemage. yml to automate the whole construction process. You only need to click a few commands. I’m not going to write it here for time reasons.

Can also be published as a mirror, so that you can build the environment once, permanent use, next time reinstall the system, pull down.


Tar. Xz decompress: Linux and Windows tar. Xz decompress: Can not stat () ` / var/lib/mlocate/mlocate db ‘: No such file or directory SQLSTATE[HY000] [2002] No such file or directory Directory [duplicate] How does the host get the IP address of the Docker container? How do I obtain the IP address of a Docker container


To discuss this article, please email [email protected] without authorization. It is prohibited to republish this article sponsored by Alipay 15262042918