环境

  • Windows 10 Pro (1909)
  • Docker-Desktop 2.3.0.3
  • PHP 7.4.6
  • Apache 2.4.38
  • MySQL 8.0.20

Docker-Desktop 下载安装

下载 Docker-Desktop for windows

  • 点击 “Get Docker” 下载安装文件
下载 Docker-Desktop
下载 Docker-Desktop
  • 启用 Hyper-v,添加桌面快捷方式,按个人习惯选择即可
安装选项
安装选项
  • 等待安装完成
安装中
安装中
  • 安装完成需要重新启动
重新启动
重新启动
  • 重启后等待更新结束
等待更新
等待更新
  • 启动 Docker Desktop
启动Docker
启动Docker
  • 跳过教程即可
跳过教程
跳过教程
  • 由于国内使用 DockerHub 速度太美,换成国内的源 (这里使用 163 的)
更换国内源
更换国内源
  • 修改后点击 “Apply & Restart” 重启Docker服务
应用设置
应用设置

PHP-Apache 容器

  • 管理员模式打开 PowerShell
右键Windows菜单
右键Windows菜单
打开PowerShell
打开PowerShell
  • 这里以 DockerHub 官方的 php:apache-buster 镜像作为示例,其它其它容器可参考官方文档
1
docker pull php:apache-buster
拉取镜像
拉取镜像
  • 建立一个项目目录 (这里使用 E:/HelloWorld 目录并放置了一个用于测试的 index.php)
1
2
<?php
phpinfo();
建立项目目录和文件
建立项目目录和文件
  • 运行容器,并绑定刚刚建立的项目目录
    • --name 指定容器名称
    • --restart always 容器自动重新启动
    • -d 以服务模式运行
    • -p 指定主机绑定的端口
    • -v 绑定主机目录到容器
1
docker run --name helloworld --restart always -d -p 8000:80 -v E:\HelloWorld:/var/www/html php:apache-buster
运行PHP容器
运行PHP容器
  • 现在可以通过 http://localhost:8000 访问容器了。
访问测试
访问测试
  • 此时PHP仍不能正常使用 PDO、mysqli 等常用的扩展,需要进入到容器内进行设置
1
docker exec -it helloworld bash
  • 先替换 Debian 的源 (这里使用163的源):
1
2
3
sed -i 's/deb.debian.org/mirrors.163.com/g' /etc/apt/sources.list
sed -i 's/security.debian.org/mirrors.163.com/g' /etc/apt/sources.list
apt-get update && apt-get upgrade
更换源
更换源
  • 安装常用的扩展
    • bcmath
    • zip
    • exif
    • gettext
    • sockets
    • mcrypt
    • opcache
    • pdo pdo_mysql
    • pcntl shmop sysvmsg sysvsem sysvshm
1
2
3
4
5
6
7
apt-get install -y --no-install-recommends libzip-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev libmcrypt-dev \
&& docker-php-ext-install -j$(nproc) bcmath zip exif gettext sockets pcntl pdo_mysql shmop sysvmsg sysvsem sysvshm \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd \
&& pecl install mcrypt-1.0.3 \
&& docker-php-ext-enable mcrypt \
&& docker-php-ext-configure opcache --enable-opcache
安装常用扩展
安装常用扩展
  • 启用 mod_rewrite,默认没有开启,启用后输入 exit 退出容器
1
2
a2enmod rewrite
exit
启用 mod_rewrite 支持
启用 mod_rewrite 支持
  • 使用 docker ps 查看容器ID
  • 保存容器改动为新的镜像,以便下次复用该镜像
1
docker commit 容器ID my-php-env
保存为新的镜像
保存为新的镜像
  • 重新启动容器测试
1
docker restart helloworld
测试扩展是否已经可用
测试扩展是否已经可用

MySQL 容器

  • 这里使用 DockerHub 官方 mysql:latest 镜像作为示例
    • --name 指定容器名称
    • --restart always 容器自动重新启动
    • -d 以服务模式运行
    • -p 指定主机绑定的端口 (由于示例主机已有其它MySQL服务,故改用 3307 端口)
    • -e 指定容器内的环境变量 MYSQL_ROOT_PASSWORD 指定 root 用户密码
    • --default-authentication-plugin=mysql_native_password 用于指定MySQL采用旧的密码验证方式,可视实际情况决定是否使用。
    • 本地没有mysql:latest镜像,docker会自行拉取。
1
docker run --name mysql --restart always -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:latest --default-authentication-plugin=mysql_native_password
运行MySQL容器
运行MySQL容器
  • 如无意外,MySQL 服务已经可以正常访问
登录到MySQL
登录到MySQL

容器间通信

  • 现在 PHP 容器仍未能访问 MySQL 容器,需要进一步设置。
  • 我们创建一个新的网络develop用于容器间通信通信:
1
docker network create develop
  • 检查网络是否创建成功:
1
docker network ls
创建新的网络
创建新的网络
  • 将前面创建的 PHP 和 MySQL 容器加入到刚刚创建的网络中:
1
2
docker network connect develop helloworld
docker network connect develop mysql
  • 检查容器是否已经成功加入到develop网络中:
1
docker network inspect develop
  • 修改项目目录中的 index.php 文件测试MySQL是否可以正常连接
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$host = "mysql"; // 前面为容器指定的名称
$port = 3306; // 前面容器指定的3307是从主机映射到容器的端口,此处仍然使用 3306
$user = "root";
$pass = "123456";
$dsn="mysql:host=$host:$port;dbname=mysql";

try {
$connection = new PDO($dsn, $user, $pass);
echo "连接成功<br/>";
} catch (PDOException $e) {
echo $e->getMessage();
}
修改index.php文件
修改index.php文件
测试MySQL
测试MySQL

镜像复用

  • 已经基本完成环境的配置,文中部分命名、参数、所使用的镜像等按实际需要调整。
  • 可以通过 docker images 查看新保存的镜像,复用时可以直接使用该镜像即可:
1
docker run --name project2 --restart always -d -p 8001:80 -v E:\project2:/var/www/html my-php-env