1. Laravel Sail requires a Windows 10 system that supports WSL 2. The WSL 2 feature is only supported in version 2004, released in May 2020, so the system must be updated to version 2004 or later. To check the system version, use the winver command. Referring to the Windows 10 release information, a release date later than 1909 is sufficient. The system version meets the requirements. See Figure 1.

2. First, use 360 to upgrade to the latest version, 21H1. See Figure 2.

3. Check the system version, which has now been upgraded to version 21H1. See Figure 3.

4. Search for and open the Windows Features management window, and ensure the two items highlighted in the red boxes below are enabled: Windows Subsystem for Linux and Remote Differential Compression API Support. See Figure 4.

5. To better access the Windows Subsystem, Windows Terminal is recommended as the command-line tool. Open the Microsoft Store, search for the keyword Windows Terminal, and click install in the search results. See Figure 5.

6. Download and install the subsystem: Ubuntu. Open the Microsoft Store and search for the keyword Ubuntu. Either the first or second result works; select the second one: Ubuntu 20.04 LTS. See Figure 6.

7. You will be prompted to create a user for the Ubuntu system. Enter a username, and then enter a password to complete the installation of the Ubuntu subsystem. This Ubuntu serves as a subsystem for the current Windows system, and Docker will run on it. See Figure 7.

8. Go to the Docker official website to download Docker Desktop: https://hub.docker.com/editions/community/docker-ce-desktop-windows . Once downloaded, click the installer package to install it, and simply keep clicking Next.
9. Prompt: WSL 2 installation is incomplete. See Figure 8.

WSL 2 installation is incomplete.
The WSL 2 Linux kernel is now installed using a separate MSI update package. Please click the link and follow the instructions to install the kernel update:https://aka.ms/wsl2kernel
Press restart after installing the Linux kernel
10. Click the link and follow the instructions to install the kernel update: https://aka.ms/wsl2kernel . Download and install the Linux kernel update package. See Figure 9.

11. Restart the computer and open Docker Desktop again. An error occurs: Docker failed to initialize. Ignore it for now. See Figure 10.

12. After restarting the computer again, open Docker Desktop, and no more errors occur. Go to the configuration page – General. Use the WSL 2 based engine is checked by default, enabling WSL2 mode. See Figure 11.

13. Go to Configuration – Resources – WSL Integration to select the Ubuntu system installed in the previous step, but the ubuntu option is not present. See Figure 12.

14. Reference URL: https://learnku.com/articles/54890 . Open Windows Terminal and convert to WSL 2. See Figure 13.

PS C:\Users\Lenovo> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Running 1
docker-desktop-data Running 2
docker-desktop Running 2
PS C:\Users\Lenovo> wsl --set-version Ubuntu-20.04 2
正在进行转换,这可能需要几分钟时间...
有关与 WSL 2 的主要区别的信息,请访问 https://aka.ms/wsl2
转换完成。
PS C:\Users\Lenovo>
15. Click the Refresh button. The Ubuntu-20.04 option appears; enable it. See Figure 14.

16. To create a test project, open the Windows Terminal command line and enter the Ubuntu system using the following instructions. See Figure 15.

17. As a Windows subsystem, Ubuntu can access the host system’s hard drives. To make code management easier, I had previously created a wwwroot directory on the E drive. After navigating to this directory, use the following command to create a test Laravel project. See Figure 16.

wangqiang@DESKTOP-QLPK8QM:/mnt/c/Users/Lenovo$ cd /mnt/e
wangqiang@DESKTOP-QLPK8QM:/mnt/e$ ls
'$RECYCLE.BIN' 'System Volume Information' cms pagefile.sys phpuploadtmp
Develop c css phpsessiontmp wwwroot
wangqiang@DESKTOP-QLPK8QM:/mnt/e$ cd wwwroot/
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot$ curl -s https://laravel.build/example-app | bash
Unable to find image 'laravelsail/php81-composer:latest' locally
latest: Pulling from laravelsail/php81-composer
eff15d958d66: Pull complete
933427dc39f7: Pull complete
35bb08dc7ee2: Pull complete
58a3f26800d7: Pull complete
28803bfad74c: Pull complete
341a482d0bd3: Pull complete
03c4148389b1: Pull complete
fa3a9bfc7793: Pull complete
024907232600: Pull complete
df5987d70de6: Pull complete
e2a72a518bd8: Pull complete
b1ba689993c8: Pull complete
3bd142ab0b85: Pull complete
872fe34989f0: Pull complete
Digest: sha256:b27920b769ad8dc036a9ede3ae36f51a280d370ec7d125e77ca1924c9fa21dbb
Status: Downloaded newer image for laravelsail/php81-composer:latest
_ _
| | | |
| | __ _ _ __ __ ___ _____| |
| | / _` | '__/ _` \ \ / / _ \ |
| |___| (_| | | | (_| |\ V / __/ |
|______\__,_|_| \__,_| \_/ \___|_|
Warning: TTY mode requires /dev/tty to be read/writable.
Creating a "laravel/laravel" project at "./example-app"
Installing laravel/laravel (v8.6.9)
- Downloading laravel/laravel (v8.6.9)
- Installing laravel/laravel (v8.6.9): Extracting archive
Created project in /opt/example-app
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 110 installs, 0 updates, 0 removals
- Locking asm89/stack-cors (v2.0.3)
- Locking brick/math (0.9.3)
- Locking dflydev/dot-access-data (v3.0.1)
- Locking doctrine/inflector (2.0.4)
- Locking doctrine/instantiator (1.4.0)
- Locking doctrine/lexer (1.2.1)
- Locking dragonmantank/cron-expression (v3.1.0)
- Locking egulias/email-validator (2.1.25)
- Locking facade/flare-client-php (1.9.1)
- Locking facade/ignition (2.17.2)
- Locking facade/ignition-contracts (1.0.2)
- Locking fakerphp/faker (v1.17.0)
- Locking filp/whoops (2.14.4)
- Locking fruitcake/laravel-cors (v2.0.4)
- Locking graham-campbell/result-type (v1.0.4)
- Locking guzzlehttp/guzzle (7.4.1)
- Locking guzzlehttp/promises (1.5.1)
- Locking guzzlehttp/psr7 (2.1.0)
- Locking hamcrest/hamcrest-php (v2.0.1)
- Locking laravel/framework (v8.76.2)
- Locking laravel/sail (v1.12.12)
- Locking laravel/sanctum (v2.13.0)
- Locking laravel/serializable-closure (v1.0.5)
- Locking laravel/tinker (v2.6.3)
- Locking league/commonmark (2.1.0)
- Locking league/config (v1.1.1)
- Locking league/flysystem (1.1.9)
- Locking league/mime-type-detection (1.9.0)
- Locking mockery/mockery (1.4.4)
- Locking monolog/monolog (2.3.5)
- Locking myclabs/deep-copy (1.10.2)
- Locking nesbot/carbon (2.55.2)
- Locking nette/schema (v1.2.2)
- Locking nette/utils (v3.2.6)
- Locking nikic/php-parser (v4.13.2)
- Locking nunomaduro/collision (v5.10.0)
- Locking opis/closure (3.6.2)
- Locking phar-io/manifest (2.0.3)
- Locking phar-io/version (3.1.0)
- Locking phpdocumentor/reflection-common (2.2.0)
- Locking phpdocumentor/reflection-docblock (5.3.0)
- Locking phpdocumentor/type-resolver (1.5.1)
- Locking phpoption/phpoption (1.8.1)
- Locking phpspec/prophecy (v1.15.0)
- Locking phpunit/php-code-coverage (9.2.10)
- Locking phpunit/php-file-iterator (3.0.6)
- Locking phpunit/php-invoker (3.1.1)
- Locking phpunit/php-text-template (2.0.4)
- Locking phpunit/php-timer (5.0.3)
- Locking phpunit/phpunit (9.5.10)
- Locking psr/container (1.1.2)
- Locking psr/event-dispatcher (1.0.0)
- Locking psr/http-client (1.0.1)
- Locking psr/http-factory (1.0.1)
- Locking psr/http-message (1.0.1)
- Locking psr/log (2.0.0)
- Locking psr/simple-cache (1.0.1)
- Locking psy/psysh (v0.10.12)
- Locking ralouphie/getallheaders (3.0.3)
- Locking ramsey/collection (1.2.2)
- Locking ramsey/uuid (4.2.3)
- Locking sebastian/cli-parser (1.0.1)
- Locking sebastian/code-unit (1.0.8)
- Locking sebastian/code-unit-reverse-lookup (2.0.3)
- Locking sebastian/comparator (4.0.6)
- Locking sebastian/complexity (2.0.2)
- Locking sebastian/diff (4.0.4)
- Locking sebastian/environment (5.1.3)
- Locking sebastian/exporter (4.0.4)
- Locking sebastian/global-state (5.0.3)
- Locking sebastian/lines-of-code (1.0.3)
- Locking sebastian/object-enumerator (4.0.4)
- Locking sebastian/object-reflector (2.0.4)
- Locking sebastian/recursion-context (4.0.4)
- Locking sebastian/resource-operations (3.0.3)
- Locking sebastian/type (2.3.4)
- Locking sebastian/version (3.0.2)
- Locking swiftmailer/swiftmailer (v6.3.0)
- Locking symfony/console (v5.4.1)
- Locking symfony/css-selector (v6.0.1)
- Locking symfony/deprecation-contracts (v3.0.0)
- Locking symfony/error-handler (v5.4.1)
- Locking symfony/event-dispatcher (v6.0.1)
- Locking symfony/event-dispatcher-contracts (v3.0.0)
- Locking symfony/finder (v5.4.0)
- Locking symfony/http-foundation (v5.4.1)
- Locking symfony/http-kernel (v5.4.1)
- Locking symfony/mime (v5.4.0)
- Locking symfony/polyfill-ctype (v1.23.0)
- Locking symfony/polyfill-iconv (v1.23.0)
- Locking symfony/polyfill-intl-grapheme (v1.23.1)
- Locking symfony/polyfill-intl-idn (v1.23.0)
- Locking symfony/polyfill-intl-normalizer (v1.23.0)
- Locking symfony/polyfill-mbstring (v1.23.1)
- Locking symfony/polyfill-php72 (v1.23.0)
- Locking symfony/polyfill-php73 (v1.23.0)
- Locking symfony/polyfill-php80 (v1.23.1)
- Locking symfony/polyfill-php81 (v1.23.0)
- Locking symfony/process (v5.4.0)
- Locking symfony/routing (v5.4.0)
- Locking symfony/service-contracts (v2.4.1)
- Locking symfony/string (v6.0.1)
- Locking symfony/translation (v6.0.1)
- Locking symfony/translation-contracts (v3.0.0)
- Locking symfony/var-dumper (v5.4.1)
- Locking theseer/tokenizer (1.2.1)
- Locking tijsverkoyen/css-to-inline-styles (2.2.4)
- Locking vlucas/phpdotenv (v5.4.1)
- Locking voku/portable-ascii (1.5.6)
- Locking webmozart/assert (1.10.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 110 installs, 0 updates, 0 removals
- Downloading doctrine/inflector (2.0.4)
- Downloading doctrine/lexer (1.2.1)
- Downloading dragonmantank/cron-expression (v3.1.0)
- Downloading symfony/var-dumper (v5.4.1)
- Downloading symfony/string (v6.0.1)
- Downloading psr/container (1.1.2)
- Downloading symfony/service-contracts (v2.4.1)
- Downloading symfony/console (v5.4.1)
- Downloading psr/log (2.0.0)
- Downloading monolog/monolog (2.3.5)
- Downloading voku/portable-ascii (1.5.6)
- Downloading phpoption/phpoption (1.8.1)
- Downloading graham-campbell/result-type (v1.0.4)
- Downloading vlucas/phpdotenv (v5.4.1)
- Downloading symfony/css-selector (v6.0.1)
- Downloading tijsverkoyen/css-to-inline-styles (2.2.4)
- Downloading symfony/routing (v5.4.0)
- Downloading symfony/polyfill-php72 (v1.23.0)
- Downloading symfony/polyfill-intl-idn (v1.23.0)
- Downloading symfony/mime (v5.4.0)
- Downloading symfony/http-foundation (v5.4.1)
- Downloading psr/event-dispatcher (1.0.0)
- Downloading symfony/event-dispatcher-contracts (v3.0.0)
- Downloading symfony/event-dispatcher (v6.0.1)
- Downloading symfony/error-handler (v5.4.1)
- Downloading symfony/http-kernel (v5.4.1)
- Downloading symfony/finder (v5.4.0)
- Downloading symfony/polyfill-iconv (v1.23.0)
- Downloading egulias/email-validator (2.1.25)
- Downloading swiftmailer/swiftmailer (v6.3.0)
- Downloading symfony/polyfill-php81 (v1.23.0)
- Downloading ramsey/collection (1.2.2)
- Downloading brick/math (0.9.3)
- Downloading ramsey/uuid (4.2.3)
- Downloading psr/simple-cache (1.0.1)
- Downloading opis/closure (3.6.2)
- Downloading symfony/translation-contracts (v3.0.0)
- Downloading symfony/translation (v6.0.1)
- Downloading nesbot/carbon (2.55.2)
- Downloading league/mime-type-detection (1.9.0)
- Downloading league/flysystem (1.1.9)
- Downloading nette/utils (v3.2.6)
- Downloading nette/schema (v1.2.2)
- Downloading dflydev/dot-access-data (v3.0.1)
- Downloading league/config (v1.1.1)
- Downloading league/commonmark (2.1.0)
- Downloading laravel/serializable-closure (v1.0.5)
- Downloading laravel/framework (v8.76.2)
- Downloading facade/ignition-contracts (1.0.2)
- Downloading facade/flare-client-php (1.9.1)
- Downloading facade/ignition (2.17.2)
- Downloading fakerphp/faker (v1.17.0)
- Downloading asm89/stack-cors (v2.0.3)
- Downloading fruitcake/laravel-cors (v2.0.4)
- Downloading psr/http-message (1.0.1)
- Downloading psr/http-client (1.0.1)
- Downloading ralouphie/getallheaders (3.0.3)
- Downloading psr/http-factory (1.0.1)
- Downloading guzzlehttp/psr7 (2.1.0)
- Downloading guzzlehttp/promises (1.5.1)
- Downloading guzzlehttp/guzzle (7.4.1)
- Downloading laravel/sail (v1.12.12)
- Downloading laravel/sanctum (v2.13.0)
- Downloading nikic/php-parser (v4.13.2)
- Downloading psy/psysh (v0.10.12)
- Downloading laravel/tinker (v2.6.3)
- Downloading hamcrest/hamcrest-php (v2.0.1)
- Downloading mockery/mockery (1.4.4)
- Downloading filp/whoops (2.14.4)
- Downloading nunomaduro/collision (v5.10.0)
- Downloading phpunit/php-file-iterator (3.0.6)
- Downloading phpunit/php-code-coverage (9.2.10)
- Downloading phpspec/prophecy (v1.15.0)
- Installing doctrine/inflector (2.0.4): Extracting archive
- Installing doctrine/lexer (1.2.1): Extracting archive
- Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
- Installing webmozart/assert (1.10.0): Extracting archive
- Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
- Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
- Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
- Installing symfony/var-dumper (v5.4.1): Extracting archive
- Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
- Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
- Installing symfony/string (v6.0.1): Extracting archive
- Installing psr/container (1.1.2): Extracting archive
- Installing symfony/service-contracts (v2.4.1): Extracting archive
- Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
- Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
- Installing symfony/console (v5.4.1): Extracting archive
- Installing psr/log (2.0.0): Extracting archive
- Installing monolog/monolog (2.3.5): Extracting archive
- Installing voku/portable-ascii (1.5.6): Extracting archive
- Installing phpoption/phpoption (1.8.1): Extracting archive
- Installing graham-campbell/result-type (v1.0.4): Extracting archive
- Installing vlucas/phpdotenv (v5.4.1): Extracting archive
- Installing symfony/css-selector (v6.0.1): Extracting archive
- Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
- Installing symfony/routing (v5.4.0): Extracting archive
- Installing symfony/process (v5.4.0): Extracting archive
- Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
- Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
- Installing symfony/mime (v5.4.0): Extracting archive
- Installing symfony/http-foundation (v5.4.1): Extracting archive
- Installing psr/event-dispatcher (1.0.0): Extracting archive
- Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
- Installing symfony/event-dispatcher (v6.0.1): Extracting archive
- Installing symfony/error-handler (v5.4.1): Extracting archive
- Installing symfony/http-kernel (v5.4.1): Extracting archive
- Installing symfony/finder (v5.4.0): Extracting archive
- Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
- Installing egulias/email-validator (2.1.25): Extracting archive
- Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
- Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
- Installing ramsey/collection (1.2.2): Extracting archive
- Installing brick/math (0.9.3): Extracting archive
- Installing ramsey/uuid (4.2.3): Extracting archive
- Installing psr/simple-cache (1.0.1): Extracting archive
- Installing opis/closure (3.6.2): Extracting archive
- Installing symfony/translation-contracts (v3.0.0): Extracting archive
- Installing symfony/translation (v6.0.1): Extracting archive
- Installing nesbot/carbon (2.55.2): Extracting archive
- Installing league/mime-type-detection (1.9.0): Extracting archive
- Installing league/flysystem (1.1.9): Extracting archive
- Installing nette/utils (v3.2.6): Extracting archive
- Installing nette/schema (v1.2.2): Extracting archive
- Installing dflydev/dot-access-data (v3.0.1): Extracting archive
- Installing league/config (v1.1.1): Extracting archive
- Installing league/commonmark (2.1.0): Extracting archive
- Installing laravel/serializable-closure (v1.0.5): Extracting archive
- Installing laravel/framework (v8.76.2): Extracting archive
- Installing facade/ignition-contracts (1.0.2): Extracting archive
- Installing facade/flare-client-php (1.9.1): Extracting archive
- Installing facade/ignition (2.17.2): Extracting archive
- Installing fakerphp/faker (v1.17.0): Extracting archive
- Installing asm89/stack-cors (v2.0.3): Extracting archive
- Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
- Installing psr/http-message (1.0.1): Extracting archive
- Installing psr/http-client (1.0.1): Extracting archive
- Installing ralouphie/getallheaders (3.0.3): Extracting archive
- Installing psr/http-factory (1.0.1): Extracting archive
- Installing guzzlehttp/psr7 (2.1.0): Extracting archive
- Installing guzzlehttp/promises (1.5.1): Extracting archive
- Installing guzzlehttp/guzzle (7.4.1): Extracting archive
- Installing laravel/sail (v1.12.12): Extracting archive
- Installing laravel/sanctum (v2.13.0): Extracting archive
- Installing nikic/php-parser (v4.13.2): Extracting archive
- Installing psy/psysh (v0.10.12): Extracting archive
- Installing laravel/tinker (v2.6.3): Extracting archive
- Installing hamcrest/hamcrest-php (v2.0.1): Extracting archive
- Installing mockery/mockery (1.4.4): Extracting archive
- Installing filp/whoops (2.14.4): Extracting archive
- Installing nunomaduro/collision (v5.10.0): Extracting archive
- Installing phpdocumentor/reflection-common (2.2.0): Extracting archive
- Installing phpdocumentor/type-resolver (1.5.1): Extracting archive
- Installing phpdocumentor/reflection-docblock (5.3.0): Extracting archive
- Installing sebastian/version (3.0.2): Extracting archive
- Installing sebastian/type (2.3.4): Extracting archive
- Installing sebastian/resource-operations (3.0.3): Extracting archive
- Installing sebastian/recursion-context (4.0.4): Extracting archive
- Installing sebastian/object-reflector (2.0.4): Extracting archive
- Installing sebastian/object-enumerator (4.0.4): Extracting archive
- Installing sebastian/global-state (5.0.3): Extracting archive
- Installing sebastian/exporter (4.0.4): Extracting archive
- Installing sebastian/environment (5.1.3): Extracting archive
- Installing sebastian/diff (4.0.4): Extracting archive
- Installing sebastian/comparator (4.0.6): Extracting archive
- Installing sebastian/code-unit (1.0.8): Extracting archive
- Installing sebastian/cli-parser (1.0.1): Extracting archive
- Installing phpunit/php-timer (5.0.3): Extracting archive
- Installing phpunit/php-text-template (2.0.4): Extracting archive
- Installing phpunit/php-invoker (3.1.1): Extracting archive
- Installing phpunit/php-file-iterator (3.0.6): Extracting archive
- Installing theseer/tokenizer (1.2.1): Extracting archive
- Installing sebastian/lines-of-code (1.0.3): Extracting archive
- Installing sebastian/complexity (2.0.2): Extracting archive
- Installing sebastian/code-unit-reverse-lookup (2.0.3): Extracting archive
- Installing phpunit/php-code-coverage (9.2.10): Extracting archive
- Installing doctrine/instantiator (1.4.0): Extracting archive
- Installing phpspec/prophecy (v1.15.0): Extracting archive
- Installing phar-io/version (3.1.0): Extracting archive
- Installing phar-io/manifest (2.0.3): Extracting archive
- Installing myclabs/deep-copy (1.10.2): Extracting archive
- Installing phpunit/phpunit (9.5.10): Extracting archive
76 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/sail
Discovered Package: laravel/sanctum
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
77 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
No publishable resources for tag [laravel-assets].
Publishing complete.
> @php artisan key:generate --ansi
Application key set successfully.
Application ready! Build something amazing.
Sail scaffolding installed successfully.
Please provide your password so we can make some final adjustments to your application's permissions.
[sudo] password for wangqiang:
Thank you! We hope you build something incredible. Dive in with: cd example-app && ./vendor/bin/sail up
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot$
18. The final successful creation screen. See Figure 17.

19. Open the E:\wwwroot\example-app directory. See Figure 18.

20. View the Dockerfile. Laravel 8 uses the Dockerfile in the vendor/laravel/sail/runtimes/8.0 directory by default. See Figure 19.

21. To run the container, execute the following command in the project’s root directory: ./vendor/bin/sail up. The first time it runs, it will initialize the container. Using a VPN is recommended. I generally do not prefer using domestic mirrors. An error occurs. See Figure 20.

ERROR: for mysql Cannot start service mysql: Ports are not available: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
ERROR: Encountered errors while bringing up the project.
22. The reason should be that the local MySQL database is already using port 3306, so I decided to change the local MySQL database port to 3307 first. Open the directory C:\ProgramData\MySQL\MySQL Server 5.7 and edit the my.ini file.
[client]
# pipe
# socket=0.0
port=3307
[mysqld]
# The next three options are mutually exclusive to SERVER_PORT below.
# skip-networking
# enable-named-pipe
# shared-memory
# shared-memory-base-name=MYSQL
# The Pipe the MySQL Server will use
# socket=MYSQL
# The TCP/IP Port the MySQL Server will listen on
port=3307
23. After restarting the computer, connecting to the local MySQL database using port 3307 is successful. See Figure 21.

24. Run the command again: ./vendor/bin/sail up. It will start running from mysql, taking a total of 20 minutes. After the sail up command runs successfully, it will continuously display the software’s real-time log interface. See Figure 22.

25. At this point, you can press Ctrl+C to interrupt the execution. When running it again, you can use the -d parameter to run the sail up command in the background. See Figure 23.

meilisearch_1 | [2021-12-21T03:09:36Z INFO actix_web::middleware::logger] 127.0.0.1:51806 "GET /health HTTP/1.1" 200 22 "-" "Wget" 0.000297
^CGracefully stopping... (press Ctrl+C again to force)
Stopping example-app_laravel.test_1 ... done
Stopping example-app_mailhog_1 ... done
Stopping example-app_mysql_1 ... done
Stopping example-app_selenium_1 ... done
Stopping example-app_redis_1 ... done
Stopping example-app_meilisearch_1 ... done
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/example-app$ ./vendor/bin/sail up -d
example-app_laravel.test_1 start-container Exit 137
Shutting down old Sail processes...
Creating network "example-app_sail" with driver "bridge"
Creating example-app_redis_1 ... done
Creating example-app_mailhog_1 ... done
Creating example-app_meilisearch_1 ... done
Creating example-app_selenium_1 ... done
Creating example-app_mysql_1 ... done
Creating example-app_laravel.test_1 ... done
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/example-app$
26. Open Docker Desktop. The container list shows the container: example-app, with a running status. See Figure 24.

27. Open the URL http://localhost/ in a browser. It responds with 200. Laravel v8.76.2 (PHP v8.1.0). The development environment has been successfully deployed. See Figure 25.

28. Regarding the issue of port 3306 being occupied, there is another solution: change the container’s port to 43306. The local MySQL database will continue to use port 3306. I plan to implement this later using Nginx Proxy Manager.
29. Edit the C:/Windows/System32/Drivers/etc/hosts file to specify the mapping between the IP and the domain name.
127.0.0.1 example-app.test
30. Open the URL http://example-app.test/ in a browser. It responds with 200. See Figure 26.

