前言
老實說,不用Docker來架設nginx服務器,是更方便的。
sudo apt-get install nginx
當然,如果你要指定最新版本,會麻煩一些,需要從源碼編譯安裝,但也復雜不到哪兒去。
Docker的優(yōu)勢是便于大規(guī)模部署。個人或小公司的單臺、幾臺服務器的部署,直接安裝可能更方便一些,解決問題也更便捷一些。我作為一個個人用戶,用Docker更多是一種學習、或者趣向。
本文主旨是展示一次簡單的docker使用過程,不對原理做出過多描述。默認讀者已經(jīng)知道Nginx、Docker的基本概念,已經(jīng)具備一臺(Debian/Ubutu系的)Linux服務器或本地電腦,并且已經(jīng)安裝了docker、docker-compose。
Nginx的Docker鏡像
雖然,從基礎鏡像開始,自行寫一個Dockerfile,然后通過docker build來創(chuàng)建一個Docker鏡像,也并不是太難。但是,這很繁瑣,足以嚇跑三分之二的初學者,并且未必能收到最好的部署效果。
一般要用Docker安裝一個東西的第一個步驟是,看看已經(jīng)有什么鏡像。
$ sudo docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 5358 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker c... 947 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 349 [OK]
jrcs/letsencrypt-nginx-proxy-companion LetsEncrypt container to use with nginx as... 149 [OK]
……
事實是,常用鏡像、或者新鮮出爐的服務,都早已有人做好了鏡像。像Nginx這樣的,還有官方(Official)鏡像。
$ sudo docker pull nginx
這樣,官方鏡像已輕松收入囊中。
鏡像版本的選擇
默認情況下,鏡像的tag是latest。這是個類似git的master分支的東西,往往是最新版本的鏡像。最新,意味著不穩(wěn)定。個人折騰時無所謂,如果是正式部署,還是需要追求穩(wěn)定。
對目前(2017年2月)的Nginx來說,有以下常用鏡像可供選擇:
1.11.10,mainline,1,1.11, latest (mainline/jessie/Dockerfile)1.11.10-alpine,mainline-alpine,1-alpine,1.11-alpine, alpine (mainline/alpine/Dockerfile)1.10.3,stable,1.10(stable/jessie/Dockerfile)1.10.3-alpine,stable-alpine,1.10-alpine(stable/alpine/Dockerfile)
我個人傾向于選擇stable-alpine,它遠比普通基于Debian制作的鏡像要小得多。
This image is based on the popular Alpine Linux project, available in the alpine official image. Alpine Linux is much smaller than most distribution base images (~5MB), and thus leads to much slimmer images in general.
Nginx的Debian與Alpine鏡像的比較:
| 基礎鏡像 | Docker Hub 大?。▔嚎s狀態(tài)) | 本地大?。ń鈮籂顟B(tài)) |
|---|---|---|
| Debian | 72 MB | 181.5 MB |
| Alpine | 18 MB | 57.18 MB |
雖然沒有詳細比較過運行時的性能差異,不過僅鏡像大小差異就足夠初次使用者做出選擇了。
Alpine這個冷門的Linux發(fā)行版,在Docker時代似乎正在開始流行起來。
使用docker-compose
直接使用docker run命令來運行一個容器,是比較麻煩的。
sudo docker run \
-p 80:80 \
-v /srv/nginx/nginx.conf:/etc/nginx/nginx.conf \
...
-d
nginx:stable-alpine
這么長的命令,是不適合在命令行敲的。所以,通常需要寫到一個shell文件里。
既然需要一個文件,為何不用docker-compose呢?
# vim: set shiftwidth=2 tabstop=2 softtabstop=-1 expandtab:
version: '2'
services:
nginx:
image: nginx:stable-alpine
restart: unless-stopped
network_mode: host
volumes:
- /srv/nginx/nginx.conf:/etc/nginx/nginx.conf
- /srv/nginx/conf.d:/etc/nginx/conf.d
- /srv/nginx/html:/usr/share/nginx/html
- /var/log/nginx:/var/log/nginx
ports:
- "80:80"
environment:
- NGINX_HOST=your.domain
- NGINX_PORT=80
將上述內(nèi)容,寫入一個docker-compose.yml文件。在同級目錄,執(zhí)行sudo docker-compose up,即可等價于一個超復雜的docker run ...。
docker-compose最擅長的是描述一組容器的配置與關(guān)系,同時啟動或關(guān)閉。但如果單個容器的配置也很復雜,我也傾向于使用它。
內(nèi)容管理
玩Nginx,主要就是改它的配置。在最近的版本中,默認配置是在/etc/nginx/nginx.conf,而默認的的網(wǎng)頁是在/usr/share/nginx/html。
我看過一些其它的教程,是基于官方鏡像,把自己的配置復制進去,build出一個新的鏡像,然后再運行。這樣的方案不太好,多加了一層,還不利于更新。
其實,把主機上需要修改和配置的內(nèi)容,變成數(shù)據(jù)卷(Volume)掛載到容器中就好了,就如我前面的docker-compose配置。
volumes:
- /srv/nginx/nginx.conf:/etc/nginx/nginx.conf
- /srv/nginx/conf.d:/etc/nginx/conf.d
- /srv/nginx/html:/usr/share/nginx/html
- /var/log/nginx:/var/log/nginx
雖然從實現(xiàn)技術(shù)來說,是把主機的目錄作為Volumn掛載到容器中去,但我還是更喜歡看做是把容器內(nèi)的東西,映射到外面的主機上來,就像軟鏈接一樣。所謂理解,就是用簡單代表復雜,用熟悉解釋陌生。
這里,所有內(nèi)容都放到主機的/srv/nginx目錄下,讓掛載進容器使用;而/var那邊,相當于把log也映射出來。這樣,在主機上也可以方便地修改配置與網(wǎng)頁,并且可以查看log。
如果考慮到更方便的部署與遷移,甚至可以把Nginx的配置與docker-compose.yml放在同一個目錄,組成一個Git庫。volumes參數(shù),也可改成相對路徑。然后,三條命令就可以在一臺機器上部署一個網(wǎng)站。
git clone git@server:repo/name.git Website
cd Website
sudo docker-compose up
這樣的部署方案,如此簡潔,以致優(yōu)雅。
參考
- Nginx的Docker頁面:https://hub.docker.com/r/library/nginx/
- Nginx的Dockerfile的GitHub頁面:
https://github.com/nginxinc/docker-nginx - 《Docker 安裝 Nginx》
- 《Docker — 從入門到實踐》
附錄
最后,以審美的目光,欣賞一下Nginx的stable鏡像的Dockerfile。
FROM debian:jessie
MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com"
ENV NGINX_VERSION 1.10.3-1~jessie
RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \
&& echo "deb http://nginx.org/packages/debian/ jessie nginx" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
ca-certificates \
nginx=${NGINX_VERSION} \
nginx-module-xslt \
nginx-module-geoip \
nginx-module-image-filter \
nginx-module-perl \
nginx-module-njs \
gettext-base \
&& rm -rf /var/lib/apt/lists/*
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
該文件地址:
https://github.com/nginxinc/docker-nginx/tree/master/stable/jessie
曾經(jīng)有個想法,要把一些復雜的軟件安裝的過程,從最初始的發(fā)行版開始腳本化,以便于二次安裝、移植、大規(guī)模部署、調(diào)試、除錯……
這些,Docker都以更優(yōu)雅的方式實現(xiàn)了。
集裝箱改變世界。