1. 程式人生 > 實用技巧 >在Ubuntu 20.04中通過Docker compose搭建用於Laravel應用開發的容器

在Ubuntu 20.04中通過Docker compose搭建用於Laravel應用開發的容器

參考 https://www.digitalocean.com/community/tutorials/how-to-install-and-set-up-laravel-with-docker-compose-on-ubuntu-20-04


通過本文,最終會建立
一個app服務執行PHP7.4-FPM
db服務執行MYSQL 5.7
使用app服務來解析PHP程式碼,最後呈現Laravel應用到終端使用者的nginx服務

請預先
初始化Ubuntu配置,
安裝好Docker
安裝好docker-compose


前面的搞完了,先來下載一個demo 的Laravel應用,已經是有初始狀態可以用的了
執行

  cd ~

執行
  curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip

接下來解壓這個壓縮包
執行
  unzip travelliist.zip

沒有安裝這個unzip命令的請執行
    sudo apt update
     sudo apt install unzip

解壓後可以看到~資料夾內多了個 travellist-laravel-demo-tutorial-1.0.1資料夾
接著移動這個資料夾到一個新資料夾 一條命令直接也可以建立這個新資料夾 【也可以叫重新命名】

執行

  mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

執行

  cd travellist-demo

然後開始建立.env檔案


laravel的配置檔案都在config資料夾中,.env檔案被用於設定環境依賴配置。比如密碼之類的在釋出的時候可有不同設定的值。
該檔案也會在版本控制中被排除掉,同時因為該檔案可以包含如資料庫密碼之類的資訊,所以不要公共釋出本檔案。
執行

  cp .env.example .env

執行
  nano .env

開始編輯.env檔案裡的設定
首先資料庫設定 初始配置是指向本地的 127.0.0.1 ,需要修改指向稍後我們會建立到Docker執行環境的資料庫服務。

暫時把服務【一般都是這麼命名】命名為db
即 修改
DB_HOST=127.0.0.1 為 DB_HOST=db
然後資料庫名travellist 使用者名稱travellist_user 密碼password 【如果是想用其他值 自己設定就行】
後面我們在設定docker-compose.yml檔案的時候,需要用到這幾個值用來配置服務。

然後儲存

設定應用的Dockerfile



雖然我們的Mysql 和Nginx服務都是基於Dockerhub下載的預設映象。 但是我們還是需要做一點新的配置並另存為一個新的映象
所以接下來建立一個新的Dokcerfile來搞定。

首先是需要基於PHP7.4-FPM的映象。 然後我們需要配置一些其他的PHP模組 以及 Composer依賴管理工具。

並在該容器中建立一個新使用者,用於開發時執行artisan和composer命令。
通過uid設定保證容器中的使用者與該宿主機的系統使用者一致。
如此任何通過上述命令建立的檔案都會附帶正確的許可權複製到宿主機中。
如此便可以在宿主機中使用宿主機的文字編輯器來開發執行在容器裡的應用!

建立一個新的Dockerfile執行:

nano Dockerfile

複製下面的內容到Dockerfile裡

 FROM php:7.4-fpm

  # Arguments defined in docker-compose.yml
   ARG user
   ARG uid

  # Install system dependencies
   RUN apt-get update && apt-get install -y \
       git \
       curl \
       libpng-dev \
       libonig-dev \
       libxml2-dev \
       zip \
       unzip

  # Clear cache
   RUN apt-get clean && rm -rf /var/lib/apt/lists/*

  # Install PHP extensions
   RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

  # Get latest Composer
  COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

  # Create system user to run Composer and Artisan Commands
   RUN useradd -G www-data,root -u $uid -d /home/$user $user
   RUN mkdir -p /home/$user/.composer && \
       chown -R $user:$user /home/$user

  # Set working directory
   WORKDIR /var/www

  USER $user



然後儲存!

解釋一下,上面就是說 我們使用一個基礎映象 php:7.4-fpm

安裝完系統包,安裝PHP擴充套件 然後從官方https://hub.docker.com/_/composer站點裡複製可以執行的
composer映象到這個應用映象裡。

一開始設定了使用user 和 uid引數 來建立新系統使用者,這些值會被Docker Composer在搭建環境的時候被注入。
最後 我們設定了我們的預設工作資料夾 /var/www 然後切換為剛建立的新使用者。這樣可以保證我們是以正常使用者
的方式連結上的,並且在應用容器裡執行composer和artisan命令的時候處於正確的工作資料夾。


設定Nginx 配置和資料庫打包檔案

通過Docker compose建立執行環境的時候,為了設定或引導啟動服務,一般要與服務的容器共享配置或者初始檔案。
不過話是這麼說,有的時候還是具體情況具體調整。

首先建立一個資料夾並在其中建立些檔案來搞定配置及服務容器初始化。
執行

mkdir -p docker-compose/nginx #建立資料夾

執行

nano docker-compose/nginx/travellist.conf

複製下面::

    server {
       listen 80;
       index index.php index.html;
       error_log  /var/log/nginx/error.log;
       access_log /var/log/nginx/access.log;
       root /var/www/public;
       location ~ \.php$ {
           try_files $uri =404;
           fastcgi_split_path_info ^(.+\.php)(/.+)$;
           fastcgi_pass app:9000;
           fastcgi_index index.php;
           include fastcgi_params;
           fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
           fastcgi_param PATH_INFO $fastcgi_path_info;
       }
       location / {
           try_files $uri $uri/ /index.php?$query_string;
           gzip_static on;
       }
     }

然後儲存。

解釋一下,就是配置Nginx監聽80埠,然後使用index.php檔案作為預設首頁。並設定資料夾根目錄為
/var/www/public ,並設定Nginx通過9000埠使用app服務處理php檔案。

為設定Mysql資料庫,需要共享一個數據庫打包檔案,然後在容器初始化的時候引入它。這個特性是
在該容器中使用的MySQL5.7映象提供的。


執行

mkdir docker-compose/mysql

執行

nano docker-compose/mysql/init_db.sql

然後

  DROP TABLE IF EXISTS `places`;

  CREATE TABLE `places` (
     `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
     `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
     `visited` tinyint(1) NOT NULL DEFAULT '0',
     PRIMARY KEY (`id`)
   ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

  INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);



儲存。

這一段就是建立一個place表,然後插入一條示例資料。

應用的Dockerfile和服務初始化配置搞完了。

使用Docker Compose建立多容器環境

Docker Compose可以給執行在Docker上的應用建立多容器環境的。

一般在根目錄下建立一個docker-compose.yml檔案,裡面定義不同服務如app,db,nginx的配置。

基於前面建立的那個Dockerfile搞出來的travellist映象,它會執行一個容器,該容器使用php-fpm解析php程式碼,
返回結果由另一個容器中的Nginx服務來處理。
然後mysql服務是由一個執行MySQL 5.7的服務的容器提供的。

這三個容器要由一個叫travellist的網橋連線起來。

應用的檔案會通過bind mounts 在app和nginx服務間同步。,這個bing mounts允許宿主機和容器間的雙向同步。


執行

  nano docker-compose.yml

一般來說格式要定義成這樣:

  version: "3.7" #標準格式,就是版本定義
  services: #緊接著就是服務


  networks: #再接著就是網路
    travellist:
       driver: bridge #橋接

可以把沒註釋的這個骨架給複製到docker-compose.yml中

開始編輯app db nginx服務的程式碼:

1.首先是app服務的:

    app:
      build: #即告知docker compose需要使用user引數,uid引數及Dockerfile配置在context路徑下,生成一個app服務的本地映象
        args:
          user: tieress
          uid: 1000
        context: ./
        dockerfile: Dockerfile #此映象使用的dockerfile與docker-compose.yml檔案同目錄
      image: travellist #這是容器儲存的映象名
      container_name: travellist-app #這是給容器的命名
      restart: unless-stopped #總是重啟,除非服務停止。
      working_dir: /var/www/ #本app容器為了執行artisan命令,需要搞一個工作目錄
      volumes: #建立一共享卷,在本容器中,同步當前資料夾./的內容到[:] /var/www資料夾【這個目錄是nginx容器中的/var/www目錄】
        - ./:/var/www
       networks: #配置本服務使用一個叫travellist的網路通訊
        - travellist


2.接下來是db服務:
因為docker compose會自動載入與docker-compose.yml檔案同目錄的.env檔案,所以我們可以使用先前修改的.env檔案中的變數配置

    db:
       image: mysql:5.7 #直接用MysSQL5.7這個官方包
      container_name: travellist-db
       restart: unless-stopped
       environment: #下面就是使用.env中的配置了
        MYSQL_DATABASE: ${DB_DATABASE}
         MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
         MYSQL_PASSWORD: ${DB_PASSWORD}
         MYSQL_USER: ${DB_USERNAME}
         SERVICE_TAGS: dev
         SERVICE_NAME: mysql
       volumes:  #建立一個卷,共享用於初始化應用資料庫的資料庫dump包檔案。
                #MySQL映象會自動引入容器裡面存放於docker-entrypoint-initdb.d資料夾下的.sql檔案
        - ./docker-compose/mysql:/docker-entrypoint-initdb.d
       networks:
         - travellist

3.最後是nginx服務:
使用預製的Nginx映象

    nginx:
        image: nginx:1.19.1-alpine
        container_name: travellist-nginx
        restart: unless-stopped
        ports:
           - 8000:80 #使用ports定義,建立一個從宿主機8000埠重定向到容器內80埠的重定向。
        volumes: #建立兩個共享卷
          - ./:/var/www #這個會同步當前資料夾到/var/www資料夾,當應用本地修改後,會立即同步到nginx服務容器中。
          - ./docker-compose/nginx:/etc/nginx/conf.d #同步nginx配置檔案複製到容器中Nginx配置資料夾內。
        networks:
           - travellist


然後儲存!

跑起來!

執行

docker-compose build app #生成我們的app映象

生成完畢

執行

 docker-compose up -d #後臺執行起來。-d就是後臺模式

執行

 docker-compose ps #檢視執行中的服務


環境跑起來了,接著執行幾個命令完成應用的設定。
注:可以通過docker-compose exec 來執行命令,比如
執行 docker-compose exec app ls -l #用於檢視應用資料夾內的檔案詳細資訊。
執行

docker-compose exec app composer install #安裝應用依賴包

執行

 docker-compose exec app php artisan key:generate #生成key 【laravel配置步驟】

然後就可以訪問8000埠看網站了。


本地機就是localhost:8000 伺服器就是伺服器ip:8000 綁定了域名的就是域名:8000
如果測試完了上線直接改埠對映 80:80 443:443這樣。

另外
執行

docker-compose logs nginx #可以檢視服務生成的logs

執行
 docker-compose pause  #暫停服務 但是不丟狀態

執行
  docker-compose unpause #恢復

執行

  docker-compose down #停止 會移除全部容器,networks和卷

更多的命令檢視 https://docs.docker.com/compose/reference/