系统综合实践第三次实践
1、先安装docker-compose,安装后验证
2、编写框架环境中的Dockerfile
编写依照上节课的内容,但由于这次目的在于实现框架的连接搭建,所以并不用在用在Dockerfile上写太多特制。
FROM mysql #MAINTAINER IFORMATION MAINTAINER jayer@xiajibaxie.com
FROM nginx #MAINTAINER IFORMATION MAINTAINER jayer@xiajibaxie.com
FROM php:7.4-fpm #MAINTAINER IFORMATION MAINTAINER jayer@xiajibaxie.com
#Configure PHP Core Extensions 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
文件目录
不明白为何挂载mysql下的data的时候多出那么多文件
配置文件
index.php——执行PHP脚本指令的文件
index.html——网页文件
default.conf——nginx下的配置文件,需要进行配置来连接nginx和php。
server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/nginx-2/html; index index.html index.htm index.php; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { root /usr/nginx-2/php; #php容器下的工作路径 fastcgi_pass lnmp_php-container:9000; #container name fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }
其中重点在于加入location ~ \.php${}的匹配信息(大致了解就是nginx在匹配路径文件时,如果后缀是php文件,即向容器端口去发送请求,从而得到运行php容器中相应路径下的index.php文件)
同时了解PHP的也应该知道,该脚本语言与HTML是兼容的。
前面3个root、fastcgi_pass、fastcgi_index容易理解,后面两个就不明白为啥了(直接写上就完事)
3、使用docker-compose.yml——可以创建相互依赖的镜像容器,从而搭建成可互通的框架。
version: "3" services: nginx: image: lnmp_nginx container_name: lnmp_nginx-container build: ./nginx ports: - "80:80" links: - "php" volumes: - ./nginx/html/:/usr/nginx-2/html/ - ./nginx/default.conf:/etc/nginx/conf.d/default.conf php: image: lnmp_php container_name: lnmp_php-container build: ./php ports: - "9000:9000" volumes: - ./php/phpfile/:/usr/nginx-2/php/ links: - "mysql" stdin_open: true tty: true mysql: image: lnmp_mysql container_name: lnmp_mysql-container build: ./mysql ports: - "3306:3306" volumes: - ./mysql/data/:/var/lib/mysql/ environment: MYSQL_ROOT_PASSWORD : 123
这里用到的几个基本的就是,image和container_name定义镜像名与容器名,build相对路径下寻找Dockerfile定制镜像,ports端口映射。
volumes挂载数据卷或环境(稍微了解一下就是将主机的某个文件或路径补充到容器下的文件路径之后,所体现就是形成同一文件环境,主机内修改文件信息可永久性反馈到容器内)
...
构建成功
4、服务测试
—nginx与php
<?php phpinfo();?>
说明端口访问PHP环境成功
——数据库连接、建库、建表、输入、删除
搭建完之后PHP没有mysqli,有pdo但不支持mysql,于是就去安装一下呗
写index.php执行php文件,这里直接套用菜鸟教程上的代码
<?php $servername = "lnmp_mysql-container"; $username = "root"; $password = "123"; // 创建连接 $conn = new mysqli($servername, $username, $password); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } echo "连接成功"; // 创建数据库 $sql = "CREATE DATABASE myDB"; if ($conn->query($sql) === TRUE) { echo "数据库创建成功"; } else { echo "Error creating database: " . $conn->error; } // 使用 sql 创建数据表 $sql = "CREATE TABLE MyGuests ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL, email VARCHAR(50), reg_date TIMESTAMP )"; if ($conn->query($sql) === TRUE) { echo "Table MyGuests created successfully"; } else { echo "创建数据表错误: " . $conn->error; } //插入数据 $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')"; if ($conn->query($sql) === TRUE) { echo "新记录插入成功"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } ?>
结果: 忘记还有dbname变量来选中数据库,略微尴尬。
改:
<?php $servername = "lnmp_mysql-container"; $username = "root"; $password = "123"; $dbname = "myDB"; // 创建链接 $conn = new mysqli($servername, $username, $password, $dbname); // 检查链接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // 使用 sql 创建数据表 $sql = "CREATE TABLE MyGuests ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL, email VARCHAR(50), reg_date TIMESTAMP )"; if ($conn->query($sql) === TRUE) { echo "Table MyGuests created successfully\n"; } else { echo "创建数据表错误: " . $conn->error; } //插入数据 $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com');"; $sql .= "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('Mary', 'Moe', 'mary@example.com');"; $sql .= "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('Julie', 'Dooley', 'julie@example.com')"; if ($conn->multi_query($sql) === TRUE) { echo "新记录插入成功\n"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } ?>
进入mysql容器查看结果
查看数据:
$sql = "SELECT id, firstname, lastname FROM MyGuests"; $result = $conn->query($sql); if ($result->num_rows > 0) { // 输出数据 while($row = $result->fetch_assoc()) { echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "<br>"; } } else { echo "0 结果"; }
删除数据:
mysqli_query($conn,"DELETE FROM MyGuests WHERE LastName='Dooley'");
5、phpmyadmin容器
通过docker-compose连接一个phpmyadmin容器,在docker-compose.yml末尾添上如下代码,执行docker-compose up -d;
phpmyadmin: image: lnmp_pmadmin container_name: lnmp_pmadmin-container build: ./phpmyadmin ports: - "9090:80" links: - "mysql" environment: - PMA_ARBITRARY=1
web端口进入phpmyadmin
有图形操作界面就感觉很可以。
六、实验感悟
这次实验的学习时长,比封建主义还保守地算,说20多个小时都不过分。
可能是因为对实践的许多经验与敏感度不足吧,没有规范的操作手册或学习教程,学习这种比较新的技术对我来说相对是吃力,如果说是尽可能明白每一个细节而不是单纯照搬别人的过程的话。
毕竟微服务框架在当下还是非常热潮与实际的,尽可能学会每个细节应该是有必要的。
遇到困难还是很多的:
换源没换好导致compose安装包的很长等一些小挫折就不说了(其实如果只是pull镜像或Dockerfile我的官方源网速是够用的),最后还是得换(第一次还没换好?就说为啥get那边还是debian啥啥啥的)
——
有一个坑,php连接nginx要在网站上体现出来phpinfo()函数所得到的php配置信息,这个东西在后面既可以建验nginx和php是否连接好,也可以查看php是否有某些配置(如PDO、Mysqli)。
然后问题就是web死活看不到php配置信息,各种检查compose配置,Dockfile配置以及种种种种,搞了4个多小时都出不来。(可能连问题的本质都没抓住)
这4个多小时翻了无数的百度和大佬标答,甚至还一度怀疑路径问题?这期间去看了所有配置的相关从location匹配到compose.yml细节,还得反复检查。
所以最后翻查log文件复制信息去百度(好像是nginx一行行的power shell还是啥的不记得了),上面说可能你需要检查一下fpm有没有,然后我发现为啥from php的tag后本来应该有“-fpm”,而我的php的Dockerfile上却漏了!一个小点点而已!
这里有个点在于,你因为对这些的很多东西一点都不了解,或者就算有接触过理论却并没有付诸实践过,所以你不得借鉴网上的教程或者大佬的标答。但你又想真正的去了解这些过程中每一个点的含义,可惜并没有一本全面的教材告诉你所有的点的含义。
——
其实更难受在连接数据库的时候,依然是nginx连接mysql就是error,各种bug疯狂涌现。
且不说安装完的php既没有PDO也没有Mysqli,没关系,安装吧,以为没问题了。severname不知道填啥,好吧本机IP或是mysql的container名都OK其实,但这混乱了重点,使得还是一度以为主机名输错了。
依旧是复制web端反馈的信息去百度,但问题不针对很多方法是不对应的,比如中途我还得进入容器去寻找my.cnf的配置文件来修改。
这里,mysql8和php不兼容的问题是个巨坑,说是mysql8.0之后字符集修改成utfmb4,导致php5.6之前的版本无法识别。而后好像7版本可以,但后来新的版本又不行(我怎么会知道?)。然而照着网上不用升级版本的方法去修改my.cnf文件依旧不行。
最后逼不得已,还是删除镜像与容器,重新compose对应的php版本。