本文說明一下PHP Laravel(包含Lumen)開發下的Docker化部署,寫到了使用 CentOS 6.九、CentOS 7.0 進行生產環境部署,並使用了 Kong 來做爲 API 網關進行鑑權。javascript
首先,咱們須要在開發環境下安裝 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
首先修改 .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 .
由於條件所限,有些服務器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
(安裝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-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服務器上按順序執行如下腳本:
#!/bin/bash docker run -it -d --name redis \ -p 6379:6379 \ --restart=always \ redis
#/bin/bash docker run --name cassandra \ -v /data/cassandra:/var/lib/cassandra \ -d --restart=always\ -p 9042:9042 \ cassandra:3
#/bin/bash docker run --rm \ --link cassandra \ -e "KONG_DATABASE=cassandra" \ -e "KONG_CASSANDRA_CONTACT_POINTS=cassandra" \ kong:latest kong migrations up
#!/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
#/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
#/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
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"}
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
(從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
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