• 第3次实践作业


    (1)完成Docker-compose的安装

    运行一下命令即可安装

    sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    

    然后为文件添加可执行权限

    sudo chmod +x /usr/local/bin/docker-compose
    

    创建软链

    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    

    查看是否安装成功

    docker-compose --version
    

    (2)Dockerfile编写

    为了保证结构的清晰明了,先创建各自的文件夹和文件,如下图所示相继创建

    创建结束后文件结构如图所示

    接下来为这些文件进行配置

    1.html文件夹下的文件

    ① index.html

    <h1> hello nginx </h1>
    

    只是简单的html代码,显示hello nginx

    ② index.php

    <?php phpinfo();?>
    
    • 标准的php代码标签是
    • phpinfo()函数会输出关于 PHP 配置的信息

    2.mysql文件夹下的文件

    ① Dockerfile

    具体解释已有注释

    #基础镜像
    FROM mysql:5.7
    
    #镜像作者
    MAINTAINER zzq031702223
    
    #设置不允许免密登录并设置root密码
    ENV MYSQL_ALLOW_EMPTY_PASSWORD no
    ENV MYSQL_ROOT_PASSWORD=123456
    

    ② data文件夹不用配置,他是挂载的目录

    3.nginx文件夹下的文件

    ① default.conf

    具体解释已有注释

    server {
        listen       2223;  #修改映射端口
        server_name  localhost;
    
        location / {
            root   /www/html; # 定义服务器的默认网站根目录位置,自动生成,注意这是容器的目录,不是主机的目录
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html; # 定义错误提示页面
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
        location ~ .php$ {		# 通过PHP脚本到127.0.0.1:9000的FastCGI服务器监听
            root           /www/html; # 定义服务器的默认网站根目录位置,自动生成
            fastcgi_pass   php:9000; # 修改php服务器端口
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;# 修改为$document_root
            include        fastcgi_params;
        }
    }
    

    ② Dockerfile

    具体解释已有注释

    #基础镜像
    FROM nginx:latest
    
    #镜像作者
    MAINTAINER zzq031702223
    
    #暴露端口
    EXPOSE 2223
    

    4.php文件夹下的文件

    ① Dockerfile

    其中更换镜像源是为了加快下载速度(没加这个之前一直报错)。

    • 在php文件夹下添加sources.list即可
    # 基础镜像
    FROM php:7.4-fpm
    
    # 更改镜像源
    COPY sources.list /etc/apt		
    
    # 镜像作者
    MAINTAINER zzq031702223
    
    RUN apt-get update && apt-get install -y 
            libfreetype6-dev 
            libjpeg62-turbo-dev 
            libpng-dev 
        && docker-php-ext-install pdo_mysql 
        && docker-php-ext-configure gd --with-freetype --with-jpeg 
        && docker-php-ext-install -j$(nproc) gd
    

    ② sources.list

    文件包含内容如下

    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)使用Compose实现多容器运行机制

    1.docker-compose.yml的编写

    version: "3"
    services:
        # nginx服务
        nginx:
            image: nginx_image  # 镜像名
            container_name: nginx_container  # 容器名
            build: ./nginx
            ports:
                - "80:2223"     # 暴露端口
            volumes:
                - ./html:/www/html   # 将主机当前目录的上级html目录,挂载到容器的/zzq/html目录
                - ./nginx/default.conf:/etc/nginx/conf.d/default.conf # 同上
    
        # php服务
        php:
            image: php_image 
            container_name: php_container 
            build: ./php       
            environment:
                MYSQL_PASSWORD: 123456      
            volumes:
                - ./html:/www/html
    
        # mysql服务
        mysql:
            image: mysql_image 
            container_name: mysql_container
            build: ./mysql
            ports:
                - "3306:3306"
            volumes:
                - ./mysql/data:/var/lib/mysql
    
    • 值得注意的是,yml严格遵从语法规则,文本中不允许出现制表符‘ '

    2.运行docker-compose

    sudo docker-compose up -d --build
    

    3.查看容器现状

    使用如下命令后,可以看见三个容器处于正常运行状态

    sudo docker ps -a
    

    (4)服务测试

    1.先查看index.html和index.php能否进行访问

    ① index.html

    访问 http://localhost/index.html

    ② index.php

    访问 http://localhost/index.php

    2.数据库测试

    ① 数据库的连接

    修改index.php文件如下

    <?php
    $servername = "mysql";
    $username = "root";
    $password = "123456";
     
    try {
        $conn = new PDO("mysql:host=$servername;", $username, $password);
        echo "连接成功"; 
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
    ?>
    

    访问 http://localhost/index.php进行更新查看

    ② 数据库的创建

    修改index.php文件如下

    <?php 
    $servername = "mysql"; 
    $username = "root"; 
    $password = "123456"; 
    
    try { 
        $conn = new PDO("mysql:host=$servername", $username, $password); 
    
        // 设置 PDO 错误模式为异常 
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
        $sql = "CREATE DATABASE dockerComposeDB"; //修改数据库名
    
        // 使用 exec() ,因为没有结果返回 
        $conn->exec($sql); 
    
        echo "数据库创建成功<br>"; 
    } 
    catch(PDOException $e) 
    { 
        echo $sql . "<br>" . $e->getMessage(); 
    } 
    
    $conn = null; 
    ?>
    

    访问 http://localhost/index.php进行更新查看

    进入容器查看数据库,以验证其正确性

    ③ 数据库建表

    修改index.php文件如下

    <?php
    $servername = "mysql";
    $username = "root";
    $password = "123456";
    $dbname="dockerComposeDB";       
     
    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);    #选择数据库
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        // 使用 sql 创建数据表
        $sql = "CREATE TABLE student_list(
            id int(4) not null primary key,
            name varchar(16) not null
        )";
        // 使用 exec() ,没有结果返回 
        $conn->exec($sql);
        echo "数据表 student_list 创建成功";
    }
    catch(PDOException $e)
    {
        echo $sql . "<br>" . $e->getMessage();
    }
     
    $conn = null;
    ?>
    

    访问 http://localhost/index.php进行更新查看

    ④ 插入数据

    修改index.php文件如下

    <?php
    $servername = "mysql";
    $username = "root";
    $password = "123456";
    $dbname="dockerComposeDB";       
     
    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
        // 设置 PDO 错误模式,用于抛出异常
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
         //开始事务
        $conn->beginTransaction();
        $conn->exec("INSERT INTO student_list (id,name)
        VALUES ('1','Tom')");
        $conn->exec("INSERT INTO student_list (id,name)
        VALUES ('2','Jack')");
        $conn->exec("INSERT INTO student_list (id,name)
        VALUES ('3','Pony')");
    
        // 提交事务
        $conn->commit();
        echo "插入数据成功";
    }
    catch(PDOException $e)
    {
        $conn->rollback();
        echo $sql . "<br>" . $e->getMessage();
    }
     
    $conn = null;
    ?>
    

    访问 http://localhost/index.php进行更新查看


    ⑤ 修改数据

    修改index.php文件如下

    <?php
    $servername = "mysql";
    $username = "root";
    $password = "123456";
    $dbname="dockerComposeDB";       
     
    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
        // 设置 PDO 错误模式,用于抛出异常
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
         //开始事务
        $conn->beginTransaction();
        $conn->exec("UPDATE student_list SET id='11' WHERE name='Tom'"); 
        // 提交事务
        $conn->commit();
        echo "修改数据成功";
    }
    catch(PDOException $e)
    {
        $conn->rollback();
        echo $sql . "<br>" . $e->getMessage();
    }
     
    $conn = null;
    ?>
    

    访问 http://localhost/index.php进行更新查看


    ⑥ 删除数据

    修改index.php文件如下

    <?php
    $servername = "mysql";
    $username = "root";
    $password = "123456";
    $dbname="dockerComposeDB";       
     
    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
        // 设置 PDO 错误模式,用于抛出异常
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
         //开始事务
        $conn->beginTransaction();
        $conn->exec("DELETE FROM student_list WHERE id='11'"); 
        // 提交事务
        $conn->commit();
        echo "删除数据成功";
    }
    catch(PDOException $e)
    {
        $conn->rollback();
        echo $sql . "<br>" . $e->getMessage();
    }
     
    $conn = null;
    ?>
    

    访问 http://localhost/index.php进行更新查看


    (5)选做

    1.编写相关文件

    ① Dockerfile文件

    #基础镜像
    FROM phpmyadmin/phpmyadmin            
    #维护者信息
    MAINTAINER zzq031702223
    #暴露端口
    EXPOSE 8080
    

    ② 在docker-compose.yml的基础上添加相关配置

    phpmyadmin:
        image: phpmyadmin_image
        container_name: myphpmyadmin_container
        build: ./phpmyadmin
        ports: 
            - "8080:80" 
        environment:
        PMA_HOST: mysql       
    

    2.重新运行docker-compose

    ① 先停止之前运行的docker-compose

    docker-compose down
    

    ② 运行docker-compose

    ocker-compose up -d --build
    

    3.数据库测试

    ① 先访问 localhost:8080 查看是否连接成功

    ② 登录并查看数据库提供的功能(建数据库)

    ③ 查看表

    ④ 插入数据


    ⑤ 更新数据

    ⑥ 删除数据

    (6)实验总结

      这次实验配置的文件很多,在实验过程中很容易出现错误,并且!,你根本不知道错在哪。。。
    其实主要还是对知识的匮乏,不懂每个文件的具体作用,每个文件里面各行代码又是如何工作等等问题。也因为这门课内容的前沿,有些错误无法得到解答,所以实验过程还是艰难的。
      由于不是很了解其中的玄妙,我尝试了使用类似访问nginx或mysql的方法来访问php,经过几个小时的磨炼,暴露nginx、mysql、php端口后,只有nginx和mysql可以被访问,而php文件始终访问失败。最终也放弃了这个想法。

      大概花了八个小时才完成这次实验,挺累的。。。

      继上个实验提出的问题,这次实验并没有得到解答,所以我在网上找了资料,大概了解了一些。

    Linux文件系统由bootfs和rootfs两部分组成

    • bootfs:包含bootloader(引导加载程序)和 kernel(内核)
    • rootfs: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件
    • 不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等

    故而Docker镜像有如下原理

    • Docker镜像是由特殊的文件系统叠加而成
    • 最底端是 bootfs,并使用宿主机的bootfs
    • 第二层是 root文件系统rootfs,称为base image
    • 然后再往上可以叠加其他的镜像文件
    • 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
    • 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
    • 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器

    由这些知识理论,可以解答那两个问题

    • Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?

      • Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
    • Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?

      • 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB
  • 相关阅读:
    [MacOS]修改Wifi默认共享网段
    [CentOS7]升级OpenSSL至1.1.1
    [Linux]checking for libevent support... configure: error: Unable to use libevent (libevent check failed)
    [CentOS7]team模式切换
    HDU 5416 CBR and tree
    CodeForces 374D Inna and Sequence
    HDU 5981 Guess the number
    题目清单
    HDU 5510 Bazinga
    KMP & AC自动机
  • 原文地址:https://www.cnblogs.com/zzqsss/p/12829520.html
Copyright © 2020-2023  润新知