centos7安装docker,以及php、nginx、mysql环境(一)
安装之前先搞清楚几个破概念:镜像、容器、仓库,我这里不使用专业术语,这东西网上介绍很多,但是让人看的云里屋里的,反正我找了不下10个网页没看懂这些到底是死马鬼。举例说明吧:
镜像(images):镜像就是安装程序,比如centos系统,或者伟大的php,mysql,nginx这些安装程序就是镜像,镜像的不同版本就是标签(Tag)
容器(Container):容器是通过镜像创建的实例,什么鬼意思?比如通过nginx镜像创建一个容器,其实就是创建后的nginx运行环境,镜像是死的,容器是动态的,是可以运行的,容器是基于镜像之上的,同一个镜像可以创建多个容器,容器之间相互隔离。
仓库(Repository):仓库就是存放镜像的地方,什么php、mysql、nginx、python等等镜像都在仓库里,所以安装的时候要先从仓库拉下来。这里还有个概念:注册服务器( Registry ):注册服务器又叫仓库注册服务器,就是管理仓库的地方。比如:192.168.0.1,这上面有一个或多个仓库,注册服务器就是:192.168.0.1,我们一般告诉别人服务器,无非就是告诉他IP或者域名,就是这个意思。
一:安装docker
安装可以参考官方给出的步骤:https://docs.docker.com/install/linux/docker-ce/centos/
1:卸载系统的旧版本
$ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine2:安装依赖工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm23:设置docker仓库(这里设置阿里的,官方的可能访问不了)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4:安装docker
$ sudo yum install docker-ce
细心的朋友可能会问发现为什么是docker-ce?而不是docker。因为从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE。Docker CE 即社区免费版,Docker EE 即企业版,强调安全,但需付费使用。
5:查看是否安装成功
$ docker -v
6:启动docker
$ sudo systemctl start docker
二:docker实例,安装php,nginx,mysql等环境
理解了开头的几个概念,我们就知道怎么玩了,首先要启动docker,然后拉取镜像,最后创建容器。
在开始之前,我们先创建一个网络,为什么要创建网络?我们这里分别创建PHP,NGINX,MYSQL三个容器,容器之间是相互隔离的,那么NGINX怎么去访问PHP,PHP怎么去访问MySQL?可以通过link访问,但这种方式官方已经放弃,不建议使用,也可以通过容器IP访问,但这不灵活,所以我们通过指定网络模式让容器之间相互通信,也就是network模式,用 通俗的话表达:容器都在同一个网络,所以相互间访问就不是问题了。
$ docker network ls #查看网络信息 NETWORK ID NAME DRIVER SCOPE 39a2ecf30cb9 bridge bridge local 3e183347b761 host host local 19c68a66f8b9 none null local
这里我创建一个名称为:my_net 的网络
$ docker network create my_netdocker有四种网络类型: bridge,host,none,container;默认为:bridge,具体参考官方文档。
1:安装nginx
(1):docker已经启动了,我们先查一下nginx的镜像有哪些,(查找nginx在Docker Hub上的镜像)
$ docker search nginx
我这里有这么多nginx的镜像,这里我选择第一个,第一个是官方的。
search这个命令功能有限,看不到详情,更直观的方法是我们打开:https://hub.docker.com/ 这个网站,然后在这里面搜索,点进去以后还有详细的安装方法。
(2):拉取(下载)镜像
$ docker pull nginx #下载nginx,这里是下载上图第一个官方的,也可以下载其他的
搞下来以后查看一下镜像:
$ docker images
nginx已经到本地了。
搞到这里,我有个疑问,pull之后,到底把镜像放到哪里去了?找一下。
$ docker info
原来在这里到这个目录搜索一下:
$ find . -name *nginx*这里都是,很多很多
如果这目录不够大咋办?可以修改存储目录
$ find / -name docker.service #找下配置文件在哪里找到后,修改里面的:ExecStart=/usr/bin/dockerd --graph /usr/docker_path #比如把存储目录修改为/usr/docker_path,这里不继续扯淡了。
(3):创建nginx容器
docker官方有介绍:https://hub.docker.com/_/nginx
a):先运行一下nginx:
$ docker run -itd -p 80:80 nginx-i: 以交互模式运行容器,通常与 -t 同时使用;
-p: 端口映射,格式为:主机(宿主)端口:容器端口;如果有多个端口,-p 80:80 -p 81:81 这样写。
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-d:后台启动
其实到这一步,nginx已经起来了,但是配置文件在哪里?www目录在哪里?怎么关联主机上的目录?接着往下走。
b):查看一下我们刚才建立的这个容器,记录容器ID
$ docker ps这个容器ID为:f490bc3b0467
c):我们进入这个容器,根据选择要进入容器的ID
$ docker exec -i -t f490bc3b0467 /bin/bash #报错的话换 /bin/sh
我们现在已经到这个nginx的容器中了,这就是一个虚拟化的linux.
d):搜索一下nginx的配置文件在容器的哪个目录里面
$ find / -name 'nginx.conf'找到位置了
进去打开看一下:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
这里可以看到nginx的一些信息,比如日志位置,pid位置等,但是server配置没看到,注意文档最后一行,这里include包含了其他配置信息,/etc/nginx/conf.d/我们打开看一下,该目录下有一个默认的:/etc/nginx/conf.d/default.conf
server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; 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 /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 html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }
完整的配置信息就出来了。从上图可以看到主目录是在:/usr/share/nginx/
命令:exit 退出容器
e):个性化配置,把nginx配置文件拷贝到主机上来,这样修改配置文件就可以个性化配置nginx
$ mkdir -p /usr/local/nginx/etc #我这里把nginx配置文件在这个地方 $ docker cp f490bc3b0467:/etc/nginx/nginx.conf /usr/local/nginx/etc/ #容器的nginx.conf文件复制到/usr/local/nginx/etc
f490bc3b0467为nginx的容器ID,docker ps 命令可输出这个ID 。
注意这里cp 选择容器中的文件时,不能Tab自动补全路径,在这个地方被坑了一下,以为没有文件。
f):加载配置文件启动:
$ docker stop f490bc3b0467 #关闭nginx容器 $ docker run --name mynginx -p 80:80 -v /usr/local/nginx/etc/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx #启动
--name mynginx:给我们的容器取一个名字:mynginx
-v /usr/local/nginx/etc/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx:
把主机上的:/usr/local/nginx/etc/nginx.conf 挂在到容器etc/nginx/nginx.conf,通俗的说,以后修改配置文件,修改主机中的就行了。
ro:可选的参数是 :ro或者 :rw,前者表示容器只读,后者表示容器对数据卷是可读可写的。默认情况下是可读可写的。
执行一下,日,竟然报错,看一下报错信息,说是名称已经存在。查看一下:
$ docker ps -a #查看所有容器果然有重名的,我们把这个删掉。
通过上图可以看到这个容器的ID为:b772d749d082 ,OK
$ docker rm b772d749d082 #删除容器,如果容器在运行加-f 参数删除
再执行,运行成功!这样是可以启动,然后并没有什么卵用。
nginx的配置最基本的三个:
1:主目录
2:主配置
3:子配置(Nginx的server配置)
2和3也可以合二为一。
我们虽然把主配置挂载过去了,但是配置里面的www,也就是主目录,还是在容器里面,但我们的程序一般是放在主机里面,所以这里还需要挂载主目录。这样我们在主机的里的文件,就自动到容器中的nginx里去了,nginx才能解析到,我们刚才把主配置挂载了,现在把子配置也挂载一下,方法和上面完全一样。另外我们把www目录也挂载过去,停掉nginx,加上我们设置的网络:my_net。
NGINX最终配置:
$ docker run --name mynginx -p 80:80 --network my_net -v /usr/local/www:/usr/share/nginx/html -v /usr/local/nginx/conf.d:/etc/nginx/conf.d -v /usr/local/nginx/etc/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx主目录:usr/local/www
主配置:/usr/local/nginx/etc/nginx.conf
子配置:/usr/local/nginx/conf.d
加入网络:--network my_net #my_net为我们最开始配置的网络
如果修改了配置文件,docker exec -it 进入容器,再执行一下:nginx -s reload 就可以了。日志文件也是一样的方法。-v就是挂载,docker目前还不支持动态挂载,挂载同一个容器,要先停掉,删除以前的,然后挂载。
2:安装mysql
前面一部分和安装nginx一样,先搜索镜像,然后拉取下来,最后安装,安装nginx的时候我们是用search搜索的,因为这命令不直观,我们去官网搜索,官网我们在安装nginx的时候已经介绍了。
(1):官网搜索镜像
选择第一个mysql点进去
切换到tags这里,就可以看见各个版本了,这里我选择5.7
(2):拉取镜像
$ docker pull mysql:5.7 #拉取mysql5.7
mysql比较大,可能会比较慢,耐心等待,下载完后查看一下镜像:
(3):查看
$ docker images # 查看所有镜像 $ docker images | grep mysql #查看mysql镜像
(4):运行容器
先简单运行一下:
$ docker run --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
我们定义mysql的容器名:mysql5.7,root密码为:123456,-d:后台启动,这样一个mysql就运行了。我们安装nginx的时候也简单运行了一下,然后才是挂载,为什么要这样?因为我们不知道docker把这些玩意儿安装到了什么地方,所以先简单运行容器,然后进入容器,查找这些配置文件位置,然后就可以挂载了,不然位置都不知道,挂载个毛啊。这部分参考上面的nginx,当然这些在镜像官网也有介绍,可以参考。
(5):查看容器状态
$ docker ps #列出所有正在运行的容器 $ docker ps -a #列出所有容器,包括运行和未运行的(6):进入容器,查找一下mysql配置文件在哪里,推荐在官网上查看,我们开始搜索mysql的那个页面有详细的介绍。
(7):挂载启动
先在主机上创建几个目录:
$ mkdir -p /usr/local/mysql/logs /usr/local/mysql/conf /usr/local/mysql/data
mysql的配置文件目录,logs日志目录,数据存储目录,以及加入我们创建的网络:
MySQL最终配置:
$ docker run --name mysql5.7 -p 3306:3306 --network my_net -v /usr/local/mysql/data:/var/lib/mysql -v /usr/local/mysql/logs:/var/log/mysql/ -v /usr/local/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7
3:安装php
前面一些步骤在安装nginx和mysql的时候已经记录过了,有些步骤省略
(1):下载php7.1.27
$ docker pull php:7.1.27-fpm-alpine3.8查看一下:
[root@121 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE php 7.1.27-fpm-alpine3.8 45297c976686 11 days ago 68.3MB nginx latest 881bd08c0b08 2 weeks ago 109MB mysql 5.7 ee7cbd482336 2 weeks ago 372MB
(2):创建容器
$ docker run -p 9000:9000 --network my_net --network-alias php-fpm --name php7.1 -v /usr/local/www:/var/www/html -v /usr/local/php:/usr/local/etc/php -d php:7.1.27-fpm-alpine3.8-v /usr/local/www:/var/www/html :这个是把本机nginx的根目录和PHP容器的根目录做映射,
-v /usr/local/php:/usr/local/etc/php :这个是把PHP的配置文件做影射,在主机修改即可,方便。
--network my_net:加入网络
--network-alias php-fpm:给my_net网络加一个别名:php-fpm
fpm配置在:容器中的:/usr/local/etc/php-fpm.d/www.conf
修改nginx配置文件:
上面nginx默认是127.0.0.1,我们改成php-fpm,这个php-fpm就是上面创建nginx容器的时候,network-alias设置的my_net别名,不能直接写my_net,也可以用PHP容器的名字,这样启用nginx,运行PHP的时候,就访问PHP容器的9000端口了,下面的目录,是PHP容器的主目录,我们创建PHP容器的时候,把主机上的根目录和这个目录做了映射。主机上的文件会到这个地方去了。
这里也可以这样配置,但不推荐这种:
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' php7.1 #查出PHP容器的IP 172.17.0.4然后配置:fastcgi_pass 172.17.0.4:9000;
(3):设置php.ini,php运行的时候并不需要这个文件,不过为了配置方便,可以把这个文件搞出来;此文件没有现成的,我们先把容器中PHP安装包复制出来,然后解压放入到我们主机上的 /usr/local/php/etc 目录下,这个目录和容器做了映射,添加之后,容器中自然就有了。
$ docker cp php7.1:/usr/src/php.tar.xz /tmp #复制到主机的/tmp目录下,php7.1是容器名称 $ cd /tmp $ tar -xvJf php.tar.xz #解压 $ cp php.ini-production /usr/local/php/etc/php.ini #复制到主机下此目录,此目录一定要-v对应到容器的/usr/local/etc/php
(4):安装PHP扩展:
进入PHP容器中:
$ docker exec -it php7.1 /bin/sh #我这容器名是php7.1 $ cd /usr/local/bin $ ./docker-php-ext-install mysqli pdo_mysql #比如安装mysqli和mysqlpdo扩展
a:核心扩展,也就是php安装包里面有的扩展
如果报错:/usr/local/bin/docker-php-ext-enable: line 110: can't create /usr/local/etc/php/conf.d/docker-php-ext-mysqli.ini: nonexistent directory
在容器:/usr/local/etc/php/ 新建一个目录:conf.d
提示:此过程,不要强制中断,否则下次扩展的时候,可能会报: Unable to lock database: Resource temporarily unavailable;如果出现这个问题,退出来,重新启动一下容器。
# 如果安装的扩展需要自定义配置,比如FreeType需要和GD库一起安装
$ docker-php-ext-configure gd --with-freetype-dir=/usr/include/ \ $ docker-php-ext-install -j$(nproc) gd
安装一些必要的插件:
centos平台:yum -y install libxm12 libxml2-devel BZip2-devel bzip2-devel curl curl-devel libjpeg libpng freetype libjpeg-devel libpng-devel freetype-devel
alpine平台:apk add freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev libxml2-dev curl-dev libressl-dev
主机查看容器日志:
docker logs --tail="10" php7.1 #查看容器php7.1日志的最后10条
#删除所有容器
docker rm `docker ps -a -q`
#删除所有镜像
docker rmi `docker images -q`