系统综合实践 第3次实践作业——学习使用Docker Compose
(一)完成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
(二)Dockerfile编写
要求:
LNMP/LAMP选择一种;
分别构建web、php应用、数据库等镜像服务,php镜像亦有提供php:
提示:php连接数据库需要安装必要的核心扩展部件(PHP Core Extensions)安装方法可参考官方镜像介绍。
- 目录结构
先展示一下目录结构,如图是做完实验后的目录结构,其中我画红色下划线部分是要自己配置的,其中data文件只要建立一个文件夹就好了,里面的文件是做完实验后自己生成的。
然后phpyadmin文件夹内是选做部分需要配置的dockerfile文件,具体文件内容会在下面选做部分写出,建议一开始就写好,这样后面选做部分做起来很快。
- mysql
FROM mysql:5.7
#基础镜像
MAINTAINER yezi
#镜像作者
ENV MYSQL_ALLOW_EMPTY_PASSWORD no
ENV MYSQL_ROOT_PASSWORD=123456
#不允许空密码登陆,设置初始密码
- php
FROM php:7.4-fpm
#基础镜像
MAINTAINER yezi
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
- index.php
<?php phpinfo();?>
- index.html
这个可以看心情随便写内容 - nginx
FROM nginx
#基础镜像
MAINTAINER yezi
#维护者
EXPOSE 2208
#映射端口
- negix配置文件default.conf
server {
listen 2208; #修改映射端口
server_name localhost;
location / {
root /www/web; #修改nginx工作目录
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
root /www/web; # php容器web文件代码目录
fastcgi_pass php:9000; # 修改php服务器端口
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;# 修改为$document_root
include fastcgi_params;
}
}
(三)使用Compose实现多容器运行机制
编写compose文件,完成上述LNMP/LAMP的微服务组合部署。
- docker-compose.yml
version: "3"
services:
#nginx服务
nginx:
image: nginx_image #镜像名
container_name: nginx_container #容器名
build: ./nginx
ports:
- "80:2208" #暴露端口
volumes:
- ./web:/www/web #磁盘映射,后者与default.conf中定义的一致
- ./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:
- ./web:/www/web
#mysql服务
mysql:
image: mysql_image
container_name: mysql_container
build: ./mysql
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
- 运行docker-compose
sudo docker-compose up -d --build
- 查看镜像
sudo docker images
- 查看容器
sudo docker ps -a
- 访问http://localhost/index.html
- 访问http://localhost/index.php
(四)服务测试
要求和提示:
包括但不限于测试数据库连接、数据库新建、表新建、表记录的插入修改和删除是否成功(pdo或mysqli均可);
参考:PHP连接MySQL
- 测试数据库连接
修改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看到反馈信息
- 新建数据库docker-compose-DB
<?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;
?>
可以登录数据库查看数据库信息
- 新建表
建立foods_list表,包含属性订单号id、食物名name,食物价格price
<?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 foods_list(
id INT(8) UNSIGNED PRIMARY KEY,
name VARCHAR(30) NOT NULL,
price DOUBLE(30) NOT NULL
)";
// 使用 exec() ,没有结果返回
$conn->exec($sql);
echo "数据表 foods_list 创建成功";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
这里foodslist是之前建成但是忘记修改echo信息了,所以又建了一个
- 插入数据
<?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 foods_list (id,name, price)
VALUES ('1','egg','2')");
$conn->exec("INSERT INTO foods_list (id,name, price)
VALUES ('2','potato', '3')");
$conn->exec("INSERT INTO foods_list (id,name, price)
VALUES ('3','salad', '6')");
// 提交事务
$conn->commit();
echo "插入数据成功";
}
catch(PDOException $e)
{
$conn->rollback();
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
- 修改数据
修改数据和删除数据只需修改替换index.php中的事务内容
$conn->exec("UPDATE foods_list SET price='8' WHERE name='salad'");
这里本来以为http://localhost/index.php只用于看反馈信息就没有刷新,直接查数据库后发现数据没有变化,不知道是不是有一定时延,但是刷新网站后就可以看到变化了。
- 删除数据
$conn->exec("DELETE FROM foods_list WHERE id='1'");
(五)实验选做
增加一个phpmyadmin容器,实现web端的数据库管理。
- 编写Dockerfile文件
#基础镜像
FROM phpmyadmin/phpmyadmin
#维护者信息
MAINTAINER yezi
#暴露端口
EXPOSE 8080
- 编辑yml文件
在docker-compose.yml加入
phpmyadmin:
image: phpmyadmin_image
container_name: myphpmyadmin_container
build: ./phpmyadmin
ports:
- "8080:80"
environment:
PMA_HOST: mysql
- 重新启动docker-compose
移除之前运行的docker-compose再建(如果在之前就已经写好phpmyadmin相关dockfile和yml文件则无需这一步)
docker-compose down
ocker-compose up -d --build
- 访问网址localhost:8080
用root用户和yml中设置密码登录
登录成功
- 数据库操作
查看表
更新表
将name=“egg”的价格price改为“3”
删除数据
看到id=2的行已删除
实验完成
(六)错误及解决方案
- 1.忘记pull php
实现多容器运行时,bulid之后,执行到php服务一直出错。
看了很多前面交作业的大佬的php的dockerfile文档,发现竟然什么样的都有,一个个尝试都不行后直到看到,要pull php镜像才想到其余镜像都已经pull过了所以忘记拉取php镜像了
2.无法建表
原因在于,order是mysql的关键字,之前把表名取为order了
这个是在http://localhost/index.php看到反馈的信息
- 3.重新构建docker-compose失败
因为做附加实验要在yml文件中添加内容,就docker-compose down移除了之前运行的,然后重新运行出现如下错误
解决方案:在shell下删除data文件夹就好了
- 4.使用phpmyadmin容器web端无法建表
解决方案:未解决
(七)实验心得
这次实验内容不难,主要是要配置的文件有点多,文件中要修改的地方要与yml文件中对应,然后就还是以前那样,了解怎么做、做什么,花的时间比实验本身多。
实验共耗时9小时45分,实验与文档同步,大概做文档耗时两个小时。最后附加实验做了1个半小时左右因为是down了之前的再运行的然后数据库没了,本来想直接在那个网站线上建的,但是建表的时候一直有问题,看了别人的攻略好像要填的都填了,不知道哪里有问题,最后还是在index.php文档中完成建数据库建表再在网站上完成数据更新等操作的。