zhangxiaocc 2020-05-03
整体思路:利用Apache变体镜像apache:<version>-apache
及MySQL搭建LAMP环境,同时使用phpmyadmin/phpmyadmin镜像实现web数据库管理。
apache:<version>-apache
:该变体包含了Debian的Apache httpd和PHP;
phpmyadmin/phpmyadmin
:该镜像用于数据库的可视化操作,实现数据库的管理。
参考install docker-compose中docker-compose在linux上的安装,具体步骤:
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
为docker-compose添加可执行权限:docker-compose --version
,出现版本信息,说明docker-compose安装成功:apache:7.4-apache
的dockerfile文件php-apache_dockerfile
:#基础镜像 FROM php:7.4-apache #环境变量,用于登录MySQL ENV MYSQL_ROOT_PASSWORD 6666 #下载php扩展mysqli,用于对数据库进行操作 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) mysqli
ps:搁这跳了个小坑,为了下载核心扩展mysqli,在build过程中,需要先对软件源进行更新,即apt-get update
,如果使用原始软件源地址直接进行apt-get update,速度很慢或者更新失败。
分析:由于该镜像是基于Debian系统的,apt-get的软件源地址是官网地址,属于外网,造成apt-get的更新所需的部分资源获取速度比较慢,导致apt-get更新卡顿。
解决方法:想到之前在本机上对apt-get更新时也会遇到卡顿的情况,当时是用软件源镜像加速处理的,于是顺藤摸瓜,尝试着用使用镜像加速的方法去解决:首先查看该镜像的dockerfile文件发现,该镜像是基于Debian构建的,通过查阅资料找到了Debian更换软件源实现镜像加速的方法(方法如下图),在php-apache_dockerfile
RUN中加入sed -i ‘s/deb.debian.org/mirrors.ustc.edu.cn/g‘ /etc/apt/sources.list
,更换软件源。接着重新build,安装速度直接起飞,卡顿问题完美解决。
修改之后的php-apache_dockerfile
:
#基础镜像 FROM php:7.4-apache #环境变量,用于登录MySQL ENV MYSQL_ROOT_PASSWORD 6666 #下载php扩展mysqli,用于对数据库进行操作 RUN sed -i ‘s/deb.debian.org/mirrors.ustc.edu.cn/g‘ /etc/apt/sources.list && apt-get clean&& 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) mysqli
MySQL_dockerfile
:#基础镜像 FROM mysql #作者信息 MAINTAINER by lxc(https://www.cnblogs.com/lxccccc/) #设置root密码 ENV MYSQL_ROOT_PASSWORD 6666 #设置不可免密登录 ENV MYSQL_ALLOW_EMPTY_PASSWORD no #为docker_mysql创建数据库 ENV MYSQL_DATABASE docker_mysql #创建新用户 ENV MYSQL_USER=docker ENV MYSQL_PASSWORD=123456
phpmyadmin_dockerfile
:#基础镜像 FROM phpmyadmin/phpmyadmin #作者信息 MAINTAINER by lxc(https://www.cnblogs.com/lxccccc/)
docker-compose.yml
docker-compose.yml
:version: ‘3.7‘ services: #构建mysql服务 mysql: image: mysql:lxc #容器运行使用的镜像 build: context: . dockerfile: MySQL_dockerfile container_name: php_mysql #定义容器名称 ports: - "3306:3306" #映射端口,格式为 "主机端口:容器端口" #构建php变体php-apache服务 web: image: php:lxc build: context: . dockerfile: php-apache_dockerfile container_name: php-apache depends_on: #设置依赖的服务 - mysql volumes: - ./www/:/var/www/html/ #将主机中的目录挂载到容器中的工作目录,易于对web服务的管理 ports: - "8080:80" #构建phpmyadmin服务 phpmyadmin: image: phpmyadmin:lxc build: contest: . dockerfile: phpmyadmin_dockerfile environment: PMA_HOST: php_mysql #设置所连接的MySQL服务器名称 container_name: phpmyadmin depends_on: - mysql - web ports: - "8081:80"
创建文件夹www
,将web代码存放该在文件夹中,并且在docker-compose.yml中将该目录挂载到容器的工作目录下,实现数据持久化,方便对容器运行时的管理。www
主要包括两个php文件,一个是index.php
,用于验证php服务是否成功开启;另一个是mysql.php,用于实现连接操作MySQL数据库,包括数据的增删改查等基本操作。
index.php
:
<!-- ./php/index.php --> <html> <head> <title>phpinfo</title> </head> <body> <?php echo phpinfo(); #显示php信息 ?> </body> </html>
mysql.php
:
<html> <body> <head> <title>Mysql Test</title> </head> <?php $servername = "php_mysql";#这里的数据库服务器名称为MySQL容器的名称 $username = "root"; $password = $_ENV["MYSQL_ROOT_PASSWORD"]; $dbname = "mydb"; function ShowData($result){ //显示数据的函数 global $servername, $username, $password, $dbname; $conn = new mysqli($servername, $username, $password, $dbname); $sql = "select * from MyTable;"; $result = $conn->query($sql); $table = "<table border=‘1‘ cellspacing=‘0‘ width=‘200‘ height=‘50‘>"; $table .="<tr align=‘center‘><td>ID</td><td>Name</td><td>Sex</td></tr>"; // 输出数据 for($i=1;$i<=$result->num_rows;$i++){ //行 $table.="<tr align=‘center‘>"; $row = $result->fetch_assoc(); //列 $table .= "<td>" . $row[‘ID‘] ."</td>" . "<td>" . $row[‘NAME‘] ."</td>" . "<td>" . $row[‘SEX‘] ."</td>"; $table.="</tr>"; } $table.="</table>"; echo $table; } // 创建连接 $conn = new mysqli($servername, $username, $password); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error . "<br>"); } else{ echo "连接成功!<br>"; } // 创建数据库mydb $sql = "DROP DATABASE " . " IF EXISTS " . $dbname . ";create DATABASE " .$dbname; // 检测数据库是否创建成功 if ($conn->multi_query($sql)){ echo "create database " . $dbname . " successfully!<br>"; } else{ echo "failed:" . $conn->error . "<br>"; } sleep(1); // 创建连接,连接到数据库 $conn = new mysqli($servername, $username, $password,$dbname); // 建表 $sql = "CREATE TABLE MyTable( ID BIGINT(10) NOT NULL PRIMARY KEY, NAME NVARCHAR(10) NOT NULL, SEX NVARCHAR(6), CHECK (SEX=‘male‘ or SEX=‘female‘ or SEX=‘男‘ or SEX=‘女‘) )"; // 检测建表是否成功 if ($conn->query($sql) === TRUE){ echo "create table MyTable successfully!<br>"; } else{ echo "failed:" . $conn->error . "<br>"; } // 向表中插入数据 $sql = "INSERT INTO MyTable VALUES (1,‘张三‘,‘male‘);"; $sql .= "INSERT INTO MyTable VALUES (2,‘李四‘,‘男‘);"; $sql .= "INSERT INTO MyTable VALUES (3,‘小兰‘,‘female‘);"; // 检测数据是否成功插入 if ($conn->multi_query($sql)){ echo "insert data into MyTable successfully!<br>"; } else{ echo "failed:" . $conn->error . "<br>"; } sleep(1); echo "<br>查表:<br>"; ShowData($result); // 修改数据 sleep(1); echo "<br>修改数据:将李四的‘Sex‘改为‘male‘<br>"; $conn = new mysqli($servername, $username, $password, $dbname); $sql = "UPDATE MyTable SET SEX=‘male‘ WHERE NAME=‘李四‘;"; $result = $conn->query($sql); echo $result->num_rows; ShowData($result); // 增加数据 sleep(1); echo "<br>增加数据:<br>"; $conn = new mysqli($servername, $username, $password, $dbname); $sql = "INSERT INTO MyTable VALUES (4,‘小红‘,‘female‘);"; $result = $conn->query($sql); echo $result->num_rows; ShowData($result); // 删除数据 sleep(1); echo "<br>删除数据:删除名为张三的信息<br>"; $conn = new mysqli($servername, $username, $password, $dbname); $sql = "DELETE FROM MyTable WHERE NAME=‘张三‘"; $result = $conn->query($sql); echo $result->num_rows; ShowData($result); $conn->close(); ?> </body> </html>
将以上所有文件放到及文件夹同一个文件夹下(我这里放到名为LAMP的文件目录下),文件结构如下:
使用命令docker-compose up --build
进行镜像的构建及多容器的开启:
镜像的构建
多容器的开启
0.0.0.0:8080
,访问php-apache服务,页面显示index.php
的内容信息mysqli
的信息:2.php连接MySQL
在浏览器中输入0.0.0.0:8080/mysql.php
,访问mysql.php,实现数据库的连接管理功能
3.phpmyadmin服务验证
在浏览器中输入0.0.0.0:8081
,访问phpmyadmin服务,对数据库进行管理
需要注意:如果我们没有设置所要连接的MySQL服务名称,就会出现无法连接到MySQL数据库的错误:
原因:php要连接docker中运行的mysql是不能用localhost, 127.0.0.1来连接的,因为每个docker运行容器的localhost 127.0.0.1都是自己容器本身,不是mysql容器,需要修改成母机 IP,或者是mysql容器名称。因此,需要在docker-compose.yml中的phpmyadmin服务中指定phpmyadmin所连接的MySQL服务名称。
方法:将环境变量PMA_HOST
赋值为MySQL容器名称:
environment: PMA_HOST: php_mysql #这里为MySQL服务的容器名称
重新运行命令docker-compose up --build
,重新构建所有镜像,启动多容器,再次访问phpmyadmin,输入设置的root用户及密码,成功登录到MySQL数据库可以看到新建的"mydb"数据库,:
对该库下的MyTable表进行简单地更新操作:
至此,利用docker-compose成功搭建LAMP+phpmyadmin环境。
本次实践所花费的时间,断断续续加起来差不多有两天,主要包括学习docker-compose的使用、docker-compose.yml的编写、php连接MySQL的基础用法等。通过搭建LAMP环境,学习了docker-compose的基本用法,感受了docker-compose构建多个镜像、运行多容器的机制,对docker的功能有了进一步的了解。同时也认识了web服务,对web服务的整体框架有了初步了解,希望在接下来的开发中能够学以致用。