本地構(gòu)建web開發(fā)環(huán)境
生成一個(gè)鏡像一般有兩種方式:
- 以一個(gè)鏡像為基礎(chǔ),修改他的容器,最終將修改后的容器提交,成為新的鏡像;
- 撰寫Dockerfile,通過(guò)docker build,一步生成最終想要的鏡像。
不論是哪種方式生成的鏡像,都可以最終被上傳到鏡像托管服務(wù),并在任何一處能夠運(yùn)行docker的環(huán)境下拉取,并運(yùn)行起來(lái)。
一步步自己修改
首先把centos的源拉下來(lái)(使用了daocloud的鏡像):
docker pull daocloud.io/library/centos:6
然后就可以把centos跑起來(lái)啦:
docker run -i -t -p 80 centos /bin/bash
跑起來(lái)的同時(shí)指定了容器的映射端口80。跑起來(lái)之后,在你面前的就是一個(gè)centos,你可以像操作任意一臺(tái)linux的機(jī)器一樣,在里面裝軟件,傳文件進(jìn)去,編譯、checkout代碼等等一系列的事情。
查看container的id:
docker ps
最終創(chuàng)建一個(gè)自己的鏡像:
docker commit -m "web-dev" -a "meijing0114" 86963dfef869 meijing0114/centos-web-dev
接下來(lái)要著重說(shuō)一說(shuō)利用Dockerfile的這種方式,因?yàn)樗粍谟酪荨?/p>
撰寫Dockerfile
首先鏈接docker:
$ docker-machine ssh development
隨后創(chuàng)建一個(gè)目錄:
$ mkdir mydocker
進(jìn)入目錄并打開Dockerfile:
$ cd mydocker$ vim ./Dockerfile
本文主要把Dockerfile分成了幾個(gè)部分,第一部分是一些基礎(chǔ)的設(shè)置,第二部分涉及到php相關(guān)的環(huán)境,第三部分涉及到nginx相關(guān)的環(huán)境,第四部分則是預(yù)留之后的擴(kuò)展,現(xiàn)在放了一些端口暴露的配置。#標(biāo)識(shí)注釋。
dockerfile的第一部分
先來(lái)看第一部分的內(nèi)容:
# 以daocloud提供的centos6為基準(zhǔn),daocloud是國(guó)內(nèi)一家提供鏡像托管等服務(wù)的公司
FROM daocloud.io/library/centos:6
# 聲明維護(hù)者
MAINTAINER meijing0114 <525937005@qq.com>
# 設(shè)置兩個(gè)環(huán)境變量
ENV src-dir /data/sourcesENV run-dir /data/env/runtime
# 安裝必須的軟件包
RUN yum install -y \
git \
svn \
vim \
wget \
gcc \
gcc-c++ \
m4 \
openssl \
openssl-devel \
zlib \
pcre \
pcre-devel \
&& yum clean all
# 創(chuàng)建必須的文件夾:
RUN mkdir /data \
&& mkdir /data/admin \
&& mkdir /data/env \
&& mkdir /data/env/runtime \
&& mkdir /data/sources \
&& mkdir /data/logs \
&& chmod 666 /data/logs
FROM命令說(shuō)明了本鏡像是基于哪個(gè)鏡像的;
ENV命令設(shè)置環(huán)境變量,為了之后的命令進(jìn)行替換;
RUN命令一般有兩種形式:
-
RUN <command>: 等價(jià)于在shell中執(zhí)行命令 -
RUN ["executable", "param1", "param2"]:可以用來(lái)指定執(zhí)行的shell, 適用于沒有shell的情況RUN命令的結(jié)果會(huì)在base image上一層層的進(jìn)行疊加,""可以用來(lái)一次執(zhí)行多個(gè)命令,同時(shí)由于docker會(huì)有cache,所以多使用""的方式把命令寫在一起,能夠避免docker錯(cuò)誤的cache住諸如“apt-update”這類命令。
如果你想要指定執(zhí)行的shell,也可以通過(guò)如下的方式:
RUN ["/bin/bash", "-c", "echo hello"]
需要注意的是RUN命令和CMD以及ENTRYPOINT命令的差異,后面的兩個(gè)命令是在容器啟動(dòng)了之后進(jìn)行運(yùn)行的。
第二部分
這部分是針對(duì)php的一些操作,主要是php附屬的libmcrypt等必備庫(kù)的解壓、編譯和安裝。然后還有基本php的配置文件的創(chuàng)建、修改。
############################### 下載(拷貝)php的依賴包編譯安裝
# 拷貝libmcrypt的包并編譯
ADD libmcrypt-2.5.8.tar.gz $src-dirWORKDIR $src-dir/libmcrypt-2.5.8RUN ./configure --prefix=/data/env/runtime/libmcrypt-2.5.8 \&& make \&& make install \&& make clean # php本身ADD ./php-5.5.30.tar.gz $src-dirWORKDIR $src-dir/php-5.5.30RUN ./configure --prefix=/data/env/runtime/php-5.5.30 --with-config-file-path=/data/env/runtime/php-5.5.30/etc --enable-opcache --enable-fpm --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --enable-xml --enable-pcntl --with-gettext=shared --enable-sysvmsg --enable-sysvshm --enable-sysvsem --enable-sockets --enable-mbstring --enable-soap --enable-bcmath --enable-zip --enable-libxml --with-curl --with-gmp --with-mcrypt=/data/env/runtime/libmcrypt-2.5.8 --with-openssl --with-zlib= \
&& make \
&& make install \
&& make clean
# 更改php配置文件(拷貝一個(gè)過(guò)來(lái))
COPY ./etc/php.ini /data/env/runtime/php-5.5.30/etc/
# php-fpm配置文件拷貝
COPY ./etc/php-fpm.conf /data/env/runtime/php-5.5.30/etc/
# 拷貝php擴(kuò)展
COPY ./ext/swoole.so /data/env/runtime/php-5.5.30/lib/php/extensions/no-debug-non-zts-20121212/
這里值得一提的是ADD命令,相比于COPY命令,ADD命令能做的更多。它可以接受第一個(gè)url的參數(shù),同時(shí)如果輸入的文件是可識(shí)別的壓縮格式的話,它同時(shí)還會(huì)把相應(yīng)的文件解壓。而COPY則是一個(gè)簡(jiǎn)單的復(fù)制。
第三部分
這部分包括了nginx的附屬庫(kù)和nginx本身的編譯安裝:
############################################## 下載(拷貝)nginx的依賴包并編譯安裝
# nginx 本身的編譯,增加了debug
ADD ./nginx-1.10.1.tar.gz $src-dir RUN /data/sources/nginx-1.10.1/configure --prefix=/data/env/runtime/nginx-1.10.1 --with-http_sub_module --with-http_realip_module --with-debug --with-http_ssl_module \
&& make \
&& make install \
&& make clean# nginx基本配置文件
第四部分
# 軟鏈,環(huán)境變量,aliasRUN echo -e "export PATH=/data/env/runtime/php-5.5.30/bin/:$PATH\n" >> /etc/profile \
"export PATH=/data/env/runtime/nginx/sbin:/data/website/qidian.com/framework/tsf/tsf2.0/bin:$PATH\n" >> /etc/profile \
"export QD_TSF_ENV=dev" >> /etc/profile \
RUN ln -s /data/env/runtime/nginx-1.10.1 /usr/local/nginx
RUN ln -s /data/env/runtime/php-5.5.30 /usr/local/php
# 暴露出80端口訪問(wèn)
EXPOSE 80 \443
# 清理文件
RUN rm -r /data/sources
# 啟動(dòng)Nginx
COPY ./admin/start.sh /data/admin/start.sh
RUN chmod 755 /data/admin/start.sh
# 指定工作目錄WORKDIR
/data/adminCMD ["./start.sh"]
創(chuàng)建、提交和分布鏡像
在build之前,需要將所有必須的源碼壓縮包、配置文件、腳本等都拷入這個(gè)目錄中,如libmcrypt等:Dockerfile當(dāng)前目錄下執(zhí)行:
docker build -t centos-web-dev .
完成本地鏡像構(gòu)建之后,接下來(lái)可以分享到dockerhub和阿里云hub。
查看已經(jīng)構(gòu)建的本地鏡像id:
docker images

經(jīng)過(guò)一些清理之后,image的大小被壓到700MB,應(yīng)該還可以再小一些。
docker-hub
為了跟docker hub里面的對(duì)應(yīng)上,必須重命名一下本地的REPOSITORY
docker tag cf34378f61c3 meijing/centos-web-dev:latest
接下來(lái)登陸docker hub:
docker login --username=yourhubusername --email=youremail@company.com
然后docker push meijing/centos-web-dev
阿里云hub
將鏡像提交到阿里鏡像進(jìn)行托管:
sudo docker login --username=525937005@qq.com registry.aliyuncs.com
$ sudo docker tag [ImageId] registry.aliyuncs.com/meijing0114/centos-web-dev
$ sudo docker push registry.aliyuncs.com/meijing0114/centos-web-dev
為了避免鏡像太大,開發(fā)代碼就進(jìn)行另外的托管了。
只需要執(zhí)行如下命令,就可以隨時(shí)隨地使用鏡像了:
docker run -i -t -P centos-web-dev /bin/bash
進(jìn)入鏡像,然后將nginx啟動(dòng)起來(lái)。注意這里使用-P將兩個(gè)端口80和443,都暴露了出來(lái),如圖所示:

再查看一下docker-machine的ip:docker-machine ip development
那么在瀏覽器輸入192.168.99.100:32769以直接看到nginx的頁(yè)面了:

最終,我們搭建了一個(gè)能夠運(yùn)行php,nginx以及我們web框架
的的web開發(fā)環(huán)境。最終生成的Dockerfile可以在github:https://github.com/meijing0114/dockerfiles-web 看到。