PHP Laravel的容器化開發與部署

本文說明一下PHP Laravel(包含Lumen)開發下的Docker化部署,寫到了使用 CentOS 6.九、CentOS 7.0 進行生產環境部署,並使用了 Kong 來做爲 API 網關進行鑑權。javascript

Docker開發環境

首先,咱們須要在開發環境下安裝 Docker。這部分網絡上的資料汗牛充棟,就不贅述了。php

在項目根目錄下建立 Dockerfile。 咱們使用了 richarvey/nginx-php-fpm 做爲基礎鏡像,相關資料能夠查閱其項目文檔html

FROM richarvey/nginx-php-fpm:1.5.7 RUN sed -i "s/try_files \$uri \$uri\/ =404;/try_files \$uri \$uri\/ \/index.php?\$query_string;/g" /etc/nginx/sites-available/default.conf \ && sed -i "s/try_files \$uri \$uri\/ =404;/try_files \$uri \$uri\/ \/index.php?\$query_string;/g" /etc/nginx/sites-available/default-ssl.conf \ && sed -i "s/root \/var\/www\/html/root \/var\/www\/html\/public/g" /etc/nginx/sites-available/default.conf \ && sed -i "s/root \/var\/www\/html/root \/var\/www\/html\/public/g" /etc/nginx/sites-available/default-ssl.conf 

而後建立 docker-compose.yml 文件:java

version: '3' services: web: build: . volumes: - .:/var/www/html ports: - "80:80" - "443:443" depends_on: - redis - db links: - redis - db redis: image: redis db: image: mysql:5.7 volumes: - ./db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: appdb MYSQL_USER: appuser MYSQL_PASSWORD: apppassword 

在項目配置 .env 裏配置相應的redis和數據庫信息:mysql

DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=appdb DB_USERNAME=appuser DB_PASSWORD=apppassword CACHE_DRIVER=redis REDIS_HOST=redis:6379 REDIS_PORT=6379 

而後執行 docker-compose up ,docker會自動構建支持 Laravel 的鏡像並將當前項目目錄掛載到容器 /var/www/html 目錄下。這樣就能夠在docker環境下進行開發了。linux

Docker生產鏡像

首先修改 .env ,以適配生產環境的相關信息,例如數據庫名稱、密碼等等。這些信息和後面部署時用到的須要一致。nginx

Dockerfile_production:git

FROM richarvey/nginx-php-fpm:1.5.7 COPY . /var/www/html/ RUN sed -i "s/try_files \$uri \$uri\/ =404;/try_files \$uri \$uri\/ \/index.php?\$query_string;/g" /etc/nginx/sites-available/default.conf \ && sed -i "s/try_files \$uri \$uri\/ =404;/try_files \$uri \$uri\/ \/index.php?\$query_string;/g" /etc/nginx/sites-available/default-ssl.conf \ && sed -i "s/root \/var\/www\/html/root \/var\/www\/html\/public/g" /etc/nginx/sites-available/default.conf \ && sed -i "s/root \/var\/www\/html/root \/var\/www\/html\/public/g" /etc/nginx/sites-available/default-ssl.conf 

使用如下命令構建生產環境鏡像:web

docker build -t prod_web -f Dockerfile_production . 

在CentOS 6.9環境的部署

由於條件所限,有些服務器OS版本比較低(CentOS6.9),安裝所需的軟件包會比較麻煩,因此須要進行一些升級來運行docker容器環境。redis

首先升級內核

(從elrepo倉庫下載最新的穩定版內核,修改grub.conf以使用最新內核,禁用selinux,而後重啓):

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm yum --enablerepo=elrepo-kernel install -y kernel-lt sed -i 's/default=1/default=0/g' /etc/grub.conf sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config sed -i 's/SELINUX=permissive/SELINUX=disabled/g' /etc/selinux/config reboot 

而後安裝DOCKER

(安裝epel倉庫,安裝docker-io,設置docker隨系統啓動並啓動docker):

yum -y remove epel-release-6-8 yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm yum install -y docker-io chkconfig --list | grep docker chkconfig docker on service docker start 

部署DOCKER鏡像

docker-io不支持docker-compose(項目中的 docker-compose.yml 只能用在開發環境或CentOS7上的容器環境),因此鏡像只能使用 docker run 來建立容器。

將前面構建的生產環境鏡像導出到文件:

docker save -o prod_web.tar prod_web 

把鏡像上傳到CentOS6.9服務器上,導入爲本地鏡像:

docker load -i prod_web.tar 

在CentOS6.9服務器上按順序執行如下腳本:

  • 1_run_redis.sh:
#!/bin/bash docker run -it -d --name redis \ -p 6379:6379 \ --restart=always \ redis 
  • 2_run_cassandra.sh:
#/bin/bash docker run --name cassandra \ -v /data/cassandra:/var/lib/cassandra \ -d --restart=always\ -p 9042:9042 \ cassandra:3 
  • init_kong_db.sh: 注意此腳本只應該跑一次
#/bin/bash docker run --rm \ --link cassandra \ -e "KONG_DATABASE=cassandra" \ -e "KONG_CASSANDRA_CONTACT_POINTS=cassandra" \ kong:latest kong migrations up 
  • 3_run_mysql.sh:
#!/bin/bash docker run -it -d --name db \ -v /data/mysql:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=rootpass \ -e MYSQL_DATABASE=appdb \ -e MYSQL_USER=appuser \ -e MYSQL_PASSWORD=apppassword \ -p 3306:3306 \ --restart=always \ mysql:5.7 
  • 4_run_prod.sh:
#/bin/bash mkdir -p /data/prod_storage chmod -R 777 /data/prod_storage docker run -it -d --name prod \ --restart=always \ -p 8080:80 \ -v /data/prod_storage:/var/www/storage \ --link redis:redis \ --link db:db \ prod_web 
  • 5_run_kong.sh:
#/bin/bash mkdir -p /data/kong_log docker run --name kong \ -d --restart=always \ -e "KONG_DATABASE=cassandra" \ -e "KONG_CASSANDRA_CONTACT_POINTS=cassandra" \ -e "KONG_PROXY_ACCESS_LOG=/data/kong_log/proxy_access.log" \ -e "KONG_ADMIN_ACCESS_LOG=/data/kong_log/admin_access.log" \ -e "KONG_PROXY_ERROR_LOG=/data/kong_log/proxy_error.log" \ -e "KONG_ADMIN_ERROR_LOG=/data/kong_log/admin_error.log" \ -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ -p 80:8000 \ -p 443:8443 \ -p 8001:8001 \ -p 8444:8444 \ -v /data/kong_log:/data/kong_log \ --link cassandra \ --link prod \ kong:latest 

後面若是 prod_web 鏡像有了修改,咱們須要刪掉正在運行的 prod 和 kong 兩個容器,而後從新導入鏡像,建立 prod 和 kong 兩個容器:

docker stop prod kong && docker rm prod kong docker load -i prod_web.tar ./4_run_prod.sh ./5_run_kong.sh 

建立 KONG API網關

  • 建立服務 prod-service,注意url裏引用的網址是容器名稱:
curl -i -X POST \ --url http://localhost:8001/services/ \ --data 'name=prod-service' \ --data 'url=http://prod' 

返回相似以下:

{"host":"prod","created_at":1539931317,"connect_timeout":60000,"id":"0dff5819-627e-41d5-8ca0-5fa8c7362d1e","protocol":"http","name":"prod-service","read_timeout":60000,"port":80,"path":null,"updated_at":1539931317,"retries":5,"write_timeout":60000} 
  • 爲服務 prod-service 建立路由,只要訪問域名 prod.test.com,即調用此路由的規則:
curl -i -X POST \ --url http://localhost:8001/services/prod-service/routes \ --data 'hosts[]=prod.test.com' 

返回相似以下:

{"created_at":1539931349,"strip_path":true,"hosts":["prod.test.com"],"preserve_host":false,"regex_priority":0,"updated_at":1539931349,"paths":null,"service":{"id":"0dff5819-627e-41d5-8ca0-5fa8c7362d1e"},"methods":null,"protocols":["http","https"],"id":"3a38359a-b5b9-482b-8c8e-40fb7f8b70e7"} 
  • 爲路由添加SSL證書 (這種方式會發生抖動)
curl -i --url http://localhost:8001/certificates \ --data "cert='-----BEGIN CERTIFICATE-----...'" \ --data "key='-----BEGIN RSA PRIVATE KEY-----...'" \ --data "snis[]=prod.test.com" 
  • 爲服務 prod-service 添加 key-auth 鑑權插件:
curl -i -X POST \ --url http://localhost:8001/services/prod-service/plugins/ \ --data 'name=key-auth' 

返回相似以下:

{"created_at":1539931369484,"config":{"key_in_body":false,"run_on_preflight":true,"anonymous":"","hide_credentials":false,"key_names":["apikey"]},"id":"9d388bb9-818a-4349-86c0-a7e0cb182978","service_id":"0dff5819-627e-41d5-8ca0-5fa8c7362d1e","name":"key-auth","enabled":true} 
  • 添加用戶,這裏添加了一個用戶名爲 sdk_007 的用戶:
curl -i -X POST \ --url http://localhost:8001/consumers/ \ --data "username=sdk_007" 

返回相似以下:

{"custom_id":null,"created_at":1539931393,"username":"sdk_007","id":"902fa8f6-feca-4b2d-8e72-d51a86579019"} 
  • 爲用戶 sdk_007 添加用戶key:
curl -i -X POST \ --url http://localhost:8001/consumers/sdk_007/key-auth/ 

返回相似以下(key已修改):

{"id":"1cc06dcc-0277-4154-a092-c91ff363de92","created_at":1539931418134,"key":"caQVlllch0efVNfGmidadfsa","consumer_id":"902fa8f6-feca-4b2d-8e72-d51a86579019"} 
  • 本地測試:
curl 'http://127.0.0.1/<API REQUEST>' --header 'Host: prod.test.com' --header 'apikey: caQVlllch0efVNfGmidadfsa' 
  • 在線測試:

使用瀏覽器打開 http://prod.test.com/<API REQUEST>?apikey=caQVlllch0efVNfGmidadfsa

在CentOS 7環境的部署

首先升級內核

(從elrepo倉庫下載最新的穩定版內核,修改grub2以使用最新內核,禁用selinux,而後重啓):

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm yum --enablerepo=elrepo-kernel install -y kernel-lt grub2-set-default 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config sed -i 's/SELINUX=permissive/SELINUX=disabled/g' /etc/selinux/config reboot 

而後安裝DOCKER

yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce systemctl enable docker systemctl start docker 

啓動容器

同CentOS 6.9

相關文章
相關標籤/搜索