Dockerfile
定義容器內環境中發生的事情。對網絡接口和磁盤驅動器等資源的訪問在此環境中進行虛擬化,該環境與系統的其他部分隔離,因此您需要將端口映射到外部世界,並具體說明要“復制”哪些文件到該環境。但是,在執行此操作之后,您可以預期Dockerfile
在此處定義的應用程序的構建 在其運行的任何位置都完全相同。
1. 快速測試Docker環境是否可用
docker run hello-world
2. 創建Dockerfile文件
在一個空目錄中創建一個名為Dockerfile的文件,內容如下:
# 使用官方的Python環境作為父鏡像 FROM python # 設置工作目錄為 /app WORKDIR /app # 拷貝當前目錄下的文件到容器的/app目錄下 COPY . /app # 在容器中運行下面命令安裝 requirements.txt中的軟件 RUN pip install --trusted-host pypi.python.org -r requirements.txt # 暴露80端口到容器外部 EXPOSE 80 # 定義一個環境變量 ENV NAME World # 當容器啟動時,運行'python app.py' CMD ["python", "app.py"]
3. 在該目錄下繼續創建一個Flask應用程序和安裝文件清單
app.py
from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) app = Flask(__name__) @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
requirements.txt
Flask Redis
4. 構建應用程序
我們准備構建應用程序。確保您仍處於新目錄的頂層。這是ls
應該顯示的內容:
$ ls Dockerfile app.py requirements.txt
創建一個Docker鏡像,我們將使用該--tag或者-t
選項命名鏡像
docker build --tag=friendlyhello .
查看創建的鏡像
root@node1 docker]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE friendlyhello latest 67bd580f29b8 21 seconds ago 937MB
Linux用戶的故障排除
- 代理服務器設置
代理服務器可以在Web應用程序啟動並運行后阻止其連接。如果您位於代理服務器后面,請使用以下ENV
命令將以下行添加到Dockerfile中,以指定代理服務器的主機和端口:
# Set proxy server, replace host:port with values for your servers ENV http_proxy host:port ENV https_proxy host:port
- DNS設置
DNS配置錯誤可能會產生問題pip
。您需要設置自己的DNS服務器地址才能pip
正常工作。您可能想要更改Docker守護程序的DNS設置。您可以/etc/docker/daemon.json
使用dns
密鑰編輯(或創建)配置文件,如下所示:
{ "dns": ["your_dns_address", "8.8.8.8"] }
在上面的示例中,列表的第一個元素是DNS服務器的地址。第二項是Google的DNS,可在第一項無法使用時使用。
在繼續之前,請保存daemon.json
並重新啟動docker服務。
sudo service docker restart
修復后,重試運行該build
命令。
5. 運行應用程序
運行應用程序,使用以下方法將計算機的端口4000映射到容器的已發布端口80,-p是將容器的端口Publish到外部的意思。
docker run -p 4000:80 friendlyhello
在瀏覽器訪問‘http://localhost:4000’即可訪問到內部的應用程序,按Ctrl+c即可結束應用程序。
后台以分離模式運行應用程序,-d就是在后台運行鏡像,並打印出容器ID
docker run -d -p 4000:80 friendlyhello
6. 停止應用程序所在容器的運行
docker container stop ID
7. 分享鏡像
如果沒有Docker帳戶,請在hub.docker.com上注冊一個帳戶 ,並記下的用戶名。
1. 在本地的計算機上登錄
docker login
2. 將鏡像打上標簽,該命令的語法是:
docker tag image username/repository:tag
比如我的登錄名為scottcho,將版本庫命名為flask,tag為v1
[root@node1 docker]# docker tag friendlyhello scottcho/flask:v1 [root@node1 docker]# docker image ls scottcho/flask REPOSITORY TAG IMAGE ID CREATED SIZE scottcho/flask v1 67bd580f29b8 30 minutes ago 937MB
3. 發布鏡像
docker push scottcho/flask:v1
在docker hup上可以看見所創建的鏡像
4. 在任何計算機上可以運行分享的鏡像
如果映像在本地不可用,則Docker會從存儲庫中提取映像。
docker run -p 4000:80 scottcho/flask:v1
查看容器內的改變信息
創建一個容器,會在容器的對應的鏡像上增加一個可寫層,鏡像部分是只讀的。通過 diff命令可以看出改變的信息。如:
[root@wls12c ~]$ docker run -i -t centos /bin/bash [root@224de7986c5f /]# touch demo.ext [root@224de7986c5f /]# echo hello docker >demo.ext [root@224de7986c5f /]# rm -rf anaconda-post.log [root@224de7986c5f /]# exit exit [root@wls12c ~]$ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 224de7986c5f centos "/bin/bash" 40 seconds ago Exited (0) 3 seconds ago desperate_curie [root@wls12c ~]$ docker diff 224d D /anaconda-post.log A /demo.ext C /root A /root/.bash_history
說明:每行代表一個變動的文件或目錄。其中 A 表示新增、C表示被修改、D表示被刪除
主機和容器之間的文件拷貝
容器--->主機
[root@wls12c ~]$ docker exec -t -i 9f bin/bash [root@9f49397623ad /]# cat demo.txt hello [root@9f49397623ad /]# exit exit
[root@wls12c ~]$ docker cp 9f:/demo.txt /test [root@wls12c ~]$ cat /test/demo.txt hello
主機-->容器
[root@wls12c ~]$ cp ~/1.txt /var/lib/docker/aufs/mnt/9f49397623ade7dfd2beb4d84454cbdb9878a4b22a2bab2e8b5db72bcffe60a0/test [root@wls12c ~]$ docker exec -t -i 9f /bin/bash [root@9f49397623ad /]# ls /test 1.txt
重命名容器
[root@wls12c ~]$ docker rename stoic_meitner demo