整體思路:利用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服務的整體框架有了初步了解,希望在接下來的開發中能夠學以致用。