第3次实践作业
(1)完成Docker-compose的安装
①curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
下载docker-compose最新版本
②chmod +x /usr/local/bin/docker-compose
给文件添加执行权限,ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
创建软连接至一个PATH目录下,一般为/usr/bin
③docker-compose --version
出现版本号表示安装成功
(2)Dockerfile编写(LNMP)
①创建项目文件夹: touch docker-compose.yml dockerfile_mysql dockerfile_nginx dockerfile_php default.conf && mkdir mysql_data web && tree
,其中default.conf为nginx的默认配置文件,mysql_data用来挂载mysql目录,web用来挂载nginx和php的目录
②拉取需要的镜像
-
mysql:
docker pull mysql
-
php:
docker pull php:7.4-fpm
-
nginx:
docker pull nginx
③编辑配置文件
-
dockerfile_mysql
#基础镜像 FROM mysql #作者信息 MAINTAINER Dicky #设置root密码 ENV MYSQL_ROOT_PASSWORD admin #禁止空密码登录 ENV MYSQL_ALLOW_EMPTY_PASSWORD no
-
dockerfile_php
#基础镜像 FROM php:7.4-fpm #作者信息 MAINTAINER Dicky 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
-
dockerfile_nginx
#基础镜像 FROM nginx #作者信息 MAINTAINER Dicky #声明暴露的端口 EXPOSE 80
-
default.conf
server { listen 80; #修改映射端口 server_name localhost; location / { root /web/html; #修改工作目录 index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ \.php$ { root /web/php; #修改工作目录 fastcgi_pass myphp:9000; #修改为容器名 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
-
docker-compose.yml
version: "3" services: nginx: image: mynginx_image #指定镜像名 container_name: mynginx #指定容器名 build: context: . dockerfile: dockerfile_nginx #指定dockerfile文件 ports: - "8081:80" #修改端口映射 volumes: - ./web:/web/html #挂载容器卷,本地/容器内修改文件后,另一方都会同步更新; - ./default.conf:/etc/nginx/conf.d/default.conf #挂载配置文件 php: image: myphp_image container_name: myphp build: context: . dockerfile: dockerfile_php environment: MYSQL_PASSWORD: admin #设置好环境变量,在php代码中使用变量名直接引用 volumes: - ./web:/web/php #挂载工作目录到本机web目录 mysql: image: mysql_image container_name: mysql build: context: . dockerfile: dockerfile_mysql ports: - "8082:3306" volumes: - ./mysql_data:/var/lib/mysql #挂载容器卷,实现数据同步,防止数据丢失
在web目录中新建index.html和index.phpcd web && touch index.html index.php
并编辑
-
index.html
This is a lnmp page test!
-
index.php
<?php phpinfo();?>
(3)使用Compose实现多容器运行机制
①执行docker-compose文件docker-compose up -d --build
②查看容器 docker ps -a
③分别访问测试页面index.html和index.php
- index.html
- imdex.php
(4)服务测试
- 创建数据库和表格
<?php
$servername = "mysql";
$username = "root";
$password = "admin";
$dbname="myDB";
// 创建连接
try {
$conn = new PDO("mysql:host=$servername", $username, $password);
echo "数据库连接成功<br>";
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE DATABASE ". $dbname;
$conn->exec($sql);
echo "数据库创建成功<br>";
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); #建立新连接并选择数据库
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE TABLE S(
sno VARCHAR(20) PRIMARY KEY,
sname VARCHAR(20) NOT NULL,
sex VARCHAR(2) NOT NULL,
CHECK(`sex`='男' OR `sex`='女')
)";
$conn->exec($sql);
echo "表格创建成功<br>";
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$conn = null;
?>
-
向表格插入数据
<?php $servername = "mysql"; $username = "root"; $password = "admin"; $dbname="myDB"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 开始事务 $conn->beginTransaction(); // SQL 语句 $conn->exec("INSERT INTO S(sno,sname,sex) VALUES ('031700000','小明','男'), ('031700001','小红','女'), ('031700002','小张','男')"); // 提交事务 $conn->commit(); echo "数据插入成功!"; } catch(PDOException $e) { // 如果执行失败回滚 $conn->rollback(); echo $sql . "<br>" . $e->getMessage(); } $conn = null; ?>
-
查询表格数据
<?php echo "<table style='border: solid 1px black;'>"; echo "<tr><th>Id</th><th>Firstname</th><th>Lastname</th></tr>"; class TableRows extends RecursiveIteratorIterator { function __construct($it) { parent::__construct($it, self::LEAVES_ONLY); } function current() { return "<td style='width:150px;border:1px solid black;'>" . parent::current(). "</td>"; } function beginChildren() { echo "<tr>"; } function endChildren() { echo "</tr>" . "\n"; } } $servername = "mysql"; $username = "root"; $password = "admin"; $dbname = "myDB"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("SELECT sno, sname, sex FROM S"); $stmt->execute(); // 设置结果集为关联数组 $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) { echo $v; } } catch(PDOException $e) { echo "Error: " . $e->getMessage(); } $conn = null; echo "</table>"; ?>
-
删除姓名为小明的数据
<?php $servername = "mysql"; $username = "root"; $password = "admin"; $dbname="myDB"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 开始事务 $conn->beginTransaction(); // SQL DELETE语句 $conn->exec("DELETE FROM S where sname='小明'"); // 提交事务 $conn->commit(); echo "记录删除成功!"; } catch(PDOException $e) { // 如果执行失败回滚 $conn->rollback(); echo $sql . "<br>" . $e->getMessage(); } $conn = null; ?>
(5)增加一个phpmyadmin容器,实现web端的数据库管理
①在lnmp文件夹中创建dockerfile_phpmyadmin文件
#基础镜像
FROM phpmyadmin/phpmyadmin
#作者信息
MAINTAINER Dicky
#声明暴露的端口
EXPOSE 80
②修改docker-compose.yml,插入以下代码
phpmyadmin:
image: myphpadmin_image
container_name: myphpmyadmin
build:
context: .
dockerfile: dockerfile_phpmyadmin
ports:
- "8080:80" # phpmyadmin默认监听80
environment:
PMA_HOST: mysql #指定mysql服务所在的host
③再次执行docker-compose up -d --build
命令
④访问phpmyadmin网页
登陆后即可查到数据库内容
(6)实验总结
-
提交可以运行的yml文件和相关的Dockerfile文件、配置文件
-
实验小结:
- 在端口映射时,尽量不占用宿主机使用中的端口,否则可能造成宿主机的端口无法正常使用。
-
实验耗费时间:
- 下午+晚上 ,大约6小时