利用 Vagrant 實現 Laravel 多個開發環境 (Ubuntu 18.4、Ubuntu 16.4) (with Bug)

日景發表於2019-01-14
  • 開發 laravel,雖然用 Homestead 十分方便,但 Homestead 在某種程度是個黑盒子,也無法用在生產環境,在最後的部署,依然會吃盡苦頭,所以不妨利用 vagrant,快速、方便打造一個與生產環境相近的開發環境。
  • 本文暫未在 Windows 系統中測試,其中 將本地與虛擬機器檔案同步型別改為 nfs ,根據 vagrant 文件,暫不支援 Windows 系統,所以本文很有可能不適用於 Windows 系統。

1. 利用 vagrant,安裝多個系統

  • 前往 vagrant 官網下載頁面,下載、安裝 vagrant。另外,自行安裝 VirtualBox

  • vagrant 安裝 Ubuntu 18.4、Ubuntu 16.4

    • vagrant cloud,可以下載、安裝 box,一步到位,但下載過程太過漫長,建議按下述方式分開進行。
    • 下載 box
      • 前往 http://cloud-images.ubuntu.com/ ,用下載軟體下載相應的 vagrant box
    • 將下載好的 box 複製到相應的目錄,新增 box
      • vagrant box add ubuntu16 xenial-server-cloudimg-amd64-vagrant.box
      • vagrant box add ubuntu18 bionic-server-cloudimg-amd64-vagrant.box
    • 初始化 box。這裡的 box 名稱,與上一步的名稱一致
      • vagrant init ubuntu16
      • vagrant init ubuntu18
    • 這時目錄下多了一個 Vagrantfile 檔案,取消這個檔案中這一行的註釋:config.vm.network "forwarded_port", guest: 80, host: 8080
      • 由於掛載多個系統,注意後者的 host 埠不要衝突,我將 ubuntu18 設為 8018,ubuntu16 設為 8016
    • 啟動 box:vagrant up
    • 此時,在 VirtualBox 可以看到兩個系統已經開啟
  • 參考 文件,同步本地及虛擬機器檔案
    • 修改 Vagrantfile,把 # config.vm.synced_folder "../data", "/vagrant_data" 修改為:config.vm.synced_folder "/Users/dayscene/code", "/home/vagrant/code" ,注意調整 /Users/dayscene/code 為個人本地目錄。
    • 重啟虛擬機器:vagrant reload --provision
    • 進入 box:vagrant ssh ,發現在 /home/vagrant 目錄下多了一個 code 目錄,其中檔案與本地檔案一致。

2. 安裝 Nginx,MySQL,PHP

主要參考 digitalocean 的這篇文章 搭建 LNMP

  • 進入 box:vagrant ssh 。進入後,先更新系統安裝源:sudo apt-get update

  • 安裝 Nginx:sudo apt-get install nginx

    • 在瀏覽器中分別訪問 http://localhost:8018/http://localhost:8016/,看到 Nginx 預設頁面,表示 Nginx 安裝成功。
  • 安裝 MySQL 5.7:sudo apt-get install mysql-server

    • 在 ubuntu16,安裝過程中會跳出設定 root 使用者密碼的彈窗。
    • 在 ubuntu18,需要額外配置:
      • sudo mysql_secure_installation
      • root 使用者預設採用 auth_socket 登入,因此無法直接通過 mysql -uroot -p 登入,需要稍作修改:
        • 先進入 mysql:sudo mysql
        • 修改 root 使用者:alter user 'root'@'localhost' identified with mysql_native_password by 'password'; 最後一個單詞 password,需要改為你的密碼
        • 更新修改:flush privileges;
        • 檢視 root 使用者的 plugin 是否為 mysql_native_password:select user,authentication_string,plugin,host from mysql.user;
  • 安裝 PHP 7.2

    • 在 ubuntu16,PHP 預設源的版本是 7.0,目前 Laravel 5.7 要求 PHP 的最低版本是 7.1,顯然不能滿足開發需求。參考 這篇文章,安裝 PHP 7.2
      • 增加 ppa 源:
        • sudo apt-get install python-software-properties
        • sudo add-apt-repository ppa:ondrej/php
        • sudo apt-get update
      • 安裝 PHP:sudo apt-get install php7.2-fpm php7.2-mysql
    • 在 ubuntu18,直接安裝:sudo apt-get install php-fpm php-mysql
    • 在兩個系統檢視 PHP 的安裝版本:php -v ,都是 PHP 7.2
  • 安裝 composer

    • 先安裝依賴:sudo apt-get install curl php-cli php-mbstring git unzip
    • 下載 installer:curl -sS https://getcomposer.org/installer -o composer-setup.php
    • 驗證 installer:
      • 前往 https://composer.github.io/pubkeys.html,複製 SHA-384 簽名
      • 利用 PHP 自帶的 hash_file 函式進行驗證:
        • php -r "if(hash_file('SHA384','composer-setup.php')==='上一步複製的 SHA-384 簽名') {echo 'verified';} echo PHP_EOL;",如果輸出 verified,表示通過驗證。
    • 執行安裝:sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
    • 刪除 installer:rm composer-setup.php
    • 可選:如果後續 composer 安裝太慢,可以使用 laravel-china 的 國內映象
      • composer config -g repo.packagist composer https://packagist.laravel-china.org
  • 至此,已基本完成開發環境的搭建,新建一個專案看看:composer create-project laravel/laravel blog --prefer-dist "5.7.*"

    • 發現報錯:Your requirements could not be resolved to an installable set of packages.
    • 原因是部分 PHP 擴充套件沒有安裝,安裝擴充套件:sudo apt-get install php7.2-xml
    • 刪除上一步安裝失敗的 blog 專案:rm -rf blog/ ,再次安裝,沒有報錯。
    • 雖然當前安裝沒有問題,後續 composer 安裝第三庫時仍可能出現此類問題,屆時再按類似方法解決:
      • 在搜尋引擎此類報錯是由於哪個擴充套件沒有安裝引起
      • 查詢安裝源是否有這個擴充套件:sudo apt list | grep php7.2 ,若有,即可直接安裝。
  • 配置 Nginx。Nginx 的配置檔案在 /etc/nginx 目錄,開啟該目錄,發現其網站配置結構為:在 sites-available 目錄新增各個網頁配置,若想該配置生效,再在 sites-enabled 目錄建立一個軟連結

    • 建立一個配置檔案:sudo vi /etc/nginx/sites-available/blog.test ,參考 laravel 文件 部署,寫入:

      server {
          listen 80;
          server_name blog.com;
          root /home/vagrant/code/blog/public;
      
          index index.php index.html;
      
          location / {
              try_files $uri $uri/ /index.php?$query_string;
          }
      
          location = /favicon.ico { access_log off; log_not_found off; }
          location = /robots.txt  { access_log off; log_not_found off; }
      
          error_page 404 /index.php;
      
          location ~ \.php$ {
              include snippets/fastcgi-php.conf;
              fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
          }
      
          location ~ /\.(?!well-known).* {
              deny all;
          }
      }
    • 建立一個軟連結:sudo ln -s /etc/nginx/sites-available/blog.test /etc/nginx/sites-enabled/
    • 刪除預設配置檔案:sudo unlink /etc/nginx/sites-enabled/default
    • 測試配置檔案語法是否正確:sudo nginx -t
    • 重啟 Nginx:sudo service nginx reload
  • 瀏覽器中訪問,發現 laravel 報錯:"/home/vagrant/code/blog/storage/logs/laravel-2019-01-14.log" could not be opened: failed to open stream: Permission denied
    • 看回 laravel 文件 安裝,需要給 storagebootstrap/cache 目錄寫入許可權,於是調整這兩個目錄的許可權:sudo chmod -R 777 storage/ bootstrap/cache 。然而,這個操作並不生效。
    • 搜尋一番,問題應該出在本地及虛擬機器共享資料夾,但慚愧的是,我沒有找到解決方法。後來,我將共享檔案的型別改為 nfs ,暫時解決了這個問題:
      • 再次修改 Vagrantfile ,把之前修改的 config.vm.synced_folder "/Users/dayscene/code", "/home/vagrant/code" ,增加一個 type :config.vm.synced_folder "/Users/dayscene/code", "/home/vagrant/code", type: "nfs" 。取消這行的註釋,增加私有網路設定:config.vm.network "private_network", ip: "192.168.33.10"
      • 再重啟虛擬機器:vagrant reload --provision
      • 此時,已經可以修改相應目錄的許可權。在瀏覽器也可以看到 laravel 預設頁面。

3. 結語

  • 使用 vagrant 最好的一點是,你發現哪個環節出錯了,可以暴力 destroy 這個 box,然後重頭再來。
  • 上述關於修改目錄許可權的問題,特此向各位請教,還望不吝指教。
  • (待續)

相關文章