原lnmp環境服務器升級為mysql+nginx+php單個docker容器構建的lnmp環境
時間:2018年2月
一.項目背景
我單位現web服務架構為lnmp環境,服務器軟件、硬件升級部署難;同時開源軟件日新月異,考慮到技術升級,領導決定服務器架構整體升級為容器架構,維護性、移植性強。
二.項目說明
原服務器架構為lnmp環境,服務器運行穩定,升級為容器架構,應平穩過度;采用單個鏡像逐個構造容器,將容器互聯,部署為lnmp環境;原服務器項目代碼、配置文件,數據庫數據等采用數據掛載方式與容器互聯,訪問端口采用端口映射方式,實現客戶訪問。
三.實施步驟
1.鏡像構造
1)mysql鏡像構造
我們采用dockerfile 構造vim Dockerfile
FROM mysql:5.7
MAINTAINER yst <[email protected]>
ENV TZ "Asia/Shanghai"
基礎鏡像為mysql5.7
docker build -t mysql .
build 為構造鏡像, mysql 為鏡像的倉庫及標簽,.為當前路徑
出現success就代表成功了。
2)php鏡像構造
vim Dockerfile
FROM centos:centos7 #以centos7為基礎
MAINTAINER yst <[email protected]> #制作者
ENV TZ "Asia/Shanghai" #時區
#安裝依賴包
RUN yum -y install libxml2-devel libmcrypt-devel libmcrypt mcrypt mhash libjpeg libjpeg-devel libpng libpng-devel net-tools gcc gcc-c++ make
ADD php-5.6.36.tar.gz / #拷貝安裝包
#運行源碼包安裝程序
RUN cd /php-5.6.36 && ./configure --prefix=/usr/local/php --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --enable-mbstring --with-zlib --with-libxml-dir=/usr --enable-xml --enable-fpm --with-gd && make && make install
#復制文件
RUN cp /php-5.6.36/php.ini-production /usr/local/php/etc/php.ini
RUN cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
#配置php
RUN useradd -M -s /sbin/nologin php
#修改配置文件
RUN sed -i -e ‘s\;pid = run/php-fpm.pid\pid = run/php-fpm.pid\g‘ -e ‘s\nobody\php\g‘ -e ‘s\listen = 127.0.0.1:9000\listen = 0.0.0.0:9000\g‘ /usr/local/php/etc/php-fpm.conf
RUN sed -i ‘s\;daemonize = yes\daemonize = no\g‘ /usr/local/php/etc/php-fpm.conf
EXPOSE 9000 #暴露端口
CMD ["/usr/local/php/sbin/php-fpm"] #啟動php-fpm
docker build -t php .
3)nginx 鏡像構造
先寫好配置文件nginx.conf
vim nginx.conf
user nginx; worker_processes 1;
error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;
pid logs/nginx.pid;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;
access_log logs/access.log main;
sendfile on; #tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
#存放網頁代碼目錄
root html;
index index.php index.html index.htm;
}
# redirect server error pages to the static page /50x.html
#重定向到錯誤頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
#如果結尾為.php 文件,轉向容器名為php的容器,由該容器負責.php,並且端口為9000,
location ~ \.php$ {
root html;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /$document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
from centos:centos7
MAINTAINER yst [email protected]
RUN yum -y install gcc gcc-c++ pcre-devel zlib-devel make
RUN useradd nginx -s /sbin/nologin
ADD nginx-1.10.3.tar.gz /
RUN cd /nginx-1.10.3 && ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_gzip_static_module --with-pcre && make && make install
#創建日誌目錄
RUN mkdir /var/log/nginx
#拷貝配置文件
ADD nginx.conf /usr/local/nginx/conf/nginx.conf #將寫好的配置文件添加到鏡像中
EXPOSE 80 443
ENTRYPOINT ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"] #以守護進程方式運行nginx
docker build -t nginx .
2.生成並運行容器
因為要升級為 docker 環境的lnmp,要以數據庫為後臺,所以要先生成數據庫容器,再生成PHP容器,最後生成Nginx容器。
1)運行並啟動mysql容器
docker run -d -it --name mysql -p 3306:3306 -v /root/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql
-d :以守護進程運行容器
-i :讓容器的輸入保持打開
-t : 分配一個偽終端
--name:為該容器的名字
-p:為宿主機的端口映射到容器的端口
-e:設置數據庫登錄root密碼
-v 掛載宿主機/root/bo/data/mysql到容器的/var/lib/mysql,也就是宿主機與容器實現數據同步
最後的mysql 為鏡像的倉庫名及標簽
2)運行並啟動PHP容器
docker run -d -it --name php -p 9000:9000 -v /root/php/data/:/usr/local/nginx/html --link mysql:mysql php
-v : 此處為宿主機的目錄掛載到nginx容器中nginx 安裝目錄的網頁代碼存放目錄,把.php為結尾的代碼文件掛載映射到該目錄
可把原舊lnmp服務器中的代碼遷移至該宿主機,實現數據與容器的互聯
--link :為連接mysql 容器,名字為mysql
3)運行並啟動nginx容器
docker run -d -it --name nginx -p 80:80 -v /root/nginx/data:/usr/local/nginx/html --link php:php nginx
--link :為連接PHP容器,名字為php
-v : 映射宿主機存放網頁代碼路徑到容器的Nginx安裝目錄的放網頁代碼目錄,可把原舊lnmp服務器中的代碼遷移至該宿主機,實現數據與容器的互聯
3.測試
1)準備 index.html,index.php,test.php
分別為普通網頁文件,PHP網頁文件,測試PHP與mysql連通的測試文件
vim index.html
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
vim index.php
<?php
phpinfo();
?>
此處mysql版本為5.7,所以測試代碼為mysqli_connect(‘為宿主機中的容器名字:對應的宿主機端口‘,‘登錄服務器的用戶名‘,‘密碼‘)
如果是其他版本,語句會不同
mysqli_close($link);為關閉連接
vim test.php
<?php
$link=mysqli_connect(‘mysql:3306‘,‘root‘,‘123456‘);
if($link) echo "連接成功";
mysqli_close($link);
?>
2)訪問測試
打開瀏覽器,輸入http://宿主機的ip回車
顯示我們準備的index.html
輸入http://宿主機的ip/index.php回車
輸入http://宿主機的ip/test.php回車
3)數據庫操作測試
打開navicat for mysql
建立新的連接
主機名為宿主機的ip,此處為什麽為宿主機的ip呢,因為,數據庫容器建立在該主機上,而宿主機與容器在運行容器時已用參數-p 3306:3306進行了端口映射,所以,訪問宿主機的3306就相當於訪問容器的3306端口,也就是訪問mysql容器的mysql服務。
用戶名為root
密碼為我們在運行容器時,-e MYSQL_ROOT_PASSWORD=123456設置的root的密碼123456
建立好連接,我們就可以在Windows桌面對容器進行操作了,操作的結果都會反饋到容器內,從而實現數據互聯。
4.總結
項目難點
1)如何生成合適的鏡像
mysql 鏡像是我們在docker鏡像庫中下載mysql純凈鏡像,docker tag 命令將原鏡像標簽標記為我們自己的命名
PHP鏡像是以centos7純凈鏡像為基礎,通過源碼安裝,配置好配置文件,並開啟端口而構建的
nginx 鏡像是以centos7純凈鏡像為基礎,通過源碼安裝,修改配置文件,開啟端口而構建的
2)如何正確啟動鏡像並運行容器
先開啟mysql容器;開啟php容器及nginx容器時,發生
容器運行命令執行後,容器就關閉了,這不是我們要的結果,我們希望容器要一直運行服務,我們才能訪問容器內的服務。
我們從查詢鏡像生成文件dockerfile 文件開始,一步步查找原因,經過反復試驗,不斷生成鏡像,運行容器,我發現在生成鏡像的最後,我們一定要開啟在該鏡像中的服務,比如PHP鏡像,我們在運行容器時,需要在容器中開啟php-fpm服務,這就需要我們在創建竟像時,開啟這個服務進程,就是
CMD ["/usr/local/php/sbin/php-fpm"];而nginx 容器運行時出現同樣問題,反復查詢,調試,應在生成鏡像時要執行入口命令
ENTRYPOINT ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"],或在執行運行容器的命令加入--restart=always參數否則在容器啟動運行完入口名,容器也會停止。
3)如何連接各個容器
單個容器,每個容器提供有每個的服務功能,這是docker容器的一個容器一個功能,也是 docker 容器的優點所在,每個容器提供的服務封裝起來,用的時候運行它,不用的時候可以遷移,拷貝到哪裏都可以提供服務。我們如何實現它,就是用--ling參數,將有關聯的幾個容器互聯起來,一起完成一個更加強大的服務功能。
比如:構建容器環境的lnmp,需要mysql,php,nginx等幾個容器提供的服務,需要將幾個容器連接起來一同完成 lnmp服務
docker run -d -it --name nginx -p 80:80 -v /root/nginx/data:/ usr/local/nginx/html --link php:php --link mysql: mysql nginx
原lnmp環境服務器升級為mysql+nginx+php單個docker容器構建的lnmp環境