從零構建一個基於Docker的Laravel應用

Docker簡介

其實在這樣的一個雲計算時代, Docker 早就已被人衆所周知了,它改變了傳統物理機的虛擬化方式,使得機器的資源獲得了高效的利用. 由於運行在 Docker 中的應用實際上就是運行在宿主機上的, 因此它是不須要進行硬件層面的虛擬化以及運行一個完整操做系統來支持. 因而在應用代碼的執行效率, 內存的使用以及文件的讀取速度都比傳統虛擬化的方式來的強. 並且它的啓動速度很是快,每每都是在毫秒級的,能夠大大的節約了開發測試以及部署的時間.
其實對於開發人員來講, Docker 一個更大的意義就是能夠保證擁有一致的運行環境, 程序員最多見的就是在開發測試部署環境不一致的狀況下, 常常會觸發一些莫名奇妙的BUG, 爲了杜絕「這段代碼在我機器上沒問題啊」這類的問題,這也是咱們要去學習 Docker 的理由之一.php

如何學習 Docker?

網上充斥着大量的關於 Docker 各個方面的教程和資料, 並且因爲 Docker 的飛速發展, 不少教程其實都過期了, 對於初學者來講很難去分辨把握, 隨之而來的就是一系列的坑與問題, 漸漸的磨滅了學習者的動力. 其實學習一門新技術最好的永遠都是從官方的文檔入手, 而後就是 GitHub 上面一個技術人員的學習筆記, 最重要的是要去摸索實踐, 而且作好學習筆記. 其實學習一門新技術, 若是有正確的學習方法是能夠少走不少彎路的, 這個有機會會寫一篇心得.html

快速入門

這裏限制於篇幅和做者水平, 不會大談 Docker 底層原理以及技術實現,也不會教你如何寫一個繁瑣的 Dockerfile, 而是會從一個普通開發者的身份入手, 帶你從零搭建一個基於 Docker 的 Laravel 應用.咱們的系統環境使用的是 Ubuntu17.04, 其餘系統也差很少,固然 Window 的話可能就要另當別論了.mysql

安裝Docker

在 Ubuntu 下 Docker 的安裝和常規的軟件同樣,可是因爲中國特點,還有有不少要注意的點,待會會詳細說明. Docker 的安裝方式有不少種,這裏建議使用官方的一鍵安裝腳原本,避免一系列繁瑣的操做。nginx

1. 下載安裝

curl -fsSL get.docker.com -o get-docker.sh

而後安裝,而且選擇從阿里鏡像源下載:laravel

sudo sh get-docker.sh --mirror Aliyun

2. 基本配置

其實安裝後基本上就可使用了,主要是配置一些鏡像源和用戶組。配置鏡像源的目的很少說,用戶組主要是爲了再使用的時候不用使用超級管理員權限便可運行。git

  • 加入用戶組
sudo usermod -aG docker $USER
PS. 配置用戶組後,可能仍是會出現仍是提示沒有權限的狀況,這時重啓機器便可
  • 配置鏡像源
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://be62qq2e.mirror.aliyuncs.com"]
}
EOF
PS. 這裏的鏡像源是我本身阿里雲的,同窗們能夠自行去阿里雲獲取專有鏡像源地址
  • 重啓
sudo systemctl daemon-reload
sudo systemctl restart docker

3. 安裝docker-compose

docker-compose相似一個包管理工具,方便咱們管理鏡像。程序員

curl -L https://github.com/docker/compose/releases/download/1.17.1/run.sh > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

基本概念

Docker 有兩個很重要的基本概念就是鏡像和容器. 這兩個其實就相似面向對象中的類和實例. 鏡像構建起來後就是容器,而後容器能夠啓動中止,對於運行於容器中的應用在運行過程當中產生的數據,其實是能夠保留下來的,只要不銷燬容器. 若是銷燬或者從新構建容器後數據天然就不存在了,因此官方建議用掛載的方式來持久化, 接下來會說到.github

docker-compose

docker-compose 能夠說是真正的讓 Docker 現代化了. 它就相似於 PHP 的 Composer 包管理工具同樣, 是用來管理多個鏡像的. 它極大的下降了學習 Docker 的難度. 咱們在平常的開發中, 常常會碰到須要多個容器相互配合來完成某項任務的狀況,好比 Web 容器和數據庫容器之間的通訊,咱們能夠單獨的把一個項目中須要的全部容器和配置寫到一個 docker-compose.yml 文件中,來統一管理.來看一下一個簡單的配置文件格式:redis

version: '3'
services:
  nginx:
    build: .
    ports:
     - "80:80"

  redis:
    image: "redis:alpine"

一個項目能夠由多個服務(容器)工程,而 docker-compose 是面向項目進行管理.sql

文件系統和網絡

這是 Docker 比較複雜的一塊,簡單介紹一下. Docker 裏面的文件系統其實很真實宿主機的同樣, 能夠用一樣的命令去操做, 只是要注意的一點就是咱們在容器中運行的應用配置文件的路徑所有都是基於 Docker 的,不是基於宿主機的,不少文件不存在的問題都是這個引發來的.好比咱們在運行一個 Nginx 容器和 PHP-FPM 容器的時候,不只要把宿主機的項目路徑映射到 Nginx 容器中,還要映射到 PHP-FPM 容器中,不然就會是一系列的 File not found.
Docker 中的網絡是有多種模式的, 在默認狀況下是會建立一個虛擬網橋的, 其實是 Linux 的一個 bridge,它會在掛載到它的網口之間進行轉發。而且會隨機分配一個本地未被使用的屬於 172.17.0.0/16 網段的 IP 到各個容器中.這是一個網絡拓撲圖:

部署 Laravel 應用

基本介紹後咱們會經過一個簡單的實例來加深理解, 就是部署一個 Laravel 應用. Web 服務器咱們會使用 Nginx, 而且經過 PHP-FPM 來處理動態請求,用 MySQL 來存儲數據, Redis 做爲咱們的緩存和隊列驅動. 不一樣於網上的經過 Supervisor 來把全部服務運行在同一個容器中,咱們會把這四個服務運行在四個容器中,這也是官方推薦的一種作法,而後咱們會經過 docker-compose 來管理全部的服務(容器).

Nginx

直接上配置文件:

version: '2'
services:
    nginx:
        image: nginx
        ports:
            - "8090:80"
        links:
            - php-fpm
        volumes:
          - ./nginx/www:/var/www/html
          - ./nginx/sites:/etc/nginx/sites-enabled
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        command: [nginx-debug, '-g', 'daemon off;']

其中的 services 節點下每個表示一個服務;而後 nginx 這是個服務名能夠隨便取;image 指定使用哪一個鏡像來構建; ports 表示要暴露的端口,其中 8090 是指宿主機的端口,80 是指容器中的端口;volumes 表示掛載的目錄和文件,咱們這裏掛載了代碼目錄,虛擬主機目錄以及配置文件;command 表示容器啓動後要運行的命令。咱們還要在當前目錄下建立一個 nginx 的目錄,用來存放一系列的文件,還須要把配置文件新建而且寫入配置內容(具體配置內容能夠去官網查看,這裏不說明),最後的目錄結構是這樣

Docker
    - docker-compose.yml
    - nginx
        - www
        - sites
        - nginx.conf
能夠把日誌一塊兒掛載,這裏沒有表述出來

而後執行啓動容器的命令:

docker-compose up nginx

以上不會在後臺啓動,而是會直接在當前的 shell 上,而後咱們訪問應該就能夠看到 Welcome to nginx!

PHP-FPM MySQL Redis

同理咱們再次配置 PHP-FPM,MySQL 以及 Redis 的容器了,具體過程很少講,這裏貼出配置:

php-fpm:
    image: 'bitnami/php-fpm:7.1'
    volumes:
      - ./nginx/www:/var/www/html
      - ./php-fpm/php.ini:/bitnami/php/conf/php.ini
    links:
      - mysql
      - redis

  mysql:
    image: mysql
    restart: always
    environment:
        MYSQL_ROOT_PASSWORD: example
    volumes:
      - /var/lib/mysql:/var/lib/mysql

  redis:
    image: redis

有一點要注意的是,在配置PHP-FPM容器的時候是須要把代碼目錄也掛載到容器裏面的,這一點很容易被遺忘,網上不少教程都沒提到,致使最後雖然按照步驟走了但就是跑不起來。其中的 links 就是配置要鏈接到哪一個容器中。好比配置了 Nginx 容器鏈接到 PHP-FPM 的容器,這樣咱們在 Nginx 的容器中就能夠直接 ping php-fpm,在配置的時候也能夠這樣 php-fpm:9000 來配置了。

配置文件

Nginx 的配置文件,而後還要修改一下本地的 hosts 文件。

server {
    listen 80;
    listen [::]:80;
    root /var/www/html/laravel/public;
    index index.html index.php;
    server_name laravel-docker.app;
    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass php-fpm:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

運行訪問

附錄

貼一些經常使用的 docker-compose 命令,其中的 dc 表示 docker-compose 命令。

dc  stop            中止全部容器
dc  stop    nginx   中止指定容器
dc  up      -d      啓動容器後臺運行
dc  ps              查看當前容器
dc  logs    kafka   查看指定容器日誌

歡迎關個人我的公衆號:左手代碼

相關文章
相關標籤/搜索