--- tags: Docker --- # Creating a new image from an existing container with a Dockerfile ##### `Docker` `Dockerfile` > [name=Mr. Akashic] [time=Wed, Jun 16, 2021] ## Prerequisites * 申請一個[Docker Hub](https://hub.docker.com/)的帳號。 * 在要製作新image的系統上,使用指令docker login登入docker hub。 ## Implementation 1. 在Raspbian桌面上建立一個資料夾,在資料夾內建立一個檔名叫Dockerfile(一定要是這個名字)的文件和修改好的gateway.py檔案。資料夾結構如下圖。 ![](https://i.imgur.com/mgSLy10.png) 2. 編輯Dockerfile,完成後儲存,內容如下: ```dockerfile= # The line below states we will base a new image on the Latest zewelor/bt-mqtt-gateway. FROM zewelor/bt-mqtt-gateway:latest # Update pip tool RUN /usr/local/bin/python -m pip install --upgrade pip # Install these packages for Python development environment RUN apk add --no-cache gcc g++ python3 python3-dev py-pip mysql-dev linux-headers libffi-dev openssl-dev # Install evdev package RUN pip3 install evdev # Update gateway.py COPY gateway.py /application/gateway.py # This is the command that will run when the Container starts CMD ["/bin/sh"] ``` :::info :warning: **注意:** Docker can only access files present below the directory where Dockerfile is present. </div> ::: 3. 開啟terminal輸入指令<span class="dark_orange">docker build -t akashic0616/bt-mqtt-gateway .</span>開始重建一個新的docker image。其中<span class="dark_orange">-t</span>參數是tag的意思,後面要接新的docker image的名字,格式通常為name或name:tag。執行畫面如下。 ``` ending build context to Docker daemon 5.632kB Step 1/6 : FROM zewelor/bt-mqtt-gateway:latest ---> 4d03df950fcb Step 2/6 : RUN /usr/local/bin/python -m pip install --upgrade pip ---> Using cache ---> b46130236d8f Step 3/6 : RUN apk add --no-cache gcc g++ python3 python3-dev py-pip mysql-dev linux-headers libffi-dev openssl-dev ---> Using cache ---> 3e42ad5a1b3b Step 4/6 : RUN pip3 install evdev ---> Using cache ---> 6011c478fa4e Step 5/6 : COPY gateway.py /application/gateway.py ---> e19c2cff6e2b Step 6/6 : CMD ["/bin/sh"] ---> Running in b3cca99b617f Removing intermediate container b3cca99b617f ---> 51dbd11cc956 Successfully built 51dbd11cc956 Successfully tagged akashic0616/bt-mqtt-gateway:latest ``` :::info :warning: **注意:** 新的docker image的名字有一個<span class="dark_orange">/</span>,<span class="dark_orange">/</span>前面的名字一定要是自己docker hub的帳號名稱,否則無法上傳到自己的docker hub。像是我的docker hub名稱為akashic0616,所以新的docker image名字就是akashic0616/bt-mqtt-gateway。 ![](https://i.imgur.com/iLZg9Dy.png) </div> 4. 建立完成後,輸入<span class="dark_orange">docker images</span>指令,可以看到本機現有的docker images多了一個剛剛建立的docker image。 ``` REPOSITORY TAG IMAGE ID CREATED SIZE akashic0616/bt-mqtt-gateway latest 51dbd11cc956 2 minutes ago 321MB ``` 5. 使用<span class="dark_orange">docker push akashic0616/bt-mqtt-gateway</span>指令將剛建立docker image上傳到docker hub自己的帳號。之後,就可以把這個docker image寫在docker-compose.yml來建立docker container執行服務了。 ``` Using default tag: latest The push refers to repository [docker.io/akashic0616/bt-mqtt-gateway] a8b6d4130bbe: Preparing 01f42319bced: Preparing 53957c9e8621: Preparing 7a18658f5782: Preparing 90818dec03dd: Preparing 53957c9e8621: Pushing [> ] 2.133MB/246.3MB 566c9614a31a: Layer already exists 5bf1f80e129a: Layer already exists ....more ``` 這樣就完成了本篇記錄的實作,[完整範例](https://github.com/awlchang/Creating-a-new-image-from-an-existing-container-with-a-Dockerfile.git)。 ## Introduction 本篇記錄如何用其他貢獻者的docker container作為基礎,來修改container的內容,然後重建一個新的docker image。 建立一個客製化docker image的方式有兩種: * <span class="dark_orange">docker commit [container_id]</span> 較不推薦使用此方式,原因參考<a href="#s1"><sup>[1]</sup></a>。 * 撰寫Dockerfile (本篇記錄的方式) 製作完客製化的docker image後,希望能夠提供的其他使用者使用,因此會將完成的docker image上傳到Docker Hub。 本篇實作的情境是在Raspbian作業系統上修改[zewelor/bt-mqtt-gateway](https://hub.docker.com/r/zewelor/bt-mqtt-gateway)的container,修改內容為下列幾點: * 更新pip套件管理工具 * 安裝Python開發環境用到的libraries * 安裝evdev套件 * 更新gateway.py檔案 ## Supplement Stop / remove all Docker containers ``` docker stop $(docker ps -a -q) docker rm $(docker ps -a -q) ``` ## Acknowledgements 1. [使用 Dockerfile 定制镜像](https://yeasy.gitbook.io/docker_practice/image/build)<div id="s1"></div> 2. [Docker Run: How to create images from an application](https://www.mirantis.com/blog/how-do-i-create-a-new-docker-image-for-my-application/) 3. [把 Docker Image Push 到 Docker Hub](https://ithelp.ithome.com.tw/articles/10191139) <style> .dark_orange { color: #FF8C00; background:#F6F6F6; border-radius:4px; padding-right:6px; padding-left:6px; } .sub_title { font-size: 25px; } .blockquote { background:#F6F6F6; } </style>