擁抱 Docker!Laravel 老專案開發環境從 Homestead 遷移到 Sail

huzhuolei發表於2022-07-02

前言

作為程式設計師,一直以來的開發環境都是在虛擬機器下。既可以標準化、又方便遷移,還有一點是不會弄髒弄亂原生系統。特別是用 Laravel 框架的時候,Homestead + Vagrant + VirtualBox 非常好用,一個 vagrant up 命令把所有依賴都裝好,開箱即用。讓我們把時間和精力都放在開發上。

不過用的時間長了,Homestead 也是有一定的弊端的。比如啟動時間長、吃硬碟、耗資源,當時就想著能不能用 Docker 替代虛擬機器。早期的時候 Laravel 官方還沒有基於 Docker 的解決方案,不過有一些第三方的,怕不靠譜就懶得折騰了。而且 Homestead 本身確實比較優秀,用起來還是比較方便的,就一直拖下來了。現在官方出了 Sail,正好把之前幾個專案都轉到 Sail 環境下,把我的 MBP 的資源都釋放出來。

網上很多類似遷移教程都是針對新專案的。本篇文章記錄的是老專案從 Homestead 遷移到 Sail。老專案比新專案要複雜一些,如果你正好有這方面需求,希望這篇文章能夠幫助到你。

我在遷移不同的專案過程中都會踩到不同的坑,解決方案我會補充在文章裡。如果你碰到了問題,仔細看看文章裡面有沒有解決方案。如果沒有,歡迎給我留言。

1. 安裝 Docker

這個就不說了,很簡單,網上教程一大堆。

2. 關閉 .env 裡面的 redis 和 memcached 配置

FILESYSTEM_DRIVER=public
BROADCAST_DRIVER=log
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=memcached
SESSION_LIFETIME=120

改為:

FILESYSTEM_DRIVER=public
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

不關閉 redis 配置的話,後面執行 composer 命令的時候會因為沒有 redis 服務而報錯。

3. 安裝 Sail

$ cd ./project
$ docker run --rm \
    -u "$(id -u):$(id -g)" \
    -v $(pwd):/var/www/html \
    -w /var/www/html \
    laravelsail/php81-composer:latest \
    composer require laravel/sail --dev

離開了 Homestead 環境,我們假設原生系統下沒有安裝 php 和 composer「至少我的是這樣」。所以要通過 composer 去安裝 Sail 就成了難題了。難不成為了裝 Sail 再裝一套 php + composer?那就與 Docker 精神背道而馳了。細心的 Laravel 團隊肯定也想到了這一點,所以提供了一個只有 php + composer 的小容器 laravelsail/phpXX-composer 給我們來安裝 Sail。

這個 phpXX 是該專案下對應的 php 版本,比如 74、80、81。例子裡我們就用 81 來演示。

當然,你可以在以前的 Homestead 環境下執行 composer require laravel/sail --dev,完全沒有問題,效果是一樣的。

如果在執行命令的時候有什麼元件因為 php 擴充套件的問題報錯,可以先在 composer.json 裡把報錯的元件刪掉,等 Sail 搭好了再重新安裝。因為畢竟這是一個簡化版的映象,不會象 Sail 開發環境那樣啟用很多擴充套件,它的目的只是安裝 Sail。

4. 生成 docker-compose.yml

$ docker run --rm \
    -u "$(id -u):$(id -g)" \
    -v $(pwd):/var/www/html \
    -w /var/www/html \
    laravelsail/php81-composer:latest \
    php artisan sail:install --with=mysql,redis,memcached

上一步已經把 Sail 安裝好了,現在就是要生成 docker-compose.yml 編排檔案。--with 後面跟的是這個專案下面需要的元件。支援的有:

  • mysql
  • pgsql
  • mariadb
  • redis
  • memcached
  • meilisearch
  • minio
  • selenium
  • mailhog

點選參閱官方說明

只要把需要的元件加在 with 後面,就會自動編排到配置檔案裡面。演示中我新增了 mysqlredismemcached

如果用到了 VSCodeRemote - Containers 來管理開發環境,可以在 --with=XXX 後面加上 --devcontainer,這樣還會額外生成 VSCode 需要的 devcontainer.json 檔案。

完成這步操作以後就可以恢復 .env 裡的 redis 和 memcached 了。

其實到這一步 Sail 就算安裝好了,可以執行 ./vendor/bin/sail up。後面的操作是一些優化步驟。

5. 修改 Dockerfile

$ cp -r ./vendor/laravel/sail/runtimes ./docker

因為一些眾所周知的原因,我們需要對 Dockerfile 進行一些修改和優化,而 Dockerfile 檔案原本在 ./vendor/laravel/sail/runtimes/X.X 下面「又是 XX」。Laravel 的約定是不能直接修改 ./vendor/ 下的任何檔案,因為一更新就沒啦,所以我們需要把它複製出來。

./vendor/laravel/sail/runtimes 整個資料夾複製一份放在專案根目錄下,資料夾名字改為 dockerdocker 下面有 7.48.08.1 三個子資料夾,裡面的檔案都一樣,用哪個版本的 php 就修改相應資料夾下面的檔案。我們們還是用 8.1 來演示。

Dockerfile 用來建立一個容器
docker-compose.yml 用來建立一堆容器,並且按照一定的網路和依賴關係組合起來

$ vim ./docker/8.1/Dockerfile
FROM ubuntu:22.04

LABEL maintainer="Taylor Otwell"

ARG WWWGROUP
ARG NODE_VERSION=16
ARG POSTGRES_VERSION=14

WORKDIR /var/www/html

ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update \
.
.
.

改為:

FROM ubuntu:20.04

LABEL maintainer="Taylor Otwell"

ARG WWWGROUP
ARG NODE_VERSION=16
ARG POSTGRES_VERSION=14

WORKDIR /var/www/html

ENV DEBIAN_FRONTEND noninteractive
ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ADD sources.list /etc/apt/

RUN apt-get update \
.
.
.
  • FROM ubuntu:22.04 => FROM ubuntu:20.04 我比較習慣 20.04,這個改不改隨個人喜好。改成 20.04 以後,該檔案中的 jammy 全部要改成 focal
  • ENV TZ=UTC => ENV TZ=Asia/Shanghai 我是中國人??
  • ADD sources.list /etc/apt/ 給容器啟動的時候新增國內映象源

6. 設定映象源

$ vim ./docker/8.1/sources.list
# 預設註釋了原始碼倉庫,如有需要可自行取消註釋
deb http://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse
# deb-src http://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse
# deb-src http://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
# deb-src http://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# deb-src http://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse

# 預釋出軟體源,不建議啟用
# deb http://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
# deb-src http://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse

幾點說明:

  • 這裡我用了中科大的源,用什麼源也是個人喜好,只不過我一開始用阿里雲的源的時候一直超時,換中科大的就沒問題。
  • 不管什麼源,只能用 http,不能用 https,會報下面的錯誤:
    Certificate verification failed: The certificate is NOT trusted. The certificate issuer is unknown.  Could not handshake: Error in the certificate verification.
  • 重複一遍,20.04focal22.04jammy

7. 修改 docker-compose.yml

$ vim ./docker-compose.yml
# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.1
.
.
.

改為:

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/8.1
.
.
.

前面選了 8.1,這裡就寫 8.1

8. 啟航!

$ ./vendor/bin/sail up

後記

第一次 sail up 生成映象的時候還是挺耗時的,需要耐心等待一段時間。這個時候網路環境特別重要,這就是為什麼要那麼費勁新增國內映象源了。

如果卡在下面這個地方一直不動:

#0 192.1 gpg: keybox '/root/.gnupg/pubring.kbx' created

解決步驟:

  1. 開啟第 5 步裡的 Dockerfile
  2. 找到 hkp://keyserver.ubuntu.com:80
  3. 改為 hkp://keyserver.ubuntu.com
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章