# Docker 基本知識 以及 Docker Compose實戰經驗 ###### tags: `Docker` docker 教學:https://yeasy.gitbooks.io/docker_practice/content/compose/introduction.html docker 命令: https://www.runoob.com/docker/docker-command-manual.html docker build 命令: https://www.runoob.com/docker/docker-build-command.html dockerfile 解說: https://www.jinnsblog.com/2018/12/docker-dockerfile-guide.html docker compose: https://yeasy.gitbooks.io/docker_practice/content/compose/compose_file.html docker mysql 使用: https://peihsinsu.gitbooks.io/docker-note-book/content/common-docker-mysql.html 了解docker的觀念後,接下來一步步的說明指令的實際應用 ## 下載image ``` $ docker pull [imageName] ``` ## docker run 把image建立成一個container ``` -d : 在後台執行 -p : 對應的port --name: container 名稱 --rm:容器停止後,自動刪除(測試用) -t : 開啟終端機 -i : 可以輸入 ``` 範例:執行docker建立一個nginx container 並且把本地的7777對應到container nginx的80 port ``` $ docker run -d -p 7777:80 --name webserver nginx ``` ## 進入container裡面 docker attach ``` $ docker attach [conatiner id] ``` 如果要退出,並保持container繼續執行, ctrl+p+q ## 進入container裡面 docker exec ``` $ docker exec -it mysql-5.7 mysql -u root -p ``` ## dockerfile 建立自己的 image 前置作業:在一個資料夾裡面創建一個 dockerfile 檔案,在裡面放入felix檔案 COPY:他會把當前目錄的檔案,移植到image裡面(注意:檔案一定要在同一個目錄下,他的根目錄就是這個dockerfile的資料夾) WORKDIR:改變container的進入點 CMD:下指令 以下 dockerfile 是建立一個java環境的container並且執行felix的image ``` FROM openjdk:11 COPY ./felix/ /opt/felix/ WORKDIR /opt/felix CMD java -jar ./bin/felix.jar ``` ``` $ docker build -t conatiner-name . ``` ## 建立 mysql + phpmyadmin 範例 建立 mysql 帳號root 密碼1234 並把port指定好 mysql預設port是3306 ``` docker run --name mysql-5.7 -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:5.7 ``` ``` docker run --name myadmin -d --link mysql-5.7:db -p 9100:80 phpmyadmin/phpmyadmin ``` ## docker-compose 非常好用 到有docker-compose.yml路徑下,才能下指令 ``` $ docker-compose up -d 建立 $ docker-compose stop 停止 $ docker-compose start 啟動 $ docker-compose restart 重啟 $ docker-compose rm 移除 ``` # 實戰開始 ## 起因 一直都聽說docker的厲害及方便,寫前端的我其實也根本懶得去碰後台,所以只有網路上看一些文章了解一下下,但剛好最近負責後台的同事有警急任務上身,不想一直打擾他作業的情況下,我就跟同事提出你簡單說明一下,我自行研究看看怎麼使用docker,自己去後台來使用,就不用一直麻煩你了,同事就說可以喔,非常簡單你只要docker-compose up -d 就萬事ok,然後就丟了一個文件docker-compose.yml檔給我,我說~這麼簡單???同事露出邪惡的笑容說就是那麼簡單,然後我就採坑了一個禮拜,才把它給up起來,所以就一一把過程記錄下來,提醒自己順便給需要的人看看吧! ## 介紹 這次是我需要架設一個獨立的環境,來提供網頁來運行,所以用docker把前後端全部一次打包起來,這個環境包有: 1. 前端網頁:目前用 vue 打包出來的disk檔 2. 後台資料庫:mysql+phpmyadmin 3. nginx:docker 裡面的伺服器管理 4. http service : (apache felix) apache felix 可以替換成node或是php等等能提供一個給網頁使用的api services就好,因為我們公司都是用這個框架寫後台,所以等等看到felix的東西可以忽略沒關係 ## 前言 因為我只是個初學者就不寫詳細的教學文件,因此不介紹其他的技術方面,只描述這次專案如何在docker上面使用 ## 第一坑 docker run 一開始看到docker-compose.yml文件老實說完全不知道在幹嗎,所以try了一個早上怎麼run都報錯,既然無法用靠賽的,那就果斷放棄,還是老老實實地了解後才能針對錯誤來修改,測試是在mac環境上 1. 首先:在mac上安裝好docker 2. 並且了解一些docker的基本知識 小提醒一下:了解容器的觀念很重要,因為在後面我就是卡在要怎麼配置端口上面,花了非常多的時間 先來個最簡單的run ``` $ docker run --name my-nginx -d -p:8888:80 nginx ``` 成功後就可以在 http://localhost:8888/ 看到nginx的歡迎畫面 ## 第二坑 docker exec 因為每個container都是一個進程,所以可以透過exec進入這個容器來查看一些東西,最基本的就是開啟一個容器的 /bin/bash ``` $ docker exec -it [container id/name] /bin/bash ``` -it 是能夠讓容器接收鍵盤輸入與螢幕輸出的指令 ## 第三坑 docker-compose 為什麼我直接帶入docker-compose,而不是先從dockerfile,或是其他的地方先開始,因為我覺得這樣對測試了解docker上非常的方變,不用打一堆指令跟刪除一堆container 1. 首先:創一個新的目錄,在目錄下面新增一個docker-compose.yml 剛剛上面的docker run 指令就可以寫成下面這樣,而這樣的好處就是我們只要cd到這個目錄下,並且執行 docker-compose up -d 就可以了,不需要打額外多餘的指令,而且之後只要修改這個檔案再執行一次docker-compose up -d就可以無痛更新,非常的方便 ``` version: "3.4" services: nginx: image: nginx container_name: my-nginx ports: - "8888:80" ``` ## 第四坑 volumes 因為docker每個container都是一個獨立的容器,你把它關掉後他就會完全消失不見,如果你在裡面新增了一些檔案,他在關掉的時候也會不間,所以這邊要使用volumes去把你想留下的東西,mount到本機的目錄上,也可以用這個去改變docker裡面的設定檔 用nginx來舉例,因為nginx的歡迎頁面html是放在/usr/share/nginx/html下面的index.html,所以如果你想改變這個畫面的內容,你只要把你的index.html修改到這個目錄下,他就會去開啟這個檔案,以我vue產生的disk來說 ``` version: "3.4" services: nginx: image: nginx container_name: my-nginx ports: - "8888:80" volumes: - ./html/dist:/usr/share/nginx/html ``` 很重要的是前面是docker-compose.yml目錄下的路徑,所有的東西一定都要在這個目錄下,他不能參考到你電腦中其他的地方,因為這個跟docker的引擎有關,所以要在你新創的目錄下,放入你要顯示的網頁內容,我的話是 ./html/disk 這樣修改完後存檔只要下docker-compose up -d, http://localhost:8888/ 就會變成你要顯示的畫面了 ## docker-nginx 相關 重啟nginx ``` docker exec <nginx_container_id> nginx -s reload ``` ## 查看 container 裡面的資訊 ``` $ docker inspect $image_name ``` ## 進入 container 裡面 ``` $ docker exec -it [Container 名稱或 ID] /bin/bash ```