Build a docker image

建置一個可輸入參數的docker image,只需要有dockerfile和另一隻shell,就能決定在container執行前,輸入你所要的參數。

Dockerfile:

以下dockerfile透過ubuntu/ping的image,將ping.sh複製到container裡面,並且提供執行的權限,最後再經由ENTRYPOINT,決定執行container要呼叫的shell

1
2
3
4
5
6
7
8
FROM ubuntu/ping

MAINTAINER sparrow.jang <sparrow.jang@gmail.com>
ENV HOME=/root SERVICE_TAGS=ping
COPY ping.sh ${HOME}/ping.sh
RUN chmod +x ${HOME}/ping.sh

ENTRYPOINT ["/root/ping.sh"]

ping.sh:

如果有參數才執行ping,否則將返回一個提示文字。

1
2
3
4
5
6
#!bin/sh
if [ -z "$1" ]; then
echo "please give me a host"
else
ping $1
fi

Build a image

透過docker build就能建置一個image,最主要功用是將配置好的image,再透過dockerfile來加工成新的image

1
docker build --no-cache -t sparrow/run-ping .

Run image

執行剛建置好的docker image

1
docker run -it sparrow/run-ping www.google.com.tw

如果你不想透過剛剛的ENTRYPOINT,那你可以在執行docker run的時候,加入--entrypoint去指定。

1
docker run -it --entrypoint /bin/sh sparrow/run-ping

Push docker hub

只要在docker hub建立好repository,接著就可以執行docker push,然後在你的repository就可以看到。

1
docker push sparrow/run-ping

Mac OSX

如果你剛好開啟一個port要對外,此時你又是透過osx的系統,使用virutalbox來開啟docker,這時你就必須使用docker-machine ip default來取得真實的ip,例如拿到192.168.99.100,然後你的開啟4000port,真實port和ip就會是192.168.99.100:4000

1
docker-machine ip default

The docker basic operation

What is the docker?

docker是一個能讓你的server中,擁有乾淨的環境,以及運行各種的linux平台,例如你開啟很多web service,可能有python、php、tomcat…,這時你可透過docker,讓這些web service,都擁有各自的環境,最後透過server的apache,proxy到各項服務,至於docker跟vm有什麼不同,可以參考這篇

Pull images

docker中要使用哪個作業系統,可以透過pull這個指令,直接抓取你所需要的image來源。

假設要抓取ubuntu:

1
sudo docker pull ubuntu

之後在用images這指令去查詢目前以抓下來的source:

1
sudo docker images

會顯示以下載的image列表:

1
2
3
ubuntu                latest              8dbd9e392a96        4 months ago        131.5 MB (virtual 131.5 MB)
learn/tutorial latest 8dbd9e392a96 2 months ago 131.5 MB (virtual 131.5 MB)
learn/ping latest effb66b31edb 10 minutes ago 11.57 MB (virtual 143.1 MB)

Run

這個指令主要用來執行image裡面的指令,換句話說image已經安裝ubuntu,就可以選擇目前已經安裝的指令去執行。

像是執行linux中,拿來下指令的bash

1
sudo docker run -i -t ubuntu /bin/bash

執行之後就可以隨意在ubuntu下任何指令,像是常用的apt-get,安裝一些web server,如apache、nginx等的。

若是要開一個常駐的程式,只要在run加上-d,此時docker執行的指令就會變成常駐程式。

例如執行一個無窮迴圈的shell:

1
$JOB = $(sudo docker run -d ubuntu /bin/sh -c "while true; do echo Hello world; sleep 1; done")

$JOB會取得到一個實際執行的container id

如果要看到目前的執行狀況,可透過logs這個指令:

1
sudo docker logs $JOB

要刪除這個只要透過剛剛取得的container id即可:

1
sudo docker kill $JOB

假設要開啟一個tcp的服務,可以在開啟的時候就輸入對內port號(docker開啟的ubuntu port):

1
$JOB=$(sudo docker run -d -p 4444 ubuntu:12.10 /bin/nc -l 4444)

docker會將正在執行的port號,對應實體機器目前的port,例如docker中的4444 port,對到目前機器的127.0.0.1:49011(port範圍落在49000..49900)。

取得目前機器正在運行的port:

1
PORT=$(sudo docker port $JOB 4444 | awk -F: '{ print $2 }')

利用實際的port將訊息丟到docker的container中:

1
echo hello world | nc 127.0.0.1 $PORT

在透過logs查詢即可:

1
echo "Daemon received: $(sudo docker logs $JOB)"

Commit

docker中運行到一半的container,如果已經安裝或配置完畢,要保留目前的狀態,此時必須要把他存成一個image

先查詢目前的正在執行的container id

1
sudo docker ps

commit成image檔案:

1
sudo docker commit fb66b3 nginx/ubuntu

若是忘記就離開container也沒關係,可以透過ps -a的指令找到:

1
sudo docker ps -a

Exec

當你已經運行了一個docker image,此時可透過docker exec進入到運行中的container

1
docker exec nginx/ubuntu /bin/sh

Ps

查詢目前在正運行的container:

1
sudo docker ps

輸入參數-a,會將停止運行的container一起顯示出來:

1
sudo docker ps -a

Images

查詢目前擁有的images檔案,像是透過pull和自己commit

1
sudo docker images

Inspect

如果要查詢正在運行的container資訊,可以透過inspect,可以將目前container正在運行的資訊顯示出來,例如docker提供的虛擬的ip。

可以先透過sudo docker ps查詢container id,在執行inspect

1
sudo docker inspect a5e78640ece4

Dockerfile

如果是要下一連串的指令,而且每次都必須去執行的話,可透過dockerfile這個檔案,把你要執行的動作寫在上面,類似的案例像是,要佈署新版project時,那這時要做的可能是抓取project,執行一些build的動作,這時透過dockerfile就可以一鍵執行完,而不需要每次登到container中去修改。

首先要先建立一個,dockerfile

1
2
3
4
5
6
7
8
9
10
11
# Nginx
#
# VERSION 0.0.1

FROM ubuntu

# make sure the package repository is up to date
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update

RUN apt-get install -y inotify-tools nginx apache2 openssh-server

透過FROM去決定執行哪個image來源,然後可使用RUNCMD,去對目前的image去執行目前的bash指令。

執行dockerfile裡面內容,其中-t是要存的image目標的名稱:

1
sudo docker build -t shykes/myapp .

Export and import

如果要存成檔案可直接透過export,要匯入則是import

將目前正在運行的container id匯出成檔案:

1
docker export a1bcbabsdhb323h2b > myfile.tar

import目前的檔案,存成image來源:

1
cat myfile.tar | docker import - newimagelocal

還有滿多沒介紹的,例如push可以發布自己的image供其他人下載等的,有興趣可以深入研究。