本篇文章給大家分享的內容是關於如何通過Docker搭建一個swoft開發環境 ,內容很詳細,有需要的朋友可以參考一下,希望可以協助到你們。
Swoft
首個基於 Swoole 原生協程的新時代 PHP 高效能協程全棧組件化架構,內建協程網路伺服器及常用的協程用戶端,常駐記憶體,不依賴傳統的 PHP-FPM,全非同步非阻塞 IO 實現,以類似於同步用戶端的寫法實現非同步用戶端的使用,沒有複雜的非同步回調,沒有繁瑣的 yield,有類似 Go 語言的協程、靈活的註解、強大的全域依賴注入容器、完善的服務治理、靈活強大的 AOP、標準的 PSR 規範實現等等,可以用於構建高效能的Web系統、API、中介軟體、基礎服務等等。
前言
Swoft
是一個在 Swoole
之上構建的一個高效能協程 PHP 全棧架構
,而 Swoole
在 PHPer
裡面是一個進階技能,所以在相關的環境安裝上也給許多人造成了很大的困擾,Swoft
更是如此,本文將通過 Docker
以一種極其簡單的方式解決運行環境和開發環境的部署。
Docker
從百科上可以看到,Docker
是一個開源的的應用程式容器引擎,讓開發人員可以打包他們的應用以及依賴包到一個可移植的容器中,然後發布到任何流行的Linux
機器上,也可以實現虛擬化,容器是完全使用沙箱機制,相互之間不會有任何介面,也可以理解為我們可以將我們的代碼和運行環境打包到一個容器中,打包好的容器發行就緒到任何流行的Linux
機器上,這裡指的Linux機器其實並不準確,得益於Docker for Windows
項目和Hyper-V
的發展,Docker
也可以以不錯的狀態運行在Windows 10系統上,但筆者不建議將 Docker for Windows
用於生產環境上。
Docker 名詞概念
這裡對 Docker
常用的的一些名詞進行簡單的闡述和解釋,以便新手對於下文的理解
Dockerfile
,Dockerfile
是 Docker鏡像
的描述檔案,通過 docker build
命令來構建成為 鏡像
鏡像(Image
),通過 Dockerfile
構建得到,包含作業系統及運行環境
容器(Container
),容器是運行起來的鏡像,可理解為鏡像是Docker
生命週期中的構建和打包階段,而容器則是啟動和執行階段
鏡像倉庫(Repository
),用於儲存構建好的 Docker鏡像
的倉庫,可理解為類似於 Git
的倉庫
安裝 Docker
Docker
的安裝流程並不複雜,本節將介紹 Linux
及 Windows 10
系統下的安裝流程,而 Mac
系統上並不建議
採用 Docker
環境來運行或開發 Swoft
項目,因為在 Mac for Docker
上共用磁碟的效能極其的差,會導致 Swoft
在啟動階段耗時極長。
在 Linux
上安裝 Docker
與 docker-compose
在 Linux
上通過 yum
和 apt-get
來 安裝 Docker
的流程可謂是相當簡單
CentOS:yum install docker -y
Ubuntu:apt-get install docker-engine -y
只需要根據系統的區別,在終端執行上面的一行命令即可完成 Docker
的安裝,在安裝完成之後我們需要執行一下 service docker start
命令來啟動一下 Docker
服務。
在安裝完 Docker
之後,我們還需要安裝一下 docker-compose
以便於後續對 Docker 的使用
CentOS:yum install python-pip -y && pip install --upgrade pip && pip install -U docker-compose
Ubuntu:apt-get install python-pip -y && pip install --upgrade pip && pip install -U docker-compose
只需要根據系統的區別,在終端執行上面的一行命令即可完成 docker-compose
的安裝。
在 Windows 10
上安裝 Docker
與 docker-compose
我們直接到 Docker 官網下載對應的安裝包 https://store.docker.com/edit...,非登入使用者我們會看到 Please Login to Download
,意思是要我們先登入 Docker 帳號好再下載,我們直接點擊按鈕到登入頁面完成帳號註冊或登入即可在上面的連結頁面通過點擊 Get Docker
下載,注意這個帳號後面我們在使用時也會用到。
下載完安裝包後可直接運行安裝包進行安裝,整個過程可以說是傻瓜式的,持續的下一步即可,注意安裝前需先開啟系統的 Hyper-V
,開啟流程相對簡單可參考其它文章 https://segmentfault.com/a/11... ,注意 Hyper-V
是與 VMware
是衝突的,兩者不能並存,只能擇其一,如果你必須要使用虛擬機器的話,比如 Vagrant
之類的工具,亦可在虛擬機器內運行一個 Linux 系統
,然後根據本文關於 Linux 系統
的安裝流程處理,在虛擬機器內運行 Docker
作為開發環境。
最新版的 Docker
安裝包已經包含了 docker-compose
了,也就無需再做多餘的操作。
安裝完成後,重啟電腦,當你看到工作列的 小鯨魚(Docker Icon)
顯示著 Docker is running
即表示 Docker
啟動成功了。
我們需要右鍵 Docker
,點擊 Sign in / Create Docker ID
登入我們剛才註冊的 Docker ID
,以便獲得我們可以從 DockerHub 中擷取公用鏡像的許可權。
由於我們是用於開發使用,所以我們還需要授權一下共用目錄的許可權,右鍵 Docker
並點擊 Settings
,設定介面切換到 Shared Drives
,勾選你項目代碼所在的 磁碟盤符
,並點擊右下角的 Apply
即可完成授權。
Swoft 開發環境
修改官方預設 docker-compose.yml
檔案
我們通過命令 git clone https://github.com/swoft-cloud/swoft
從 Github
上 複製(clone)
Swoft 項目,並使用項目內建的 docker-compose.yml
檔案來實現一個用於開發的環境,docker-compose.yml
是 docker-compose
的編排設定檔, 我們看一下官方預設檔案的內容:
version: '3'services: swoft: container_name: swoft image: swoft/swoft ports: - "80:80" volumes: - ./:/var/www/swoft stdin_open: true tty: true command: php /var/www/swoft/bin/swoft start
這是一個相對簡單的編排檔案,僅僅只有 swoft
一個服務,也沒有關聯過多的內容,關於 docker-compose.yml
的檔案格式我們這裡不做過多的解釋,可自行尋找相關的內容進行閱讀理解。
簡單的解讀此檔案的內容可以理解為,使用了swoft/swoft
官方鏡像並設定了容器名稱為swoft
,綁定容器內的80
連接埠與宿主機的80
連接埠,設定./
目前的目錄與容器內的/var/www/swoft
目錄為共用目錄,開啟與容器的互動式終端並於啟動編排檔案時啟動Swoft
服務。
我們可以注意到預設編排檔案上的 command
配置了 php /var/www/swoft/bin/swoft start
,也就是啟動 Swoft 服務
的命令,但如果僅 複製(clone)
項目並執行 docker-compose up
來嘗試啟動 容器
的話,我們會得到一個失敗的結果,因為尚未執行 composer install
來載入 Composer
的依賴而缺少 vendor
檔案夾和 autoload
等相關檔案,導致無法正確運行 Swoft
執行個體,我們再看預設的編排檔案設定了 stdin_open: true
和 tty: true
兩個參數,分別對應 docker
命令上的 -i
和 -t
兩個參數,簡單的理解就是 -i
開啟了 輸入(input)
功能,-t
開啟了一個串連容器裡面的 互動式終端(terminal)
,我們可以利用這兩個參數,並將編排檔案的 command
行改為 command: /bin/bash
,使容器啟動後不是直接啟動 Swoft
服務,而是由我們手動通過 互動式終端(terminal)
進入容器內去啟動。
下面是一個更改後的 docker-compose.yml
檔案執行個體:
version: '3'services: swoft: container_name: swoft image: swoft/swoft ports: - "80:80" volumes: - ./:/var/www/swoft stdin_open: true tty: true command: /bin/bash
啟動開發環境容器
此時我們在編排檔案的所在目錄啟動一個 終端(Shell)
, 然後執行 docker-compose up -d
,-d
的意思是以守護模式(Daemon Mode)
運行,便於我們在同一個 終端(Shell)
進入到容器內,命令執行後我們可以看到 Starting swoft ... done
即表示啟動容器成功。
如果在執行啟動命令時得到一下錯誤,則說明宿主機的80
連接埠已經被佔用了,更改 docker-compose.yml
檔案內的 80:80
為其它未被佔用的連接埠即可,注意第一個80
指的是宿主機的連接埠,第二個80
指的是容器內的連接埠,也就是說我們只需要更改第一個即可
ERROR: for swoft Cannot start service swoft: b'driver failed programming external connectivity on endpoint swoft(dab0f4d00620e2f5c07e33084ca5cac6f08cb48018d6b737eadc035e5aa0b597): Bind for 0.0.0.0:80 failed: port is already allocated'
進入開發環境容器
通過執行 docker ps
命令可以查看啟動的容器資訊,下面為樣本資訊:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf22173763374 swoft/swoft:latest "docker-php-entrypoin" About a minute ago Up About a minute 0.0.0.0:80->80/tcp swoft
得知 容器ID(Container ID)
為 f22173763374
,容器名稱(Container Name)
為 swoft
,我們可以執行 docker exec -it f22173763374 bash
或 docker exec -it swoft bash
通過 互動式終端(terminal)
進入到容器內。
如執行時報錯 the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty'
,可在 docker exec
命令前面增加 winpty
命令解決,即 winpty docker exec -it swoft bash
運行以及開發調試
安裝 Composer
依賴及產生自動載入(Autoload)
檔案
通過 docker exec
命令進入容器後,我們留意到游標左側的內容變為 root@f22173763374:
即為已進入容器內,其中 f22173763374
為對應的 容器ID(Container ID)
。
由於 Swoft
官方鏡像 swoft/swoft
配置的工作目錄為 /var/www/swoft
,而 docker-compose.yml
又將項目目前的目錄
關聯了容器 /var/www/swoft
目錄,即通過 docker exec
進入的目錄已經為 /var/www/swoft
目錄,即項目目錄,所以我們可以直接執行 composer install
命令來載入 Composer
的依賴並產生 自動載入(Autoload)
檔案。
考慮到國內的網路環境,我們在執行 composer install
命令前可以先執行 composer config -g repo.packagist composer https://packagist.phpcomposer.com
命令配置 Composer 中國鏡像源
加速安裝速度。
啟動 Swoft
服務
安裝完 Composer
依賴後,便可以執行 php bin/swoft start
啟動服務了,當你看到
root@f22173763374:/var/www/swoft# php bin/swoft start Server Information********************************************************************* HTTP | host: 0.0.0.0, port: 81, type: 1, worker: 1, mode: 3* TCP | host: 0.0.0.0, port: 8099, type: 1, worker: 1 (Enabled)********************************************************************Server has been started. (master PID: 15, manager PID: 16)You can use CTRL + C to stop run.
即意味著你的 Swoft
以及啟動成功了,我們可以開啟瀏覽器訪問一下 http://127.0.0.1:80
,當你看到即大功告成了!
如果你綁定宿主機的連接埠不是80
,則改成對應的即可;
如果訪問看到的是 Redis connection failure host=127.0.0.1 port=6379
則說明缺少 Redis
服務,最簡單直接的就是直接在當前容器內安裝 Redis Server
,直接執行 apt install -y redis-server && service redis-server start
即可完成安裝以及啟動操作了;
修改代碼並使代碼生效
Swoft
跟 PHP-FPM
模式下的開發會有一點差異,在PHP-FPM
模式下直接改變代碼內容,再訪問對應的代碼便能得到變更後的內容,是因為PHP-FPM
模式下每一次請求都會重新載入PHP代碼,而 Swoft
是持久化運行
的,也就意味著代碼在服務啟動之後,接受的請求都無需重新載入,這個模式的變化可以使得 Swoft
的大量代碼可被重複使用,而無需重新載入和重新執行個體化,大大提升效能的其中一點原因之一。
這樣的變更對開發會造成一定程度的影響,也就是說在 Swoft
下,你需要 重啟 Worker
或 重啟服務
才能使變更的代碼生效,但是得益於 Swoft
的 熱重載
功能,可以自動檢查代碼變更並自動 重啟 Worker
,我們只需通過項目根目錄下的 .env
檔案更改 AUTO_RELOAD
項為 true
即可,如項目根目錄下沒有 .env
檔案,可直接複製 .env.example
檔案為 .env
並作出對應的更改即可,有一點需要注意的是僅在改變 app
目錄下的代碼才會被 熱重載
功能重載,改變其它代碼不會被重載,這是由於不同代碼是處於不同的生命週期導致的,僅 WorkerStart
之後載入的代碼才能被重載,關於這部分的內容我們將在後續涉及到 Swoft 的生命週期
時再做進一步的講解。