闲来无事就研究了下Docker,一开始还没接触过它,不知道他是干嘛的,最近在头条上看到很多相关的文章,于是下定决心好好研究下这个Docker。
下面我主要分以下几点讲述,也算是自学的一些心得吧
1、Docker是什么?
2、Docker的出现解决了我们什么问题
3、Docker和传统的虚拟机有什么区别
4、Docker中几个比较重要的概念
5、开始搭建我们的Lnmp环境+redis扩展
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后可以发布到任何的linux机器上,也可以实现虚拟化。容器是完全使用沙盒机制,相互直接不会有任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行,最重要的是他们不依赖任何语言,框架或系统。Docker的slog就是one build,run everywhere.
在这里举个常见的例子:我们开发时一般需要先搭建测试环境,然后将没有bug的代码提交到正式环境。这就涉及到我们搭两个环境,可能在搭建的过程中因为系统的版本等因素导致两个环境不一样,这就苦恼了,如果我们是用docker搭环境的,只需要在
正式环境下也装个docker,直接将测试环境镜像文件复制到正式环境,正式环境就可以跑了。而且两个环境是强一致的。
1、相同点
docker容器技术和虚拟机技术都是虚拟化技术。
2、不同点
docker中的容器共享宿主机的内核,而虚拟机则是有独立于宿主机的内核。
docker中的所有容器共享宿主机的内核,内核只维护一套uid/gid机制(这个在后面会讲到)
1、镜像: 类似iso文件,其实就是一些文件而已(精简版的linux系统文件)。
2、容器: 说直白点就是镜像的运行状态。
3、仓库:镜像的存储位置。我们可以把做好的镜像文件提交到dockerHub或者到阿里云发布,方便下次获取。
搭建之前说下:首先了解下相关的镜像、容器操作命令,docker基本的网络类型及实现的原理。要不然下面只会云里雾里。
1、首先了解下容器通信
关于 docker0 和 bridge
Docker 容器网络模式包括桥接模式(bridge)、主机模式(host)、中继模式(overlay)等,但大多数时候我们只使用默认的桥接模式(bridge),本文也只涉及默认的桥接模式(bridge)。
Docker 会在宿主机上创建一个名称为 docker0 的桥接网络,这个网络将会是容器的默认网络,通过在宿主机上运行 ifconfig docker0 你将看到这个网络的具体信息。
容器名 所用镜像 说明
nginx nginx:latest 官方最新版本镜像
mysql mysql:5.7 也可以使用 mariadb:10.2
phpfpm php:7.2-fpm 可以使用已安装 mysql扩展的bitnami/php-fpm
本文中使用的路径如下:
网站主目录: ~/wwwroot
mysql root密码: root
nginx 配置文件目录: ~/docker/nginx
mysql 配置文件目录: ~/docker/mysql
php 配置文件目录: ~/docker/php
1、获取nginx配置
docker run --name nginx -d nginx #运行一个nginx容器
mkdir ~/docker #创建容器配置文件夹
docker cp nginx:/etc/nginx ~/docker #复制nginx默认配置
docker cp nginx:/usr/share/nginx/html ~ #顺便复制默认网站内容
mv ~/html ~/wwwroot #更改文件夹名为wwwroot
docker stop nginx #停止nginx容器
docker rm nginx #删除nginx容器
2、运行mysql容器
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -d -p 3306:3306 mysql:5.7
3、运行nginx容器
docker run -d --name nginx
-v ~/docker/nginx:/etc/nginx
-v ~/wwwroot:/usr/share/nginx/html
-p 80:80
-p 443:443
nginx
4、运行php-fpm容器
docker run --name phpfpm -d -P
-v ~/wwwroot:/usr/share/nginx/html
php:7.2-fpm
说明:需要注意的是 PHP-FPM 容器的网站目录必须与 nginx 内的一致,否则会有不必要的麻烦
另外这里使用了 PHP 官方的包,采用了7.2.12版本,各版本的 Tags 可以在官方Docker Hub页面中查询
5、配置容器通信
docker network create test
docker network connect test phpfpm
docker network connect test nginx
docker network connect test mysql
使用容器名好处就是比ip更稳定
6、配置nginx链接php-fpm,nginx.conf做如下修改:
a.fastcgi_pass: php-fpm:9000
b.将/script 改为$document_root
至此访问页面就能成功。
数据库配置:
1、配置mysql数据库,下载phpmyAdmin.登陆数据库
a.下载 phpMyAdmin 到网站主目录
wget https://files.phpmyadmin.net/phpMyAdmin/4.8.3/phpMyAdmin-4.8.3-all-languages.zip
b.解压缩 phpMyAdmin 压缩包
unzip phpMyAdmin/4.8.3/phpMyAdmin-4.8.3-all-languages.zip
c.修改 phpMyAdmin 目录名称
mv phpMyAdmin-4.8.3-all-languages phpmyadmin
d.在nginx.conf添加
location /phpmyadmin {
root /usr/share/nginx/html/phpmyadmin;
index index.html index.htm;
}
location ~ /phpmyadmin/(?(.*)\.(php|php5)?$){
root /usr/share/nginx/html/phpmyadmin;
fastcgi_pass 172.17.0.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
当访问phpmyadmin 报mysqli错误,添加mysqli扩展(利用DockerFile)
FROM php:7.2-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-install -j$(nproc) iconv \
&& 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 mysqli pdo pdo_mysql
将以上代码写进DockerFile文件
之后我们构建一下我们的镜像:
docker build -t myphpfpm-7.2 .
删除我们之前的phpfpm容器
docker stop phpfpm
docker rm phpfpm
docker run --name phpfpm -d -P \
-v /root/wwwroot:/usr/share/nginx/html \
myphpfpm-7.2
之后访问就正常,但登陆失败
我们需要将 phpmyadmin 默认的 Server host 由 localhost 修改为我们宿主机在容器中的IP,即 172.17.0.1
前往 phpmyadmin 配置文件夹
cd ~/wwwroot/phpmyadmin
复制config.sample.inc.php并命名为 config.inc.php
cp config.sample.inc.php config.inc.php
修改内容如下:
将config.inc.php中的host改为mysql(在容器通信配置过)即可
上一部分我们已经在宿主机与容器间共享了部分文件夹,如网站目录、Nginx 配置目录等,因为这些是显而易见且会影响我们对容器的基本使用的,但实际上各容器需要共享的文件不止这些,下表是一个不完全统计,各位可以根据自己的需要修改
容器 需与宿主机共享内容 容器内文件路经 宿主机文件路经 绑定方式
nginx 网站主目录 /usr/share/nginx/html ~/wwwroot 文件
nginx 配置文件 /etc/nginx ~/docker/nginx 文件
nginx 证书文件 /etc/letsencrypt /etc/letsencrypt 文件
mysql 数据库文件 volume:mysql /var/lib/mysql volume
mysql 配置文件 /etc/mysql ~/docker/mysql 文件
phpfpm 配置文件 /usr/local/etc/php ~/docker/php 文件
重新运行容器
我们需要由容器复制默认配置文件,再删除原有容器,之后加入新的文件绑定后重新运行容器:
复制容器默认配置文件
docker cp mysql:/etc/mysql ~/docker #复制 mysql 配置文件
docker cp phpfpm:/usr/local/etc/php ~/docker #复制phpfpm配置文件
删除所有容器
docker stop nginx
docker rm nginx
docker stop mysql
docker rm mysql
docker stop phpfpm
docker rm phpfpm
重新运行 Nginx 容器:
docker run -d --name nginx
-v ~/docker/nginx:/etc/nginx
-v ~/wwwroot:/usr/share/nginx/html
-v /etc/letsencrypt:/etc/letsencrypt
-p 80:80
-p 443:443
nginx
重新运行 MySQL 容器
docker run -d --name mysql
-e MYSQL_ROOT_PASSWORD=root
-v ~/docker/mysql:/etc/mysql
-v mysql:/var/lib/mysql
-p 3306:3306
mysql:5.7
重新运行 phpfpm 容器
docker run --name phpfpm -d -P
-v ~/wwwroot:/usr/share/nginx/html
-v ~/docker/php:/usr/local/etc/php
myphpfpm-7.2
添加redis扩展,同样利用到了DockerFile
在DockerFile中添加一下代码:
FROM myphpfpm-7.2
MAINTAINER author "jia*****@gmail.com"
ENV PHPREDIS_VERSION 3.13
RUN curl -L -o /tmp/redis.tar.gz https://github.com/phpredis/archive/$PHPREDIS_VERSION.tar.gz \
&& tar xfz /tmp/redis.tar.gz \
&& rm -r /tmp/redis.tar.gz \
&& mkdir -p /usr/src/php/ext \
&& mv phpredis-$PHPREDIS_VERSION /usr/src/php/ext/redis \
&& docker-php-ext-install redis \
&& rm -rf /usr/src/php
执行docker build -t phpfpm-redis .
将之前的myphpfpm7.2停掉
最重要的一点就是将extension=redis.so写入conf.d目录(PHP的配置文件)下的docker-php-ext-redis.ini,这个是非常重要的。切记勿忘
添加了phpredis扩展,再装一个redis容器就ok了。
好了,今天的分享就到这了。