Docker初学_php-nginx-mysql

Dcoker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的,可移植的,自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机),baremetal,OpenStack集群和其他的基础应用平台.
-Docker通常用于如下场景
.web应用的自动化打包和发布
.自动化测试和持续集成,发布
.在服务型环境中部署和调整数据库或其他的后台应用
.从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的Pass环境.

以上是比较官方的说明,开始实践。该文章主要记录个人实践中遇到一些问题的解决办法。
跟着 Docker从入门到实践(书),从git获取docker开始就有报错,yum默认安装的git版本不是最新的,需要安装最新的git版本。centos7的版本可能不是最新的,导致docker在运行容器的时候会报错,反正逐个在网络上搜索答案。具体遇到的问题也没有记录下来,最后没有延续这个教程。阮一峰老师的教程对我帮助很大,非常感谢。
链接:http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html

开始个人的实践。

安装 Docker CE

Docker 有两个版本:社区版 (Community Edition,缩写为CE)和企业版(Enterprise Edition)。文中使用社区版。
本来不准备写安装 Docker CE 步骤,后来完善文章的时候发现 Docker 官网上的安装教程不容易打开,所以也把安装 Docker 的步骤记录下来。
官网安装教程链接:https://docs.docker.com/install/linux/docker-ce/centos/ ,英文不太好的可以用google翻译,官网的教程还是比较完善的。
本文的运行环境是 Centos7,所以介绍 Centos7下安装 Docker。

系统要求:Centos7;启用centos-extras repository,默认是启用的;建议使用 overlay2 存储驱动。
CentOS Extras – 这个软件库是为那些增加格外功能,但不损坏 CentOS 与上游的兼容性,而且不更改基本组件的组件而设立的。CentOS 的开发小组已经针对这个软件库内的每个程序作出测试,确定它们能在 CentOS 下运作。上游提供者并未测试这些软件,它们亦不包含在上游产品内。这个软件库已连同 CentOS 一并安装,并缺省为启用的。
是否启用centos-extras repository,查看文件 vim /etc/yum.repos.d/CentOS-Base.repo,文件CentOS-Base.repo中enabled的値从0变成1。
overlay2简单介绍在后面的参考链接中有可以看下。

官网介绍的 Doker CE 的安装方式有3中,我选择常用的方式,通过设置 docker repositories 并安装 Docker,就是在增加 docker repository的链接,然后通过 yum 命令来安装和更新Docker。

设置存储库
安装所需的包。yum-utils提供了yum-config-manager 效用,并device-mapper-persistent-data和lvm2由需要 devicemapper存储驱动程序。
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
使用以下命令设置稳定存储库。
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

安装最新版本的Docker CE和containerd
$ sudo yum install docker-ce docker-ce-cli containerd.io
如果提示接受GPG密钥,校验码是否匹配060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35,如果匹配,则接受 。在下载完成以后就能看到提示。

如果需要安装特定版本:

//查看docker版本列表
$ yum list docker-ce --showduplicates | sort -r
//指定安装某个版本的命令
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

启动 docker

$ sudo systemctl start docker

运行hello-world验证是否安装成功

$ sudo docker run hello-world

按照步骤安装基本没出现什么大问题,还有几个常见的问题记录下。

//检查docker是否安装正确,查看docker信息
$ docker version
//或者
$ docker info

Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组,我默认是root用户操作,如果不是 root 用户需要加入到 docker 用户组中。

//如果没有docker组,需要创建docker组。
$ sudo groupadd docker
//将您的用户添加到该docker组。
$ sudo usermod -aG docker $USER

Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image
文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。–http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html

mage(镜像) 和 container(容器)的具体概念,我个人理解,就像装系统的时候,系统盘是个image,系统安装成功后,运行的系统就是一个 container。如果通过ghost软件对系统进行备份生成的ghost文件又是一个新的image。学习 docker 的过程会对这些基础概念了解更深刻。
常用的命令:

//列出本机的所有 image 文件。
$ docker image ls
//删除 image 文件
$ docker image rm [imageName]
//在容器中运行hello-world软件
$ docker container run hello-world
//终止容器--有的容器会自动终止,对于不会知道终止的容器可以使用下面语句
$ docker container kill
//列出本机正在运行的容器
$ docker container ls
// 列出本机所有容器,包括终止运行的容器
$ docker container ls --all
// 没执行一次 $ docker container run hello-world 就会创建一个新的容器,如果需要删除旧的已经终止的容器
$ docker container rm [containerID]
docker ps //查看当前正在运行的容器
docker start 容器id或者容器name //启动容器
docker stop 容器id或者容器name //停止容器,kill 类似于电脑关机的时候直接拔掉电源,stop 开始菜单中的关机
docker container logs [containerID]命令用来查看 docker 容器的输出,即容器里面 Shell 的标准输出。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令查看输出。
docker container exec命令用于进入一个正在运行的 docker 容器
docker container exec -it [containerID] /bin/bash 进入容器,在容器中执行 shell 命令
docker container cp命令用于从正在运行的 Docker 容器里面,将文件拷贝到本机。拷贝到当前目录的写法。docker container cp [containID]:[/path/to/file] --这个会在后面的实践中用到。

实践

准备部署的环境是nginx+php+mysql,其中php还需要支持cli模式。从选择image开始,之前教程中使用的php是php:5.6-apache。我使用的是nginx,所以需要php和nginx两个image。nginx选个稳定版本即可。不需要选择php7,因为项目是早期开发的,找个5.6版本就可以了。选择我需要的版本tags(标签)怎么写呢,到底有哪些标签。

docker search -s 10 php

docker search -s 10 php

从Docker Hub查找所有镜像名包含PHP,并且收藏数大于10的镜像。
我个人还是习惯在docker官网上查找image(https://hub.docker.com/r/library/php/tags/)。
我选择的image,使用pull语句下载到本地:
     nginx
     php:5.6-fpm
     mysql:5.5
     部署项目需要解决的问题列表:
     *php需要mysql扩展
     *php需要cli扩展,当然也可以直接使用php:5.6-cli
     *php需要设置时区,nginx需要设置默认编码格式为UTF-8
     *mysql设置log过期时间

docker image pull ngnix
//不指定tag会直接获取最新版本,可以在提示中看到
//Using default tag: lastest
//lastest: Pulling from library/nginx
然后执行:docker image ls 就能看到获取到本地的image
docker image pull php:5.6-fpm
docker image pull mysql:5.5

1.php:5.6-fpm

php docker run第一版:
docker container run \
  -p 9000:9000 \
  --name my-php-fpm \
  --volume "$PWD/www":/var/www/html \
  -d \
  php:5.6-fpm

9000是nginx连接fpm的默认端口,$PWD表示当前路径,-d后台运行,如果没有-d启动后会进入php运行环境。/var/www/html 是容器中php的工作目录。

--volume "$PWD/www":/var/www/html \可以写成--volume "root/www":/var/www/html \

只需要将php文件放到root/www文件夹,会映射到容器中的/var/www/html 文件夹。
如果需要设置时区等配置信息,编写修改php的配置文件,写个简单的php代码查看ini文件的位置。

<?php
echo phpinfo();
>

phpinfo
进入php容器内:

docker exec -it my-php-fpm bash
默认进入的是 /var/www/html文件夹

在/usr/local/etc/php 的文件夹中没有发现php.ini配置文件。这个问题好像是使用php-fpm会遇到的。
网上找到了解决办法:https://serverfault.com/questions/840046/why-is-there-no-php-ini-file-when-i-install-php-in-a-docker-container
php.ini
基本思路是:php容器中有源代码,存放的位置/usr/src/php.tar.xz,解压以后可以找到文件:
php.ini-development 和 php.ini-production,修改以后的docker run。

docker container run \
  -p 9000:9000 \
  --name my-php-fpm \
  --volume "$PWD/www":/var/www/html:ro \
  -v "$PWD/php.ini-development:/usr/local/etc/php/php.ini" \
  -d \
  php:5.6-fpm

修改时区等设置,只需要先修改php.ini-development 和 php.ini-production文件。
/usr/local/etc/php/php.ini是php容器中配置文件的路径。
安装扩展,直接在容器来运行docker-php-ext-install命令
命令中的“:ro”,表示只读。

docker-php-ext-install mysqli

mysqli
在Additional.ini中可以看到。
1.1 创建image文件
如果需要容器运行时就自带扩展,可以创建一个自己的image文件。
创建一个Dockerfile文件,文件名Dockerfile:

FROM php:5.6-fpm
RUN docker-php-ext-install mysqli
RUN docker-php-ext-install pcntl

如果有需要忽略的文件,创建一个文件名为.dockerignore的文件,然后不需要放入image的文件加入到里面。
创建image

docker image build -t phpfpmwithmysql

最近发现运行的时候会报错,说需要一个参数:
发现需要把Dockerfile文件的路径写上去,估计在默认路径下没能找到 Dockerfile文件
修改下:
docker image build /root/docker -t phpfpmwithmysql
其中/root/docker 是 Dockerfile 文件存放的路径。

PHP的docker run的最终的版本是:

docker container run \
  -p 9000:9000 \
  --name my-php-fpm \
  --volume "$PWD/www":/var/www/html \
  -v "$PWD/phpconf/php.ini-development:/usr/local/etc/php/php.ini" \
  --link my-mysql:dockermysql.01 \
  -d \
  phpfpmwithmysql

my-mysql是mysql容器的名称,dockermysql.01是mysql数据库的别名,类似于localhost。
我的mysql和php在同一台机器上,在其他机器上可以直接用ip地址访问mysql数据库(当然要打开权限),但是php容器中使用ip地址访问会报错:no route to host。mysql容器的别名修改成localhost也不能用,localhost代表的东西太多了。至于使用ip也不能访问mysql我也没有深究了,添加一个link,就可以用别名访问mysql数据库。
2.nginx容器

docker container run \
  -p 80:80 \
  --name my-nginx \
  -v "$PWD/www":/usr/share/nginx/html:ro \
  --link my-php-fpm:php \
  -d \
  nginx

/usr/share/nginx/html是nginx容器的工作目录,/etc/nginx/conf.d是配置文件所在的文件夹。
nginx文件的配置默认是没有配置fpm的。
容器中文件夹/etc/nginx/conf.d下存放的是default.conf,我先把配置文件从容器中复制出来,然后修改,修改以后再重新创建和运行新的nginx容器。

docker container run \
  -p 80:80 \
  --name my-nginx \
  -v "$PWD/www":/usr/share/nginx/html:ro \
  -v $PWD/docker/nginx/conf.d:/etc/nginx/conf.d:ro \
  --link my-php-fpm:php \
  -d \
  nginx

此处为了防止理解错误,标记下:
-v $PWD/docker/nginx/conf.d:/etc/nginx/conf.d
$PWD/docker/nginx/conf.d 是一个文件夹路径,conf.d是文件夹名称,$PWD表示当前路径,$PWD/docker/nginx/conf.d 表示主机文件夹conf.d的路径,也可以写成直接路径 /root/docker/nginx/conf.d。此文件夹中包含一个文件 default.conf。这个文件时我之前从容器中复制出来,然后再根据自己的需要修改的。
配置文件default.conf:

server {
    listen       80;
    server_name  localhost;

    charset utf-8;
    #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$ {
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/$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;
    }
}

如果要修改其他的,按照个人需求修改 。
3.mysql:5.5

docker container run \
  -d \
  -p 3306:3306 \
  --name my-mysql \
  -v $PWD/docker/mysql/data:/var/lib/mysql\
  --env MYSQL_ROOT_PASSWORD=123456 \
  -v /etc/localtime:/etc/localtime:ro \
  mysql:5.5

这个配置文件我也是默认运行mysql容器,复制出mysql的配置文件。
修改以后配置文件以后再增加
-v $PWD/docker/mysql/my.cnf:/etc/mysql/my.cnf
运行mysql容器。mysql的日志清理时间可以在配置文件中设置。

-v /etc/localtime:/etc/localtime:ro \
设置mysql时间和系统时间一致

3.1 两个 mysql 容器同时运行
由于各种原因,需要在一台机器上运行两个mysql容器。因为要运行两个mysql容器,所以需要两个系统端口,mysql的默认端口是3306,再用一个3307。
将 container 中的端口映射到系统端口命令选项是:–publish , -p

官网教程
Publish or expose port (-p, --expose)
$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash
This binds port 8080 of the container to TCP port 80 on 127.0.0.1 of the host machine. You can also specify udp and sctp ports. The Docker User Guide explains in detail how to manipulate ports in Docker.
127.0.0.1:80 是运行docker的主机端口号,8080是容器内的端口号。

$ docker run --expose 80 ubuntu bash
This exposes port 80 of the container without publishing the port to the host system’s interfaces.
如果不想映射到主机的端口,只暴露端口给容器内调用,可以使用–expose。

代码:

docker container run \
  -d \
  -p 3306:3306 \
  --name my-mysql-1 \
  --env MYSQL_ROOT_PASSWORD=123456 \
  mysql:5.5
docker container run \
  -d \
  -p 3307:3306 \
  --name my-mysql-2 \
  --env MYSQL_ROOT_PASSWORD=123456 \
  mysql:5.5

查看当前正在运行的容器,可以看到对应的端口映射
可以用常用软件测试下,两个mysql连接都是成功的,只是端口号不一样。
4.从容器中复制文件到运行系统中
这些默认的配置文件都是复制到root路径然后再修改的,这个方法比较笨,也正好用到了从容器复制文件的语句。
参考网站:https://blog.csdn.net/chengly0129/article/details/70147517

docker cp my-php-fpm:/usr/local/etc/php/php.ini /root 
docker cp my-nginx:/etc/nginx/conf.d/root 
docker cp my-mysql:/etc/mysql/my.cnf /root 

5.Centos7 端口操作
参考文章:
http://havee.me/linux/2015-01/using-firewalls-on-centos-7.html
https://blog.csdn.net/u013310075/article/details/80983117
Centos升级到7之后,内置的防火墙已经从iptables变成了firewalld。

//查看端口情况
sudo firewall-cmd --list-all
//打开http 80端口,--permanent表示用久有效
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-port=80/tcp --permanent
//重启防火墙
sudo firewall-cmd --reload
//再次查看端口情况
sudo firewall-cmd --list-all

sudo firewall-cmd --list-all
个人纪录,希望解决方式能分享给需要的人。

其他参考网站:
https://zhuanlan.zhihu.com/p/26418829?utm_medium=social&utm_source=weibo(稍微进阶的教材)
https://segmentfault.com/q/1010000008638208
CentOS Extras是什么–http://www.ha97.com/2625.html
【Docker 基础知识】存储驱动overlay和overlay2–https://blog.csdn.net/zhonglinzhang/article/details/80970411
docker 安装nginx、php-fpm(有参考价值):https://www.cnblogs.com/boundless-sky/p/7182410.html?utm_source=itdadao&utm_medium=referral
docker常规操作——启动、停止、重启容器实例–https://blog.csdn.net/Michel4Liu/article/details/80889977
默认路径,方便查阅:
nginx默认安装以后,容器中默认的工作目录/user/share/nginx/html
nginx容器中文件夹/etc/nginx/conf.d下存放的是default.conf(default.conf是nginx.conf的初始值)
nginx默认的配置文件位置:/etc/nginx/nginx.conf
mysql:5.5
数据位置
show global variables like “%datadir%”;
/var/lib/mysql/
配置文件位置:/etc/mysql/my.cnf
复制配置文件出来看下:
docker cp my-mysql:/etc/mysql/my.cnf /root
php配置文件位置
复制配置文件出来看下:
docker cp my-php-fpm:/usr/local/etc/php/php.ini /root

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值