zoukankan      html  css  js  c++  java
  • 第3次实践作业

    Docker Compose 安装与卸载

    在 Linux 上安装docker compose十分简单,从 官方 GitHub Release 处直接下载编译好的二进制文件即可。

    $ sudo curl -L https://github.com/docker/compose/releases/download/1.26.0-rc4/docker-compose-Linux-x86_64 >> /usr/local/bin/docker-compose
    $ sudo chmod +x /usr/local/bin/docker-compose
    

    使用docker-compose --version,出现如下提示表示安装成功。

    docker-compose version 1.26.0-rc4, build d279b7a8
    

    构建LNMP服务

    docker-compose.yml文件中使用 build 指令时, Dockerfile 中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等) 将会自动被获取,无需在 docker-compose.yml 中再次设置。为了减少docker-compose.yml的篇幅,本次实验大多使用Dockerfile进行设置。

    Dockerfile编写

    Nginx

    nginx在LNMP服务中充当着web代理服务器的角色,需要通过nginx来定位需要使用的web服务。首先修改nginx的相关配置。需要注意的配置选项是rootfastcgi_passfastcgi_param,如果这些选项配置不正确,将会出现一系列的not found问题。

        ...
        server {
            listen       80;
            server_name  localhost;
    		...
            location / {
                root   /usr/share/nginx/myhtml;
                index  index.html index.htm;
            }
    		...
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            location ~ .php$ {
               root           /var/www/myphp;
               fastcgi_pass   myphp:9000;	# 容器名:端口号
               fastcgi_index  index.php;
               fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
               include        fastcgi_params;
            }
        ...
    

    Dockerfile配置比较简单,代码如下所示:

    FROM nginx
    COPY nginx.conf /etc/nginx/nginx.conf
    RUN mkdir /usr/share/nginx/myhtml
    EXPOSE 80
    

    MySQL

    MySQL在LNMP服务中充当数据库的角色,根本职责就是存储结构化数据。在MySQL容器启动过程中,建立了一个数据库、一个基本表并往基本表加入一个元组的数据,以用于查看MySQL是否初始化正确。

    Dockerfile完整代码如下:

    FROM mysql
    ENV MYSQL_ROOT_PASSWORD=123456  
            MYSQL_ALLOW_EMPTY_PASSWORD=no 
            MYSQL_DATABASE=mydb
    COPY mytable.sql /docker-entrypoint-initdb.d
    EXPOSE 3306
    

    创建基本表以及插入数据的sql语句如下:

    use mydb;
    create table student(
        id int(4) not null primary key,
        name varchar(16) not null
    )DEFAULT CHARSET=latin1;
    INSERT INTO student VALUES (1, 'My LNMP-MySQL.');
    

    PHP

    PHP在LNMP服务中充当的是对数据库进行操作的角色,因为需要连接MySQL,所以需要安装PHP Core Extensions以及pdo扩展。在阅读PHP Docker Official Images中的

    并加以适当修改,可以得到如下完整的Dockerfile代码:

    FROM php:7.4-fpm
    COPY sources.list /etc/apt		# 更改镜像源
    RUN apt-get update && apt-get install -y 
            libfreetype6-dev 
            libjpeg62-turbo-dev 
            libpng-dev 
        && docker-php-ext-configure gd --with-freetype --with-jpeg 
        && docker-php-ext-install -j$(nproc) gd 
        && docker-php-ext-install pdo pdo_mysql # 安装pdo
    ENV MYSQL_ROOT_PASSWORD=123456
    

    docker-php-ext-install pdo pdo_mysql添加了连接MySQL相关的组件,MYSQL_ROOT_PASSWORD=123456环境变量方便PHP连接到MySQL。

    使用Compose实现多容器运行机制

    docker-compose.yml

    docker-compose.yml文件时docker-compose的关键文件,它通过yml文件获知需要部署的应用的整体框架以及相关细节。

    version: "3"
    services:
      web:
        container_name: myweb
        build: ./myNginx
        ports:
          - "80:80"
        volumes:
          - /var/lib/myLNMP/nginx:/usr/share/nginx/myhtml
      db:
        container_name: mydb
        build: ./myMySQL
        ports:
          - "3306:3306"
        volumes:
          - /var/lib/myLNMP/mysql:/var/lib/mysql
      php:
        container_name: myphp
        build: ./myPHP
        volumes:
          - /var/lib/myLNMP/php:/var/www/myphp
      phpmyadmin:
        container_name: myphpmyadmin
        image: phpmyadmin/phpmyadmin:latest
        ports:
        - "8080:80"
        environment:
        - PMA_ARBITRARY=1
    

    在yml文件中,container_name创建容器后的容器名;build表示使用Dockerfile定制镜像,它后面跟上Dockerfile文件所在的目录,默认的上下文路径与Dockerfile文件所在目录相同;ports表示端口映射;volumes表示将容器内的文件目录持久化到本地目录,可以使用该方法避免每一次开启容器后,数据重新初始化导致数据丢失;image表示镜像来源;environment表示设置环境变量。

    在该实验中,phpmyadmin容器可以直接使用原生镜像,而不需要使用Dockerfile进行定制。

    整个应用项目所需文件并不多,使用tree -L命令可以很清楚地看到文件目录。

    做好上述的准备工作后,就可以在docker-compose.yml文件所在的目录中,使用docker-compose up命令进行项目部署。

    看到一连串的done之后,项目就部署成功了。

    将nginx的主页index.html放到root所在的持久化目录(上文中的/var/lib/myLNMP/nginx)下,并在浏览器上,登录http://hostname/就能看到nginx的主页。index.html的内容是<h1>My LNMP-Nginx.</h1>

    使用navicat登录MySQL,并查看相关初始化。

    在navicat中可以看到,相关数据库、基本表均初始化正确。

    将PHP的主页index.php放到root所在的持久化目录(上文的/var/lib/myLNMP/php)下,就能够访问了。index.php的内容是<?php phpinfo();?>

    下滑,可以看到pdo相关组件安装成功。

    以上,LNMP服务成功部署,接下来通过PHP对MySQL进行测试。

    服务测试

    连接测试

    首先,使用PHP对MySQL进行连接测试。在PHP的root持久化目录中新建一个connect2DB.php,并向其中输入如下代码:

    <?php
    $servername = "mydb"; // 上述的数据库容器名
    $username = "root";
    $password = $_ENV["MYSQL_ROOT_PASSWORD"];
     
    try {
        $conn = new PDO("mysql:host=$servername;", $username, $password);
        echo "连接成功"; 
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
    ?>
    

    在浏览器中,通过URL的方式,访问该web服务。出现连接成功,即表示PHP与MySQL无障碍通信。

    同样,在PHP的持久化目录下,新建一个PHP2DB.php文件,并输入如下代码:

    <?php
    $servername = "mydb"; // 上述的数据库容器名
    $username = "root";
    $password = $_ENV["MYSQL_ROOT_PASSWORD"];
     
    try {
        $conn = new PDO("mysql:host=$servername;", $username, $password);
        echo "连接成功"; 
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
    //创建数据库和基本表
    $conn->exec("create database if not exists phpdb;");
    echo "数据库创建成功!<br>";
    $conn->exec("use phpdb;");
    $conn->exec("create table if not exists student(
        id int(4) not null primary key,
        name varchar(16) not null
    )DEFAULT CHARSET=latin1;");
       echo "表格创建成功!<br>";
    //插入数据
        $conn->exec("INSERT INTO student VALUES (1, 'Insert By PHP');");
        echo "记录插入成功!<br>";
    ?>
    

    得到如下反馈:

    使用phpMyAdmin组件可以查看相关数据。

    可以看到,数据库创建、基本表创建、数据插入操作均成功。创建changedViaPHP.php,并输入如下代码:

    <?php
    $servername = "mydb"; // 上述的数据库容器名
    $username = "root";
    $password = $_ENV["MYSQL_ROOT_PASSWORD"];
     
    try {
        $conn = new PDO("mysql:host=$servername;", $username, $password);
        echo "连接成功<br>"; 
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
    //修改数据
    $conn->exec("use phpdb;");
    $conn->exec("update student set name='Changed By PHP' where id = 1;");
        echo "修改成功<br>";
    ?>
    

    同样通过URL访问web服务,可得如下现象:

    并使用phpMyAdmin验证:

    创建deleteByPhp.php,并输入如下代码:

    <?php
    $servername = "mydb"; // 上述的数据库容器名
    $username = "root";
    $password = $_ENV["MYSQL_ROOT_PASSWORD"];
     
    try {
        $conn = new PDO("mysql:host=$servername;", $username, $password);
        echo "连接成功<br>"; 
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
    //修改数据
    $conn->exec("use phpdb;");
    $conn->exec("delete from student where id = 1;");
        echo "删除成功<br>";
    ?>
    

    执行,并在phpMyAdmin中查看:

    至此,本次实验成功完成。

    问题

    1、第一次写docker-compose.yml并部署时,出现如下错误。根据提示可知,yml文件扫描错误,容易推断出是语法错误。

    root@docker01:/usr/local/myLNMP# docker-compose up
    ERROR: yaml.scanner.ScannerError: mapping values are not allowed here
      in "./docker-compose.yml", line 2, column 9
    

    文章指出,在编写docker-compose.yml时,要求每个冒号和每个-符号后面必须有一个空格。

    2、使用docker-compose up命令部署项目时,定制PHP出现总是下载不了的情况。卡在Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7907 kB]动不了。

    在PHP的Dockerfile中添加COPY sources.list /etc/apt,并在上下文中添加sources.list以更改软件源后,才能成功解决。

    sources.list的内容如下:

    # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
    deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
    deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
    deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
    deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
    

    3、在使用docker-compose up命令部署项目的最后,出现了如下问题:

    根据Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use可知,端口已占用。这才想起Ubuntu中的本地MySQL服务仍开启中,使用service mysql stop将它关闭后,就能正确部署了。

    4、使用nginx服务器访问php业务时,出现SQLSTATE[HY00O] [2002] No such file or directory错误。

    出现这个问题主要是nginx的配置文件错误,注释的地方出错的关键。

        ...
        server {
            listen       80;
            server_name  localhost;
    		...
            location / {
                root   /usr/share/nginx/myhtml;
                index  index.html index.htm;
            }
    		...
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            location ~ .php$ {
               root           /var/www/myphp;
               fastcgi_pass   myphp:9000;	
               # 容器名:端口号,原句为127.0.0.1,修改的原因是容器ip并非127.0.0.1
               fastcgi_index  index.php;
               fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
               # 原句为 fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
               include        fastcgi_params;
            }
        ...
    

    时间开销

    事项 耗时(小时)
    了解docker-compose 3
    编写Dockerfile和docker-compose.yml 1
    因网络问题部署失败 2
    nginx与php连接排错 0.5
    记录过程 2.5
    总耗时 9

    感想

    感受到了docker虚拟化技术的强大,部署项目时足够的快速,比之前在物理机上效率高得多;遇到的问题就当是经验的积累吧。

  • 相关阅读:
    durex-word
    闲聊可穿戴设备
    闲聊质数
    一步一步学swift之:自己写Api接口-PHP
    Swift实战-小QQ(第2章):QQ侧滑菜单
    Swift实战-小QQ(第1章):QQ登录界面
    一步一步学习Swift之(一):关于swift与开发环境配置
    objective-c底层: runtime机制
    手把手教你视频直播开发
    多语言本地化开发Localized
  • 原文地址:https://www.cnblogs.com/auspiciousjimmy/p/12827478.html
Copyright © 2011-2022 走看看