基于Docker搭建LNPM环境

Docker

转载至我的博客

基于Docker搭建LNPM环境

​ 作为一只iOS前端工程师,最近对PHP产生了兴趣,我认为这不属于不务正业,作为一个程序员不应该把自己局限在一个封闭的领域当中,应该时刻保持好奇心,所以我对“世界上最好的语言”开始了探索~

​ 工欲善其事,必先利其器,首先就要搭建开发环境,由于本人不喜欢因为开发环境把自己的电脑搞得乱七八糟,乱安装一些有的没的依赖开发包,所以我选择虚拟机+Docker来搭建环境~

​ 下面我们开始:

Docker准备

​ 我选择了完全兼容Redhat系统的CentOS7发行版Linux系统,下载Linux并且虚拟机安装系统这里就省略了,准备好Linux系统就可以开始安装Docker了。

删除旧版本

如果以前安装过想重新安装新版本请先使用下面的命令卸载旧版本的Docker,第一次安装请直接到第二步

$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine

Docker安装设置

Docker提供两种安装方式,官方推荐使用软件仓库的方式安装Docker,方便更新等操作,另一种是以RPM的方式安装,这里不做介绍~

直接用官方推荐的方式安装,首先设置Docker的软件仓库

设置Docker的官方软件仓库

  1. 先安装Docker依赖的软件包

    $ sudo yum install -y yum-utils \
      device-mapper-persistent-data \
      lvm2
    
  2. 设置稳定版本的Docker仓库地址,Docker还提供了测试版本的地址,这里我们不需要,只要稳定版本就可以了。

    $ sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    

正式安装Docker

  1. 安装Docker的最新版本

    $ sudo yum install docker-ce
    
  2. 启动Docker服务

    $ sudo systemctl start docker
    
  3. 测试Docker是否工作正常

    $ sudo docker run hello-world
    

    如果输出了 hello world说明Docker已经安装正常了

编写Dockerfile

Dockerfile是用来制作镜像使用的一系列Docker命令的脚本文件,docker build命令会根据Dockerfile中的设置生成我们自定义的镜像。

​ 首先准备好一个目录结构如下:

testphp                                 #你自定义的一个目录名
├── html                                #用作Nginx的站点目录
│   └── phptest                         #子目录可以自定义
│       ├── index.php                   #一段简单的PHP代码,比如<?php phpinfo();?>
├── mysql                               #Mysql数据库相关的目录
│   ├── conf                            #Mysql配置文件目录
│   └── data                            #Mysql数据目录
├── nginx                               #Nginx相关目录
│   ├── conf                            #Nginx配置文件目录
│   └── logs                            #Nginx日记目录
└── php-mysqli                          #我们需要根据官方镜像生成支持mysqli的镜像,此为自定义目录
    └── Dockerfile                      #生成自定义镜像的Dockerfile

​ 在php-mysqli目录下的Dockerfile文件中,输入如下内容:

FROM php:7.2.11-fpm                     #基于PHP官方镜像7.2.11-fpm版本制作自定义镜像

RUN docker-php-ext-install mysqli       #安装PHP扩展支持mysqli

完成以后不用手动运行docker build命令生成镜像,稍后使用docker-compose自动帮我们构建镜像。

安装docker-compose

docker-composeDocker提供的用于管理多个Docekr容器的工具,Docker推荐的理念是,一个容器运行一个服务进程,这里我们搭建的环境包括,一个PHP服务进程、一个Nginx服务进程、一个phpadmin进程(用于方便的操作mysql数据库的工具)、一个mysql服务进程,总共4个,所以需要先安装docker-compose

  1. 下载docker-compose命令文件

    sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    
  2. docker-compose命令文件赋予可执行权限

    sudo chmod +x /usr/local/bin/docker-compose
    
  3. 测试安装是否正确

    $ sudo docker-compose --version
    

    如果正常输出版本号说明安装完成

编写docker-compose.yml

docker-compose命令可以根据我们编写的docker-compose.yml文件自动的管理Docker镜像。

​ 在我们自己建立的根目录下面新建一个docker-compose.yml,输入如下内容:

version: '3'                            #指定docker-compose文件的版本,低版本不支持services、
services:                               #networks等标签
  phpmyadmin:
    image: phpmyadmin/phpmyadmin        #使用的镜像
    ports:                              #端口映射
      - "8080:80"
    depends_on:                         #此服务要依赖于mysql服务
      - mysql
    links:                              #连接到mysql服务
      - mysql:db
    networks:                           #指定内部网络
      - app_net
  nginx:
    image: nginx:latest
    ports:
      - "80:80"                         #容器中的80端口映射到HOST的80端口
    depends_on:
      - "php"
    volumes:                            #指定挂载的文件或目录
      - "./nginx/conf/nginx.conf:/etc/nginx/nginx.conf"
      - "./html:/home:ro"
    networks:
      - app_net
    container_name: "compose-nginx"     #指定容器名字
  php:
    build: ./php-mysqli                 #这里指定Dockerfile的路径 会帮我们自动构建镜像
    image: php:7.2.11-fpm-mysqli        
    ports:
      - "9000:9000"
    depends_on:
      - mysql
    volumes:                            #这里的挂载目录要和nginx中的一样,否则找不到php文件
      - "./html:/home"
    networks:
      - app_net
    container_name: "compose-php"
  mysql:
    image: mysql:5.7.24                 #数据库镜像版本
    ports:
          - "3306:3306"
    volumes:
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/conf/my.cnf:/etc/mysql/my.cnf"
    environment:                        #镜像内部使用的环境变量,这里用来折纸数据库的密码
      - MYSQL_ROOT_PASSWORD=zhaofucheng
    networks:
      app_net:
        ipv4_address: 10.10.10.1        #指定内部网络中的IP地址
    container_name: "compose-mysql"
networks:
  app_net:
    driver: bridge                      #网络模式用桥接
    ipam:
      config:
        - subnet: 10.10.0.0/16          #使用CIDR方式子网划分

准备Nginx和Mysql的配置文件

​ 这里我们需要把配置文件放到我们的指定的目录中,稍后更改配置不需要进入到容器内部,也能更好的管理配置我们的服务。

​ 有两种方式准备镜像文件,一是自己从头编写,而是从镜像当中复制一个默认的再根据自己的需要去修改,这里我们选择从镜像当中复制。

Nginx配置文件

​ 准备Nginx配置文件

复制Nginx文件

  1. 启动一个临时容器

    $ sudo docker run --name tmp-nginx-container -d nginx
    
  2. 从临时nginx镜像当中复制配置文件 放到我们自己建立的nginx/conf目录中

    $ sudo docker cp tmp-nginx-container:/etc/nginx/nginx.conf ./nginx/conf/nginx.conf
    
  3. 删除建立的临时容器

    $ sudo docker rm -f tmp-nginx-container
    

编辑Nginx配置文件

编辑文件内容如下:


user  nginx;
worker_processes  2;                #根据CPU核心数量指定工作线程的数量,这里我的虚拟机为2核心

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;

    server {
        listen       80;            #监听端口
        server_name  test.ng;       #虚拟主机的名称,稍后要写入到本机的host文件当中
        root /home/phptest;         #项目php的路径

        access_log  /var/log/nginx/access.log  main;
        error_log /var/log/nginx/error.log error;

        location / {
                index  index.html index.htm index.php;
        }
                                    #配置所有访问php的请求都交给PHP: FastCGI 进程管理器处理
        location ~ \.php$ {
                fastcgi_pass   php:9000;#这里是在docker-compose.yml文件中指定的服务名和端口号
                fastcgi_index  index.php;   #默认寻找的php入口页面
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include        fastcgi_params; #网络上还有另一种方式 include fastcgi.conf; 由于要引入一个新的配置文件 这里我就嫌麻烦就使用这种方式了 根据个人喜好自己选择吧
        }
    }
}

Mysql配置文件

​ 同样复制Mysql的配置文件

  1. 启动一个临时的Mysql容器

    $ sudo docker run --name tmp-mysql-container -d mysql:5.7.24
    
  2. 从临时的Mysql容器中复制配置文件到我们指定的目录

    $ sudo docker cp tmp-mysql-container:/etc/mysql/my.cnf ./mysql/conf/my.conf
    
  3. 删除临时的Mysql容器

    $ sudo docker rm -f tmp-mysql-container
    

    这里我们使用默认的mysql配置就可以了。

查看虚拟机的IP地址加入到host文件当中

​ 在虚拟机的终端中输入:

$ ifconfig eth0                     #查看默认网卡的信息

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.31.150  netmask 255.255.255.0  broadcast 192.168.31.255
        inet6 fe80::caec:3251:7864:4814  prefixlen 64  scopeid 0x20<link>
        ether 00:1c:42:a4:5b:ef  txqueuelen 1000  (Ethernet)
        RX packets 2341561  bytes 1335991534 (1.2 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 520557  bytes 56885302 (54.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

​ 其中的inet 192.168.31.150就是我们虚拟机的IP地址,我本人的电脑是Mac系统,所以回到在我的Mac系统电脑的终端中输入:

$ sudo vim /etc/hosts

​ 将我们指定的虚拟主机名和IP地址以如下格式加入到host文件中 然后保存退出。

192.168.31.150 test.ng                  #Ngxin服务地址
192.168.31.150:8080 phpadmin.net        #用于访问PhpAdmin服务

​ 稍后我们就可以直接在浏览器中输入http://test.ng/访问Nginx测试了。

启动我们的服务

​ 回到虚拟机中,我们目前为止的文件结构如下:

testphp
├── docker-compose.yml
├── html
│   └── phptest
│       ├── index.php
│       ├── testmysql.php
├── mysql
│   ├── conf
│   │   └── my.cnf
│   └── data
├── nginx
│   ├── conf
│   │   └── nginx.conf
│   └── logs
└── php-mysqli
    └── Dockerfile

​ 编辑我们的index.php文件,输入如下内容:

<?php
phpinfo();
?>

有些人不输入<?php 而是直接写<?,导致出现错误,还得修改什么php.ini配置项,这里我建议就别给自己找麻烦,按照标准写法就可以了,别起什么幺蛾子~

编辑testmysql.php文件用来测试能否连接到Mysql数据库,输入如下内容:

<?php
  $db = new mysqli('10.10.10.1:3306','root','zhaofucheng','testdatabase');
  if (mysqli_connect_errno()) {
    echo 'Error: Could not connect to database. Please try again later.';
    exit;
  } else {
    echo 'The connection is successful.';
  }
  $db->close();
?>

​ 确保我们在自己定义的根目录中输入:

testphp]$ sudo /usr/local/bin/docker-compose up -d
testphp]$ sudo docker ps

​ 如果输入完成后可以看到四个容器都启动了,那么代表我们成功了,如果出现了错误,请回到上面仔细对照配置项,或者GoogleBaidu以及留言给我一起解决~

测试我们的服务

先在我们自己电脑的浏览器中输入地址http://test.ng/,成功页面如下图:

PHP信息

以上代表我们的NginxPHP已经配合完美了~~

再来测试phpMyAdmin是否也成功启动了,在浏览器中输入地址http://phpadmin.net访问,成功页面如下图:

phpMyAdmin登陆

​ 出现上图代表phpMyAdmin启动成功,如果输入我们配置的Mysql密码可以正常登陆,代表phpMyAdminMysql配合完美了~

这里如果登陆成功了,现在数据库中新建一个名叫testdatabase数据库,用来给我们测试PHP是否能正常连接到Mysql

现在见证奇迹的时刻到了~,在浏览器中输入http://test.ng/testmysql.php访问,如果页面显示The connection is successful.那就代表成功了~,可以尽情的玩耍了~~。

Mysql8.0更改默认密码验证方式的导致PHP连接报错的问题

我在使用Mysql8.0版本的镜像来配置时,发现PHP默认的配置不能登录到Mysql,导致连接报错,原来是Mysql8.0改了密码验证方式,如果想要正常连接,需要在Mysql数据库中把要登陆的用户密码的验证方式从caching_sha2_password改为mysql_native_password,这里就不费那个劲了,练习环境5.7版本的Mysql就可以了~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 引言 这段时候主攻云服务 服务器 CentOS 文件目录 操作 基本操作: Docker简介: 安装Docker:...
    采香行处蹙连钱阅读 1,186评论 0 1
  • 1、数字+字符串: 将数字转换为字符串 2、数字+boolean: 将boolean转换为number类型 3、数...
    喜欢暗杠阅读 127评论 0 0
  • 《西游记》中,唐僧骑的马是白龙马。不过此马非马,它是西海龙王的三太子,因为纵火烧了殿上玉帝赐的明珠,触犯天条,要被...
    青竹院阅读 1,634评论 0 0
  • 最近作为一名消费者, 因为退货的事情, 觉得厂家欺人太甚。应公司工作要求和任务的紧迫性,上个月第一次作为公司采购者...
    Kttey阅读 615评论 0 0
  • “不知道我穿裙子的模样他看到了没,很想问一问他喜欢长发垂肩温婉善良或者是是短发齐耳潇洒不羁酷酷的的女孩子。不管喜...
    我mm阅读 731评论 0 8