在 WSL 2 虚拟机中基于 Docker 编排 LNMP 运行环境

前言

有很多同学反馈如何在 WSL 虚拟机中使用 Docker 搭建开发环境,今天学院君来给大家演示下。

上篇教程学院君给大家演示了如何在 Windows 中安装 WSL 版 Ubuntu 虚拟机,并且在虚拟机中安装了 PHP、Composer、Git 等 PHP 开发基础软件,此外还简单介绍了 WSL 虚拟机与 Windows 宿主机之间的文件同步机制。

由于 PHP 主要用于 Web 开发,所以,一个完备的本地开发环境必须配备 Web 项目运行环境,这通常需要一个 Web 服务器和数据库软件,这里我们选择比较通用的 Nginx 和 MySQL 作为 Web 服务器和数据库服务器,这样的一个 PHP 运行环境被称之为 LNMP(Linux + Nginx+ MySQL + PHP,如果 Web 服务器使用的是 Apache,则对应的运行环境简称为 LAMP)。

你当然可以通过 Ubuntu 的包管理工具进行对应软件的安装:

sudo apt install nginx
sudo apt install mysql

对应的完整教程可以参考学院君以前写过的教程:在 Ubuntu 中快速部署安装 Nginx + PHP + MySQL 笔记

不过,这里我们准备通过更简单快捷的方式 —— 基于 Docker Compose 编排 Nginx、MySQL、PHP-FPM 容器来完成 LNMP 运行环境的搭建和运行。

将 Docker 集成到 WSL 虚拟机

在开始之前,我们需要先在 WSL 虚拟机中集成 Docker。

在 WSL 中可以安装 Docker,但是由于 WSL 没有使用真正的 Linux 内核,而是模拟,所以有诸多权限限制,而在 Windows 10 最新版(version 2004)提供的 WSL 2 中,使用了真正的 Linux 内核,这样一来,就可以在其中运行原生的 Linux 容器,也因此,从 WSL 2 开始,Docker Desktop for Windows 支持通过配置将 Docker 集成到 WSL 2 中使用,无需额外单独安装,非常方便。

Docker 和 Windows 版本要求

上述功能特性要求 Docker 桌面端版本是 2.3.0.2 及以上版本:

同时 Window 10 版本是最新版的 2004 或者更高(在 Windows 系统设置->系统->关于页面可以看到):

如果你的 Windows 或者 Docker Desktop 软件版本没有达到此要求,请务必先升级到对应版本,否则无法进行后续操作。

升级 Ubuntu 到 WSL 2 发行版

在具备以上条件的基础上需要将 WSL 升级到 WSL 2(如果已经升级到 WSL 2 则跳过此步骤),你可以在 Windows 官方提供的更新 WSL 2 Linux 内核文档下载 Linux 内核更新包,然后参照文档指南安装这个更新包,这样就可以在 Windows 中使用 WSL 2 了。

接下来们以管理员身份运行 PowerShell 来启动一些 WSL 2 特性:

上述命令是:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

执行完该命令后重启 Windows 系统让上述操作生效,再通过 PowerShell 设置 WSL 中已安装的 Ubuntu 版本号为 2:

注:上述命令中,wsl -l -v 用于查看 WSL 虚拟机中所有已安装 Linux 系统的 WSL 发行版本,1 对应 WSL,2 对应 WSL 2,我们通过 wsl --set-version Ubuntu-18.04 2 命令指定 Ubuntu-18.04 系统使用 WSL 2 发行版,如果你安装的是其他 Linux 系统,以 wsl -l -v 命令列举的 Name 字段为准。

升级成功后,再次运行 wsl -l -v,可以看到 Ubuntu-18.04 对应的 WSL 版本已经变成 2:

你还可以将 WSL 默认版本号设置为 2,这样,以后安装的虚拟机 Linux 系统都会初始化为 WSL 2 发行版:

wsl --set-default-version 2

将 Docker 集成到 Ubuntu 虚拟机

接下来,就可以参照 Docker 官方文档 Docker Desktop WSL 2 后端 将 Docker 软件集成到 WSL 虚拟机中使用了。

在 Windows 宿主机中打开已运行的 Docker Desktop 设置界面,在通用(General)选项中勾选「Use the WSL 2 based engine」:

然后应用并重启 Docker,在 PowerShell 中运行 wsl --set-default Ubuntu-18.04 命令设置默认 WSL 虚拟机为之前安装的 Ubuntu-18.04:

再次打开 Docker Desktop 的设置界面,在资源「Resources」选项的子菜单「WSL INTEGRATION」中按照下面截图勾选对应输入框,在对应虚拟机系统中启用集成 Docker 到 WSL:

点击应用&重启「Apply&Restart」按钮让上述配置生效。

在 Ubuntu 中运行 Docker 命令

在 Windows PowerShell 中运行 wsl 启动默认的 Ubuntu 虚拟机,就可以运行 docker 相关命令了,表示 Docker 已经成功集成到 WSL 中的 Ubuntu 虚拟机系统:

在上面的截图中,我们在虚拟机中通过本地安装的 VS Code 打开某个项目目录,然后在 VS Code 的终端窗口中,对应的命令行环境就是虚拟机的上下文环境,这样,我们就可以更加方便地与虚拟机进行交互,比如在虚拟机中启动容器、运行代码,同时也可以在 Windows 宿主机通过图形化窗口进行编码,提升工作效率。

通过 Docker 编排 LNMP 运行环境

编排 & 启动基于容器的 LNMP 环境

既然已经将 Docker 集成到 WSL 虚拟机,接下来,就可以通过 Docker Compose 来编排 Nginx、PHP-FPM、MySQL 来搭建 PHP Web 项目运行环境了,你当然可以使用前面介绍的 Laradock,不过,Laradock 是一个集大成的集成开发环境,如果你只是需要 PHP-FPM、Nginx、MySQL、Redis 之类的最小化运行环境,可以使用更简单的编排方案。

对于 Laravel 项目而言,已经有现成的编排方案可以直接拿来使用 —— ambientum/php,该方案对 Laravel 项目开箱即用,非常方便,你所要做的只是组织好 docker-compose.yml 配置文件,然后运行一个 docker-compose 命令而已,而不用自行去安装、配置、维护 PHP-FPM、Nginx、MySQL 等软件。

这里我还是以一个 Laravel Blog 项目为例进行演示,在 blog 项目根目录下创建 docker-compose.yml,然后参照 ambientum/php 项目官方示例组织 Nginx、PHP-FPM、MySQL 容器如下:

version: '3'
volumes:
  # MySQL Data
  mysql-data:
    driver: local
services:
  # PHP (with Nginx)
  app:
    image: ambientum/php:7.3-nginx
    volumes:
      - .:/var/www/app
    ports:
      - "80:8080"
      - "443:8083"
    links:
      - mysql
    
  # MySQL (5.7)
  mysql:
    image: mysql:5.7
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=blog
      - MYSQL_USER=xueyuanjun
      - MYSQL_PASSWORD=123456

然后在虚拟机中 blog 项目根目录下,运行 docker-compose up -d app 启动相关容器(包含 PHP-FPM、Nginx、MySQL 这个完整的 LNMP 环境,由于 app 依赖 mysql,所以启动它之前会先启动 mysql):

启动完成后,通过 docker-compose ps 命令可以查看容器启动情况:

配置 & 访问 Laravel 应用

打开 blog 项目的 .env 文件,修改数据库配置:

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=xueyuanjun
DB_PASSWORD=123456

在虚拟机中进入 app 容器,在 Laravel 项目映射根目录下运行数据库迁移命令:

然后我们在 Windows 本地可以基于数据库图形界面客户端(这里以 TablePlus 为例)连接到这个数据库:

连接成功后可以看到 blog 数据库中已经包含迁移命令生成的数据表了:

在 Windows 宿主机中打开 hosts,配置一个 blog.test 虚拟域名:

127.0.0.1 blog.test

就可以在浏览器中通过 http://blog.test 访问部署在 WSL 虚拟机中的 Laravel 应用了:

好了,一个简单的基于 Docker 编排的 LNMP 运行环境就搭建起来了,是不是非常简单?需要注意的是这里演示的是基于单个项目的 Docker Compose 编排,如果想要同时管理多个 PHP 项目,可以在 WSL 虚拟机中使用 Laradock,关于 Laradock 的编排和启动和在 Mac 环境中完全一样,参考在 Mac/Windows 系统中使用 Laradock 搭建基于 Docker 的 Laravel 开发环境这篇文章即可,这里不再单独演示了,大家可以作为课后作业去自行体验下。

下篇教程学院君将给大家演示如何在 Windows 宿主机的 PhpStorm 中集成运行在 WSL 虚拟机中的 PHP。

上一篇: 基于 WSL 在 Windows 中搭建 PHP 本地开发环境

下一篇: 选择一款趁手的 PHP 代码编辑器