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