利用docker-compose搭建LAMP+phpmyadmin环境
整体思路:利用Apache变体镜像apache:<version>-apache
及MySQL搭建LAMP环境,同时使用phpmyadmin/phpmyadmin镜像实现web数据库管理。
apache:<version>-apache
:该变体包含了Debian的Apache httpd和PHP;
phpmyadmin/phpmyadmin
:该镜像用于数据库的可视化操作,实现数据库的管理。
👉一. docker-compose的安装
参考install docker-compose中docker-compose在linux上的安装,具体步骤:
- 运行如下命令,下载当前稳定版本的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
为docker-compose添加可执行权限:
- 运行命令
docker-compose --version
,出现版本信息,说明docker-compose安装成功:
👉二. dockerfile编写
-
apache变体
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配置文件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
进行镜像的构建及多容器的开启:
-
镜像的构建
-
多容器的开启
👉四.服务验证
-
php-apache服务验证
在浏览器中输入0.0.0.0:8080
,访问php-apache服务,页面显示index.php
的内容信息
查看mysqli
的信息:
-
php连接MySQL
在浏览器中输入0.0.0.0:8080/mysql.php
,访问mysql.php,实现数据库的连接管理功能
-
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服务的整体框架有了初步了解,希望在接下来的开发中能够学以致用。