# Docker 實戰 2 - 相關指令與Dockerfile ## 前言 前一篇和大家介紹了什麼是Docker,如果還沒看過的可以先去看一下 [Docker 實戰 1 - 五分鐘了解 Docker](/lo88XIBlTiGJeiUDs8JmFw) 本篇會告訴大家如何下載Docker及相關指令,最後教大家撰寫Dockerfile,就可以執行屬於自己的docker container了! ## 安裝 - Docker 有支援 Linux、Mac 跟 Windows,到 [Get Docker](https://docs.docker.com/get-docker/) 安裝即可,之後在cmd輸入docker version,有跑出版本就代表成功! - 官方下載[Docker桌面版](https://www.docker.com/):包含GUI介面,管理方便,剛開始對於指令不熟的時候也可以從介面操作,會降低很多門檻! - 透過介面可以看到所有本地端的container,image和volumes  ## 常用指令 如果不使用GUI介面當然也可以查看相關內容 - 查看運行中的conatiner docker ps > 要查看所有的後面加上 -a ,會發現和上面GUI介面結果相同  - 查看所有的image docker images  - 下載image docker pull <image name> - 建立 image docker build [OPTIONS] PATH - --build-arg=[] :设置镜像创建时的变量; - -f :指定要使用的Dockerfile路径; - --no-cache :创建镜像的过程不使用缓存; - --pull :尝试去更新镜像的新版本; - --quiet, -q :安静模式,成功后只输出镜像 ID; - --rm :设置镜像成功后删除中间容器; - --tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。 - 執行 image docker run [OPTIONS] IMAGE [COMMAND] [ARG...] - -d : 背景執行 - -h : 自訂 host name - -i : 進入互動模式 - -p: 指定端口映射,格式为:主机(宿主)端口:容器端口 - -u : 設定 username - --name : 自訂 docker container 的名稱 - -v : 設定從外部掛載資源到 container 中 - --env-file=[]: 从指定文件读入环境变量; ## Dockerfile Dockerfile 是一份以 YMAL 語言撰寫的 Docker 設定檔,是docker建立image的重要角色,會從檔名是「Dockerfile」的文字檔中,透過docker build創建 Image,在透過docker run 執行container。如下圖:  ### 基本語法 - FROM:哪個映像檔(通常會抓取應用程式的執行環境,例如前端通常都是寫 JavaScript 所以就會利用 Node 作為執行環境) - WORKDIR:應用程式執行位置 - ADD/COPY:新增或複製檔案到應用程式執行位置 - RUN:執行應用程式 ### 進階語法 - ARG:在 build 的過程中,可以從外部帶入一些參數進來作為後續的環境變數使用。 - ENV:在 build 的過程中,可以定義一些環境變數,讓後面指令在執行時候可以使用,但前提是這個環境變數必須要從 ARG 中先被定義。 - CMD:Docker 在啟動容器的時候會執行的指令,不過這個指令只能執行一次,也就是假如你的 Dockerfile 中寫了多個 CMD,最後只會執行最後寫的那個 CMD。 - ENTRYPOINT:Docker 在啟動容器的時候會優先執行的指令,所以比起 CMD 來說 ENTRYPOINT 會更優先執行。 ### 實作 Docker container 1. 先用express簡單架一個伺服器 ```javascript= const express = require('express') var cors = require('cors') const app = express() const port = 8000 app.use(cors()) app.get('/', (req, res) => { res.json({ healthy: 'ok' }) }) app.listen(port, () => { console.log(`Example app listening on port ${port}`) }) ``` 2. 接著在資料夾的同一層建立Dckerfile的檔案 ```dockerfile= FROM node:18 # 建立目錄 WORKDIR /usr/src/app # 安裝套件 # 將程式中的package和package-lock的檔案先複製到docker image目錄底下 COPY package*.json ./ # 在執行npm install 前面package有的套件就可以不用安裝,省下一些時間 RUN npm install # Bundle app source # 將自己程式文件中所有的檔案複製到 docker image裡面 COPY . . # 指定 container 對外開放的 port EXPOSE 8000 CMD [ "node", "app.js" ] ``` 3. 建立透過dockerfile建立名為my-app的docker image ```dockerfile= # my-app後面的 . 不可省略 代表路徑 # 就像git 指令中的git add . 一樣代表該資料夾 docker build -t my-app . ``` 4. 等待建立image後就可以建立容器,執行image了 ```dockerfile= docker run -p 8000:8000 my-app ``` 5. 打開瀏覽器 http://localhost:8000 就可以看到透過express建立的server了! :::warning :warning: 有一個常常會搞錯的地方就是 port的設定 docker run -p 本機端口:容器端口 [image name] 也就是說如果按照上面的例子,因為dockerfile中,設定EXPOSE 8000,所以後面的容器端口一定要是8000,如果把指令改成 > docker run -p 8787:8000 my-app 就會發現無法連上http://localhost:8000了,因為前面port改成8787所以連線的位置就會變成http://localhost:8787 ! ::: ## 總結 恭喜大家距離docker又更進一步了,要熟悉一門新的技術真的要透過不斷的實戰練習才是最好的方法!下一篇要介紹的是同時執行很多image的魔法 docker-compose! [Docker 實戰 3 - Docker-compose](https://hackmd.io/@emmmmmma/HyyMSNd1T)  ## 參考資料 - [官方文件](https://docs.docker.com/) - [Docker 基本觀念介紹與容器和虛擬機的比較](https://www.omniwaresoft.com.tw/product-news/docker-news/docker-introduction/) - [Docker 學習筆記(三) — Docker指令講解](https://medium.com/%E4%B8%80%E5%80%8B%E5%B0%8F%E5%B0%8F%E5%B7%A5%E7%A8%8B%E5%B8%AB%E7%9A%84%E9%9A%A8%E6%89%8B%E7%AD%86%E8%A8%98/docker-%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-docker%E6%8C%87%E4%BB%A4%E4%BD%BF%E7%94%A8%E8%AC%9B%E8%A7%A3-9040d9de4677) - [docker run 命令](https://www.runoob.com/docker/docker-run-command.html) - [Docker build 命令](https://www.runoob.com/docker/docker-build-command.html)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up