我刚开始学习docker时,想的是docker pull centos, 然后在centos上安装所有应用。但是去docker官方网站上能看见, php, mysql, nginx都有现成的镜像。几乎所有这种软件,redis, mongodb,esearch都有官方的docker镜像。 以后docker直接下载软件会很方便。
嗯,那就安装三个,然后相连吧。
拉取,开容器,进入容器
docker pull nginx
docker run -itd -p 80:80 --name nginx nginx
docker exec -it 26204fca20dc /bin/bash
里面连个ps命令也没,vim也没,支持apt-get命令,有需要可以自己安装。只查看文件内容可以用cat
Apt-get update
Apt-get install vim
apt-get install procps 安装ps
apt-get install inetutils-ping 安装ping
apt-get install net-tools 安装ifconfig
本地80端口没被占用的话,可以直接访问 , http://localhost/
nginx是默认启动的。
Nginx -h 查看配置文件目录,
默认nginx都是这个目录
vim /etc/nginx/conf.d/default.conf
看到默认访问目录是
vim /etc/nginx/conf.d/default.conf
/usr/share/nginx/html。
我们再开一个容器,映射这个目录吧。
我们查看下本地81是否被占用, 名字改成nginx2
lsof -i:81
dockerrun -itd -p 81:80 -v /Users/guanliyang/php:/usr/share/nginx/html --name nginx nginx2
访问下,
403,我本地目录没有index.html文件, 嗯,起码证明nginx启动成功
这里不要学我, 第一次就映射你的项目目录, 这时可以删除第一个无用镜像。
然后我们来搞php-fpm
docker pull php:7.4-fpm
docker run -itd --name php-fpm7.4 -p 9000:9000 -v /Users/guanliyang/php:/Users/guanliyang/php 77cd7cd803b2
注意我们这里必须映射php项目目录, 你项目目录是nginx.conf文件里面配置的,但这个配置会作为参数传给php-fpm, 然后php-fpm会读取php文件并解析, 这样php才可用。
映射9000端口,映射前还是 lsof -i:9000 查看一下。
然后建立一个index.php文件,nginx访问他http://localhost:81/index.php
会直接把index.php文件下载下来,因为我们配置文件里面没有支持php,
去nginx容器里面。
vim /etc/nginx/conf.d/default.conf
修改配置文件。
以下是废话
这里我们又想重新run我们的nginx镜像里,原因是我想把nginx.conf配置文件映射处理,便于配置。其他两个nginx容器删掉,避免重名。
docker run -itd -p 80:80 -v /Users/guanliyang/php:/usr/share/nginx/html -v /Users/guanliyang/nginx.conf:/etc/nginx/nginx.conf --name nginx nginx
我们配置文件的内容是
#user nobody;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /usr/share/nginx/log/error.log;
#error_log /Users/guanliyang/php/log/error.log;
#error_log /Users/guanliyang/php/log/error.log notice;
#error_log /Users/guanliyang/php/log/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
#server_name www.fu.com;
#charset koi8-r;
#root /Users/guanliyang/php;
root /usr/share/nginx/html;
#access_log /Users/guanliyang/php/log/host.access.log;
location / {
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 172.17.0.3:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
}
}
继续废话,这里真是废话。
(docker最麻烦的就是刚开始不好理解容器和镜像的作用, 比如这里, 第一个nginx容器我们装过vim, 第二个开启的容器,vim不可能存在,需要重新装。第一个容器的任何修改都不会出现在第二个容器里面。 结论是我们在容器里做的任何修改,都要重新导出镜像, 然后在新镜像里面重新 run, 开启容器,你修改的内容才会存在) 创建新镜像 docker container commit -m "ad a new file" -a "docker newbee" 89b4e9f1bcb5 test:0.1 打好标签,你可以把它上传到云上。 docker tag centos:0.3 guanliyang/centos:0.3 Docker push guanliyang/centos:0.3 注意这里名字不能重复 vim /etc/nginx/conf.d/default.conf 里面,把对php的配置去掉, root 后面路径删除。 重启nginx Nginx -s reload 其实在docker配置文件, dashboart 里面有容器列表, 可以直接点击重启按钮。 哦,两种发放均重启失败, ps命令没有,安装一下。 apt-get install procps docker restart nginx 重启nginx, 其实重启成功,配置错误。
这里有一个大坑, 由于run的时候没有映射配置文件, 一旦你配置文件配置错误, 你 docker restart nginx 的时候查看log,说你配置文件错误不能启动,不能启动就进不去容器,你改不了配置。改不了配置就启动不成功,。这是一个死循环。 只有删掉容器重新run。 原来的容器就废掉了。
上条语句回报 nginx: [emerg] open() "/Users/guanliyang/php/log/error.log" failed (2: No such file or directory) 错误,让我分析一下原因, 开启容器,容器自动开启nginx服务, nginx开启前一定加载配置文件, 配置文件我映射的本地nginx.conf文件, 我这个配置文件里有一行: error_log /Users/guanliyang/php/log/error.log; 有意思了, 这行配置它会去容器里找这个文件,容器里没有目录 /Users/guanliyang/php/log/, 这时候你在宿主机器怎么建立文件都没有,因为他会去容器里找这个文件。 知道原因就好办了, 修改命令为 docker run -itd -p 80:80 -v /Users/guanliyang/php:/Users/guanliyang/php -v /Users/guanliyang/nginx.conf:/etc/nginx/nginx.conf --name nginx nginx 容器开启成功了,
安装mysql
docker pull mysql
默认安装的是mysql8.0
映射 -p 3307:3306 容器的是3306端口,宿主机是3307端口。
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql
这里MYSQL_ROOT_PASSWORD=123456可以直接指定密码,舒不舒服。
然后你还得开启,其他机器可以访问。
# 创建用户和用户密码,%表示通配,在所有host上都可以登录 create user 'guanliyang'@'%' IDENTIFIED BY '123456';
#删除用户 drop user hanMM
#授权用户所有权限 GRANT ALL ON *.* TO 'guanliyang'@'%';
建立了一个用户guanliyang , 密码123456, 且宿主机也可以访问。
我们给一个php文件
<?php try {
$dbh = new PDO('mysql:host=172.17.0.4;port=3306;dbname=sys', 'guanliyang', '123456');
foreach(
$dbh->query('SELECT * from sys_config') as $row) { print_r($row); }
$dbh = null;
}
catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } ?>
没啥玩应儿哈,要注意的是。
这里端口是3306,我run是对应端口 3307:3306
就是从php-fpm容器对应端口时,直接对应mysql容器中的3306端口,而不是宿主机的3307端口。
好! 三大件都通了。
以上的, 172.17.0.1 是什么意思也清楚了, 他是宿主机的ip,
知道原理就很好完了,我们修改nginx.conf 配置文件
fastcgi_pass
172.17.0.9:9000;
我瞎写一个ip,docker restart nginx 重启下, 访问一下,
html文件访问正常,我们所有php文件都报404错误, 证明fastcgi_pass不通。
修改下:
fastcgi_pass
172.17.0.3:9000;
172.17.0.1是宿主机ip, 172.17.0.3是php-fpm容器ip, 这两个都通。
官方文档解释了为什么mac去平容器ip不通,但其实容器ping宿主机是通的。
好,万事大吉,大吉大利。终于成功了。恭喜恭喜。