利用docker-compose搭建LAMP+phpmyadmin環境


  本文主要闡述如何利用docker-compose搭建LAMP(Linux+Apache+MySQL+PHP)環境,實現web服務。

  整體思路:利用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_dockerfileRUN中加入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進行鏡像的構建及多容器的開啟:

  • 鏡像的構建

  • 多容器的開啟

👉四.服務驗證

  1. php-apache服務驗證
    在瀏覽器中輸入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數據庫的錯誤:
    無法連接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服務的整體框架有了初步了解,希望在接下來的開發中能夠學以致用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM