1、在官网安装docker

   https://hub.docker.com/editions/community/docker-ce-desktop-windows

2、在官网测试你的安装

https://docs.docker.com/docker-for-windows/#test-your-installation

3、安装镜像

   https://www.runoob.com/docker/docker-install-nginx.html

4、开始配置环境

①、创建容器

       docker run -itd -p 23:22 -p 80:8080 -p 8080:8080 --name dev --dns=10.237.8.8  -v  d:/www/vhost:/home/work/app/nginx/conf/vhosts -v d:/www:/home/work/data/www/  dev-registry.be.mi.com/online/centos63:php71 /usr/bin/supervisord

      参数说明:

  • -itd : 已守护进程方式运行
  • -p : 端品映射, 80( 开发机端口 ) : 8080 ( 容器端口)
  • -v : 目录映射,d:/www(需要在本地手动创建),d:/www/vhost(开发机目录,需要手动创建) : /home/work/app/nginx/conf/vhosts (容器目录);
  • --dns : 默认DNS解析,一般指定为10.237.8.8
  • --name : 容器名称或标签,可以在启、停、删除容器时、与其它容器进行连接时使用
  • dev-registry.be.mi.com/online/centos63:php53 镜像名称 php53代表TAG,不同TAG可以使用不同的镜像
  • /usr/bin/supervisord 容器创建 后第一个运行的程序,小米网基础环境镜像的服务是使用supervisord进行管理的,需第一个启动它

     报错实例:

   (1)、docker: Error response from daemon: Mount denied:The source path "D:/www/vhost"  doesn't exist and is not known to Docker. See 'docker run --help'.

               错误原因:本地没有改文件夹

               解决方案:在本地创建文件夹

  (2)、docker: Error response from daemon: driver failed programming external connectivity on endpoint dev (eb9e6278e4014ba9707d010c9fea4fe6c2250bc2cd0db3ad8ef10db9664cf032): Bind for 0.0.0.0:80 failed: port is already allocated.

              错误原因:80端口被占用

              解决方案:使用docker ps –a 查看运行的进程,然后将进程停止以及移除,docker stop 2137af85261a(CONTAINER ID) ,docker rm 2137af85261a

②、将新建的dev项目以bash运行,并且通过容器进入ssh

       docker exec -it dev bash

       在此同时新开启一个cmd命令框,执行以下两个命令:docker stop dev    ,  docker start dev

③、切换到work用户

        su – work

④、进去docker,熟悉文件内容。

       此时的位置在:/home/work

  • ls之后就可以看到以下文件:app  data  logs  opshell
  • cd  data/www  本地目录与docker映射的目录
  • cd app/  这里有nginx php mysql等文件,如下:git  keycenter_agent  logcollect  mae  micron_agent  micron-agent  mysql  nginx  php  supervisor
  • cd app/supervisor/etc  这里是一些配置文件,如下:demo.ini.template  dssagent.ini.bak  hostname.ini.bak  keycent_agent_c3.ini.bak  keycent_agent_lg.ini.bak  logcollect.ini  micron-agent.ini  nginx.ini  php-fpm.ini

⑤、开启nginx

  • 进去nginx目录,    cd /home/work/app/nginx
  • 在本地的d:/www/vhost目录下创建xx.conf,例如:
server
{
    listen       8080;
    server_name  zxy.XXXX.com;
    index index-test.php  index.html index.htm  default.html default.htm default.php;
    root  /home/work/data/www/XXXXXX/web;
    if ($request_uri ~ "^/api/(.+)$") {
        set $path $1;        rewrite .* /api.php?$path last;
    }
    if (!-e $request_filename){
        rewrite ^/(.+)$ /index-test.php?r=$1 last;
    }
    location ~ .*\.(php|php5)?$
    {
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index-test.php;
        include /home/work/app/nginx/conf/fastcgi_params;
        gzip on;
        gzip_min_length 1k;
        gzip_disable "MSIE [1-6]\.";
        gzip_buffers 4 16k;
        set $path_info "";
        set $real_script_name $fastcgi_script_name;
        if ($fastcgi_script_name ~ "^(.+?\\.php)(/.+)$")
        {
                set $real_script_name $1;
               set $path_info $2;
        }
        fastcgi_param SCRIPT_REAL_SCRIPT_NAME $real_script_name;
        fastcgi_param SCRIPT_FILENAME /home/work/data/www/XXXXX/web$real_script_name;
        fastcgi_param SCRIPT_NAME $real_script_name;
        fastcgi_param PATH_INFO $path_info;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
    }

    location ~ .*\.(js|css)?$
    {
        expires      12h;
    }
}
  • vim app/nginx/conf/nginx.conf  把下面几段注释掉。

       忘记是啥了。

  • 第一次运行nginx脚本,  -> cd ..
    ->./run.sh start
  • 重启nginx,    ./run.sh reload  

⑥、开启php

  • 进去php目录,    cd  /home/work/app/php
  • 第一次运行php,    ./run.sh start    
  • 重启php(在docker中php是自动启动的),    ./run.sh reload  

⑦、配置C:\Windows\System32\drivers\etc\ hosts 

备注:./run.sh status 可以看到当前php、nginx的运行状态

5、关闭cmd命令框之后,进入docker的方法;

  •     管理员方式运行cmd,执行  docker exec -it dev(容器名) bash  命令,之后重复4、(3)以及以下的步骤即可。

6、如果有一天配置新的项目之后,没有任何错误,访问域名显示没有访问到(ERR_CONNECTION_REFUSED)。

  • 这种情况是在没有请求到nginx时出现的,原因为:nginx8080端口与docker映射失败。
  • docker restart dev  重启你的项目docker,报错: Error response from daemon: driver failed programming external connectivity on endpoint dev (5b300a42d9908f51c034a891d2e569e28e035aab9c7794fcbcabf8417057814d): Error starting userland proxy: mkdir /port/tcp:0.0.0.0:8080:tcp:172.17.0.2:8080: input/output error
    Error: failed to start containers: dev
  • 解决方案:重启你本地的docker服务。

7、在docker中ping 你的域名失败,解决方案如下。

  • 切换到root权限
  • vim /etc/hosts  
  • 路由为:172.17.0.1,在本地打印$_SERVER['REMOTE_ADDR']得来。
  • 172.17.0.1 zxy.express.com

 

8、如果想要什么扩展,比如redis、memcache等,先去/home/work/app/php/etc/php.ini中看下是否已经存在。

        

9、 docker 内部署多个项目时,项目间互联问题(PHP,nginx在同一容器内)

            当docker 同一个容器内部署多个项目时,有时会出现项目相互访问的情况。

            此时,经常出现访问不同的情况。

            例子:

                      后台b系统代码,集成访问b-api的接口域名。

                      b系统代码与b-api代码,均部署在同一容器内,且通过本地hosts映射,均映射至同一docker  IP地址。所以,单独访问其所对应的域名时均能访问通。

                      但,当b系统去请求b-api时,却出现域名不解析的情况,导致接口数据访问不到。

             原因:

                     因为两者均部署在同一容器内,且对应同一docker IP地址,在本地hosts内均有相关域名映射。所以,单独访问时,均可访问.。如果想访问同一容器内的不同项目时,访问容器hosts时,却并没有找到相应的域名,导致访问不通。

             解决方法:

                      在容器内hosts内也添加相应的域名映射。

            此类问题也适用于PHP和nginx不在同一容器内的情况,也就是不同容器间互相访问的情况。