docker container 本身並沒有 persistence 的機制,但可以透過共享 valume 的方式,將本地機器的某個實體的路徑,綁定到 container 中,由於 container 疊加式的文件檔案系統,我們還是會覺得只有一個檔案系統。
靜態網站
在 sample 目錄中,製作一個 Dockerfile 檔案
FROM ubuntu:latest
MAINTAINER yaocl
ENV REFRESHED_AT 2016-12-23
# 安裝 ngnix
RUN apt-get -yqq update && apt-get -yqq install nginx
# 建立 website 目錄
RUN mkdir -p /var/www/html/website
# 調整 nginx 設定
ADD nginx/global.conf /etc/nginx/conf.d/
ADD nginx/nginx.conf /etc/nginx/
# TCP Port 80
EXPOSE 80
另外準備兩個 nginx 設定檔:
nginx/global.conf
server {
listen 0.0.0.0:80;
server_name _;
root /var/www/html/website;
index index.html index.htm;
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;
}
nginx/nginx.conf
user www-data;
# process 數量
worker_processes 4;
# 紀錄 process id
pid /run/nginx.pid;
# 不讓 nginx 進入 daemon 狀態,以前景執行,否則會讓 container 啟動後直接停掉
daemon off;
events { }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
}
在 website 目錄,放一個 index.html 網頁。
所有檔案的目錄結構為
sample\
Dockerfile
nginx\
global.conf
nginx.conf
website\
index.html
以 build 指令產生 docker image
docker build -t yaocl/nginx .
可透過 history 查看 image 的過程
docker history yaocl/nginx
啟動 container,以 -v 將 website 目錄綁定為 container 的 /var/www/html/website 目錄,覆蓋掉原本在 image 中的那個目錄,我們就可以修改 website 的網頁,並即時由 browser 看到網頁的結果。
$ docker run -d -p 80:80 --name website \
-v $PWD/website:/var/www/html/website \
yaocl/nginx nginx
b64855fbfc6bb313c9190eeead2f1d433d28b9d759dba85d06399841e0ef9f78
如果加上 :ro ,就變成 readonly,rw 則是可讀寫
docker run -d -p 80:80 --name website \
-v $PWD/website:/var/www/html/website:ro \
yaocl/nginx nginx
連結兩個 container
如果我們需要用到兩個 containers,其中一個用來執行 application server,另一個執行 redis或 db,這時候有兩種方式,可以讓兩個 containers 可以互相連結使用服務。
我們建立一個 redis image 跟 container,另外產生一個只有 os 的 container,讓測試讓後面那個 container 可以用 redis-cli 連結到 redis server。
產生 redis db server 的 Dockerfile
FROM ubuntu:latest
MAINTAINER yaocl
ENV REFRESHED_AT 2016-12-23
RUN apt-get -yqq update && apt-get -yqq install redis-server redis-tools
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
CMD []
產生 redis image,並啟動 container
docker build -t yaocl/redis .
docker run -d -p 6379:6379 --name redis yaocl/redis
如果剛剛沒有指定主機的 port 可以用 port 指令查詢 port
$ docker port redis 6379
0.0.0.0:6379
以本機的 redis-cli 測試 redis:6379
$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379>
要從 container: redis-cli 連接到 redis,有兩種方式,一種是使用 docker 的內部網路 network stack,安裝 docker 時就會建立一個 docker0 的網路介面,每一個 docker container 都會在這個網路上分配到獨立的 172.16~172.30 這個範圍的 ip。
預設這些網路之間不能互相連接,如果搭配修改 iptables(DNAT),就可以讓 container 互相溝通,但 docker for mac 找不到 docker0 這個 network,如果要測試,可以參考 Docker container networking 的說明。
我們用另一個比較常見的方式,直接讓 container 互相連接。
在 mac 先將 lo0 綁定一個新的 ip
sudo ifconfig lo0 alias 10.200.10.1/24
首先刪除掉剛剛的 redis container
docker stop redis
docker rm redis
重新執行一個 redis container,但不指定 -p 6379
docker run -d --name redis yaocl/redis
redis-cli 的 Dockerfile
FROM ubuntu:latest
MAINTAINER yaocl
ENV REFRESHED_AT 2016-12-23
RUN apt-get update
RUN apt-get -y install inetutils-ping redis-tools
ENTRYPOINT ["/bin/bash"]
CMD []
產生 redis-cli image
docker build -t yaocl/redis-cli .
docker run --name webapp -t -i yaocl/redis-cli
如果不是用 docker for mac,可以用 link 的方式直接將 container 連接起來。
docker run --name webapp --link redis:db -t -i yaocl/redis-cli
啟動 redis-cli container webapp 後,就能直接用 db 這個 hostname 連接到 redis server
root@79bb961c2b78:/# redis-cli -h db
db:6379>
root@79bb961c2b78:/# env
HOSTNAME=79bb961c2b78
DB_NAME=/webapp/db
DB_PORT_6379_TCP_PORT=6379
TERM=xterm
DB_PORT=tcp://172.17.0.2:6379
DB_PORT_6379_TCP=tcp://172.17.0.2:6379
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
DB_ENV_REFRESHED_AT=2016-12-23
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
REFRESHED_AT=2016-12-23
PWD=/
DB_PORT_6379_TCP_ADDR=172.17.0.2
DB_PORT_6379_TCP_PROTO=tcp
SHLVL=1
HOME=/root
no_proxy=*.local, 169.254/16
DB_ENV_no_proxy=*.local, 169.254/16
_=/usr/bin/env
root@79bb961c2b78:/# ping db
PING db (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.223 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.139 ms
References
Networking your docker containers using docker0 bridge
沒有留言:
張貼留言