windows 使用docker-compose+DockFile部署專案(內含laravel-echo-server)

Enzo_Lwb發表於2020-09-15

平時開發環境是windows下的整合環境,在一年前下載了Docker Desktop 想安裝laradock 但是忘了什麼原因了 失敗了,最近閒來沒事準備整一下本地的dockfile一鍵部署

本文的閱讀和實踐需要一些docker、lnmp、docker命令等基礎。
重申一下 這是windows環境下laravel專案的部署。

感謝laradock專案給我的很多地方的靈感,讓我自己編寫dockerfile時得心應手。大家在部署的時候也可以參考它的原始碼

目錄

1. Docker Desktop 的安裝 以及 配置
2. docker-compose.yml + dockerfile 檔案說明
3. laravel-echo-server的部署指南
4. supervisor 監控佇列
5. 容器內的定時任務
6. k8s 入門除錯(下一篇文章吧)

1.Docker Desktop 的安裝 以及配置

:no_mouth:就是官網下載安裝,修改映象源(Setting-Docker Engine-registry-mirrors,可以去DAOCloud找個源)。現在的desktop 更新的很智慧了,不像之前還要手動新增允許file sharing,現在都隨著掛載隨著提示你允許,並且應該是自動安裝好docker-compose,如果沒有安裝,就百度下安裝方式吧。

2.docker-compose.yml + dockerfile 檔案說明

先看下大體的專案目錄吧

  • app
  • config
  • docker
    • app_local.dockerfile(workspace容器部署檔案)
    • supervisor.conf(supervisord 配置檔案)
    • crontabs(容器內的定時任務)
    • laravel-echo-server.dockerfile
    • package.json(單獨安裝laravel-echo-server 的)
    • php.ini
    • vhost.conf
    • web.dockerfile
  • public
  • resources
  • ….
  • .env
  • .laravel-echo-server.json
  • .docker-compose.yml
  • …..

  • 專案目錄下建立docker-compose.yml和 docker/ *.dockfile,然後根據專案具體需求調整檔案內容,下面我把用過的所有服務都列到下面舉個例子。直接在程式碼裡說明吧

composer和node我沒有選擇使用映象容器處理,因為可擴充套件性不是很好,平時更新專案時可能需要修改composer和npm,我也下載過映象進行模擬 使用起來都不盡如人意,不如直接在php app的容器(workspace)中進行命令操作。

version: '3.7'
services:
  app:
    image: xxx_app #映象名稱
    build: #指定該容器構建引數
      context: ./
      dockerfile: ./docker/app_local.dockerfile #dockerfile 的目錄在當前專案下的docker檔案下
    working_dir: /app # 指定容器工作目錄
    restart: always
    volumes: #目錄掛載 修改php配置
      - ./:/app
      - ./docker/php.ini:/usr/local/etc/php/conf.d/php.ini #配置檔案
    environment: #這裡可以新增修改.env的引數使其使用容器服務 
      - REDIS_HOST=redis

  # nginx
  web:
    image: xxxx_web
    build:
      context: ./
      dockerfile: ./docker/web.dockerfile
    restart: always
    depends_on:
      - app
    ports:
      - 80:80  #前面的80指本地埠 後面的80指容器中的埠
    volumes: #本機也需要記錄日誌
      - ./:/app
      - E:/DockerData/nginx/:/data/logs/nginx/

  # redis database 需要連線本地資料庫時可以使用
  redis:
    container_name: xxx_redis #不使用dockfile的時候設定容器名稱
    volumes:
      - E:/DockerData/redis:/data  # 掛載redis資料目錄
      - E:/DockerData/conf/redis/redis.conf:/etc/redis/redis.conf  # 需要配置檔案 不然無法啟動
    image: redis
    command: redis-server /etc/redis/redis.conf
    ports:
      - 6380:6379

# mysql database 需要連線本地資料庫時可以使用 
  database:
    container_name: xxx_mysql
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    ports:
    - 3316:3306
    environment: #MYSQL_ROOT_PASSWORD 才是登陸密碼 env中的密碼
    - "MYSQL_ROOT_PASSWORD=password"
    - "MYSQL_DATABASE=database_name"
    volumes: #需要資料轉移的時候 可以掛載 沒有的話就直接進入php容器 執行資料遷移
    - D:/xxxx/MySQL5.7.26/data/xxx:/var/lib/mysql/xxxx

  #  laravel-echo-server
  laravel-echo-server:
    build:
      context: ./
      dockerfile: ./docker/laravel-echo-server.dockerfile
    volumes:
      - ./laravel-echo-server.json:/usr/src/app/laravel-echo-server.json
    ports:
      - 6001:6001 #關鍵 別設定錯
    links:
      - redis #通知關聯redis服務
  • 下面我們來看dockfile和配置檔案
  1. app_local.dockerfile (workspace 也就是php-fpm)
FROM php:7.3-fpm-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.huaweicloud.com/g' /etc/apk/repositories
RUN apk update \
    && apk upgrade \
    && apk add --no-cache \
        freetype \
        libpng \
        libjpeg-turbo \
        freetype-dev \
        libpng-dev \
        jpeg-dev \
        libjpeg \
        libjpeg-turbo-dev \
        libwebp-dev\
        libzip-dev\
        git
RUN docker-php-ext-configure gd \
                --with-freetype-dir=/usr/lib/ \
                --with-png-dir=/usr/lib/ \
                --with-jpeg-dir=/usr/lib/ \
                --with-webp-dir=/usr/lib/
RUN docker-php-ext-install mysqli pdo pdo_mysql gd zip
WORKDIR /app
RUN apk add composer npm
RUN composer config -g repos.packagist composer https://packagist.phpcomposer.com
RUN npm config set registry https://mirrors.huaweicloud.com/repository/npm/

# composer 和 npm的命令等容器建立好之後 進入容器進行 
# composer install composer autoload-dump 和 npm install npm run prod 等操作
  1. laravel-echo-server.dockfile(關於laravel-echo-server 使用和安裝中的坑 可以看我之前的文章laravel-echo-server 踩坑記錄)
FROM node:alpine

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# 拷貝 屬於 echo-server自己的package.json 與專案本身的區分開
COPY ./docker/package.json /usr/src/app/

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

RUN apk add --update \
    python \
    python-dev \
    py-pip \
    build-base

RUN npm install

# 根據專案自身的配置laravel-echo-server.json進行啟動
COPY laravel-echo-server.json /usr/src/app/laravel-echo-server.json

EXPOSE 3000
CMD [ "npm", "start", "--force" ] #容器構建後 啟動echo-server
  1. package.json (laravel-echo-server 使用的)
{
  "name": "laravel-echo-server-docker",
  "description": "Docker container for running laravel-echo-server",
  "version": "0.0.1",
  "license": "MIT",
  "dependencies": {
    "laravel-echo-server": "^1.5.0"
  },
  "scripts": {
    "start": "laravel-echo-server start"
  }
}
  1. php.ini(在yml檔案中掛載了)
post_max_size = 500M
upload_max_filesize = 500M
memory_limit = 512M
#...其他配置的更改
  1. vhost.conf(nginx 配置 更具體的內容可以看看laradock專案)

client_max_body_size 500m;


proxy_read_timeout 240s;

server {
    listen 80;

    index index.php index.html;
    root /app/public;

    server_name xxxx.com;

    access_log /data/logs/nginx/xxxx_access.log;
    error_log /data/logs/nginx/xxxx_error.log;

    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000; #workspace的服務名稱app
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
  1. web.dockerfile (nginx的映象檔案)
FROM nginx:1.17-alpine
ADD docker/vhost.conf /etc/nginx/conf.d/default.conf
RUN mkdir -p /data/logs/nginx/
#這裡修改日誌名稱 與上面的檔案相對應
RUN touch /data/logs/nginx/xxxx_access.log
#這裡修改與上面的檔案相對應
RUN touch /data/logs/nginx/xxx_error.log

laravel-echo-server的部署指南

  1. laravel-echo-server.json(authhost不修改的話會顯示 Error authenticating)

    {
     "authHost": "http://web",
     "authEndpoint": "/broadcasting/auth",
     "clients": [],
     "database": "redis",
     "databaseConfig": {
         "redis": { //這裡要修改的
             "port": "6379",
             "host": "redis"
         }
     },
     "devMode": true,
     "host": null,
     "port": "6001",
     "protocol": "http",
     "socketio": {},
     "sslCertPath": "",
     "sslKeyPath": ""
    }
  2. 最後提示一下.env檔案別忘了修改 QUEUE_CONNECTION、BROADCAST_DRIVER為redis,DB_HOST修改為服務名稱,我這裡叫database。以及涉及到的主機掛載目錄是否都已經建立?


然後你就可以愉快的 docker-compose up -d ,docker-compose build 了

supervisor 監控佇列

先呈上supervisor.conf

[program:yourname_queue]#這裡改個自己名字
process_name=%(program_name)s_%(process_num)02d
directory=/app #你的容器內的專案目錄 
command=php artisan queue:work --tries=3 --sleep=3 --daemon
autostart=true 
autorestart=true
numprocs=1
user=root
stopasgroup=true
killasgroup=true
redirect_stderr=true
stderr_logfile=/app/storage/logs/err_queue.log #配置錯誤日誌檔案路徑
stdout_logfile=/app/storage/logs/queue.log  #配置輸出日誌檔案路徑
[supervisord]

[supervisorctl]
  1. 在你的workspace容器內安裝supervisor(直接配置dockfile即可), 然後copy配置檔案到容器內
# 我這裡是app_local.dockerfile
RUN apk add supervisor
# supervisor 服務配置檔案
COPY ./docker/supervisor.conf /etc/supervisor/conf.d/supervisord.conf
  1. 在映象完成成為容器後執行啟動命令
docker exec your_container_name /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

容器內的定時任務

呈上crontabs檔案

#最好不要用windows記事本編輯這個檔案出現換行,以免出現不必要的bug
* * * * * php /app/artisan schedule:run >> /app/storage/logs/crond.log 2>&1

因為我的workspace映象使用的事alpine系統,不是centos和ubuntu之類的,所以它自帶的crontab與其他的不同,這裡我就列出alpine的步驟,其他系統的方式應該是先安裝 然後需要修改crontab檔案的許可權為600 然後執行。

1.在dockerfile中copy我們自己的crontab檔案(可選),也可以直接在命令列中echo方式書寫一個crontab檔案

# 可選
COPY ./docker/crontabs /etc/cron.d/
# 新增定時任務在docker中,似乎只能執行root的crontab命令,其路徑在/var/spool/cron/crontabs/root中,並不是掃描cron.d/資料夾下面的所有檔案,將自己的crontab指令碼先copy到docker,再cat到docker的root指令碼後面才可以執行
RUN cat /etc/cron.d/crontabs>>/var/spool/cron/crontabs/root

# 如果是不copy檔案 直接書寫crontab的方式(可選)
RUN echo -e '* * * * * php /app/artisan schedule:run >> /app/storage/logs/crond.log 2>&1'>>/var/spool/cron/crontabs/root
  1. 在映象完成成為容器後執行啟動命令(類似supervisor),如果不這樣做的話 直接在dockerfile中CMD或者Entrypoint的話,我嘗試過會報錯。
docker exec your_container_name crond

這裡我參考的文章連結在alpine linux構建的docker中使用crontab執行定時任務
裡面也包含了修改容器 date 時區的方式 我就不贅述了。

再重申一遍 我這是alpine的映象 其他linux的映象方式可百度


好啦 結束了。以後若有新的dockerfile新增,我也會更新的。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章