# **Docker** **安裝Docker流程** **docker desktop 安裝(Windows)** **1.安裝網址:https://docs.docker.com/desktop/install/windows-install/** **2.驗證docker版本、進行測試安裝是否成功** ``` PowerShell docker --version docker images docker pull hello-world docker images docker run hello-world ``` **P.S.參考文件** https://www.evernote.com/shard/s475/client/snv?noteGuid=ca24e8d3-7774-1d2c-a4b7-aea354aee165&noteKey=9df30b0a5cedce798f394386637797eb&sn=https%3A%2F%2Fwww.evernote.com%2Fshard%2Fs475%2Fsh%2Fca24e8d3-7774-1d2c-a4b7-aea354aee165%2F9df30b0a5cedce798f394386637797eb&title=%25E7%25AC%25AC%2B2%2B%25E7%25AB%25A0%2BDocker%2B%25E5%25A6%2582%25E4%25BD%2595%25E5%259C%25A8%25E4%25B8%258D%25E5%2590%258C%25E4%25BD%259C%25E6%25A5%25AD%25E7%25B3%25BB%25E7%25B5%25B1%25E4%25B8%258A%25E4%25BD%25BF%25E7%2594%25A8 --- # **Java建置&tar匯出&資料庫匯出** **1.專案下建立設定檔** Dockerfile ![](https://i.imgur.com/zCqWb1p.png) 內容 ``` #Dockerfile FROM openjdk:8-jdk-alpine COPY ./target/*.jar /Documents/mydocker/demo.jar WORKDIR /Documents/mydocker RUN sh -c 'touch demo.jar' ENTRYPOINT ["java","-jar","demo.jar"] ``` [Dockerfile](https://matthung0807.blogspot.com/2020/11/docker-what-is-dockerfile.html)指令簡單說明 1. `[FROM](https://docs.docker.com/engine/reference/builder/#from) openjdk:8-jdk-alpine`:使用的base image。 2. `[COPY](https://docs.docker.com/engine/reference/builder/#copy) ./target/*.jar /Documents/mydocker/demo.jar`:將build context,即所在目錄的`target/*.jar`複製到container檔案目錄的/Documents/mydocker/demo.jar。 3. `[WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) /Documents/mydocker`:指定container的`/Documents/mydocker`為Docker的命令執行目錄。 4. `[RUN](https://docs.docker.com/engine/reference/builder/#run) sh -c '[touch](http://linux.vbird.org/linux_basic/0220filemanager.php#touch) demo.jar'`:修改`demo.jar`的時間戳記為目前時間。 5. `[ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) ["java","-jar","demo.jar"]`:在container剛指定的`WORKDIR`目錄執行`java -jar demo.jar`。 **2.建立專案jar包** 執行Run As 中的 Maven clean & Maven install ---> 開始打包 生成路徑 linux: /home/'user名稱'/'專案讀取路徑'/target/'專案.jar' windows: C:\\'專案路徑下'\\'專案讀取路徑'\\target\\'專案.jar' **3.切換到檔案路徑** cd '準備執行的jar檔的路徑' wsl下的linux參考路徑 ``` cd \\wsl.localhost\Ubuntu-20.04\home\tkbuser\Desktop\Workspace\Training_test ``` ``` cd \\wsl$\Ubuntu\home\tkb0004757\Desktop\TkbGitProject\forecast ``` **4.打包專案並於Docker執行** ``` docker build -t '專案名稱'-app . ``` **5.由Windows連線到Container** docker run -p 8080:8050 forecast-app 前面的port號為windows的 後面的port號為Container的(要跟原來專案一樣) 最後打上image名稱 ``` cd C:\Users\TKB0004757 ``` ``` docker run -p 8080:8050 forecast-app ``` **6.開啟瀏覽器** ``` localhost:8080/'專案'/ ``` **7.打包為tar壓縮檔** ``` docker save forecast-app -o forecast-app.tar ``` **8.tar就會生成在當前的路徑下** **9.資料庫匯出** ``` [mysqldump -u tkb0004558 -p project > member20220802.sql] mysqldump -u 使用者名稱 -p 資料庫名 表名> 匯出的檔名 ``` **10.完成** **P.S.參考文件** https://www.evernote.com/shard/s475/client/snv?noteGuid=cd7703dd-8897-a1ca-6b24-4e4cefaa2b4e&noteKey=3c123e129886329f917f140bcc125f7f&sn=https%3A%2F%2Fwww.evernote.com%2Fshard%2Fs475%2Fsh%2Fcd7703dd-8897-a1ca-6b24-4e4cefaa2b4e%2F3c123e129886329f917f140bcc125f7f&title=%25E5%258C%25AF%25E5%2587%25BADocker%25E6%25AA%2594%25E6%25A1%2588 --- # **建議方式** **安裝** 從官方存儲庫安裝 Docker **第1步:更新軟件存儲庫** 首先打開一個終端窗口並更新本地存儲庫: ``` sudo apt update ``` 等待該過程完成。 **第2步:下載依賴項** 通過運行以下命令,允許您的 Ubuntu 20.04 系統通過 HTTPS 訪問 Docker 存儲庫: ``` sudo apt-get install apt-transport-https ca-certificates curl software-properties-common ``` 上面提到的命令: 授予包管理器通過https傳輸文件和數據的權限。 允許系統檢查安全證書。 安裝curl,一個用於傳輸數據的工具。 添加用於管理軟件的腳本。 **第3步:添加 Docker 的 GPG 密鑰** 接下來,添加GPG密鑰以確保軟件包的真實性: ``` curl -fsSL [https://download.docker.com/linux/ubuntu/gpg](https://download.docker.com/linux/ubuntu/gpg) | sudo apt-key add - ``` **第4步:安裝 Docker 存儲庫** 現在使用以下命令安裝 Docker 存儲庫: ``` sudo add-apt-repository "deb [arch=amd64] [https://download.docker.com/linux/ubuntu](https://download.docker.com/linux/ubuntu) $(lsb_release -cs) stable" ``` 該命令為您的特定 Ubuntu 版本(在本例中為 20.04 Focal Fossa)安裝最新的存儲庫。 **第5步:安裝最新的 Docker** 首先再次更新存儲庫: ``` sudo apt update ``` 現在您可以使用以下命令安裝最新的 Docker 版本: ``` sudo apt-get install docker-ce ``` **第6步:驗證 Docker 安裝** 要確認安裝,請檢查 Docker 的版本: ``` docker --version ``` 它應該顯示 Docker 版本。 **第7步:[啟動Docker]** ``` sudo service docker start ``` **第8步:[測試docker engine可否使用 先看images檔案]** ``` sudo docker images ``` **第9步:[空的,現在建立images檔案上去]** ``` sudo docker pull hello-world ``` **第10步:[再看一次images就會有data]** ``` sudo docker images ``` **第11步:[run hello-world]** ``` sudo docker run hello-world ``` **第12步:[關閉docker服務]** ``` sudo service docker stop ``` --- # **Mysql、Springboot建立連線 (第一種方法)** **MySQL** docker安裝mysql ``` docker pull mysql:8 ``` **確認是否安裝完成** ``` docker images ``` **建立網路** ``` docker network create 'image名稱' ``` **docker network ls 查看是否建立成功** ``` docker network ls ``` **建立Container並執行** ``` docker run --name mysqldb --network 'image名稱' -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=docker -e MYSQL_USER=root -e MYSQL_PASSWORD=123456 -d mysql:8 ``` **查查看Container是否建立** ``` docker ps ``` **測試連線帳號** ``` docker exec -it container ID bash mysql -u帳號 -p密碼 ``` **指令整理** ``` 查看 images docker images 移除 images docker rmi ' xxxxxxxxxx ' 查看 network docker network ls 啟動 docker docker-compose up 查看 container中的東西 docker ps -a ``` --- # **SpringBoot** **設定** 根據上面自己建立image的設定,建立application.properties檔案 ``` spring.datasource.url=jdbc:mysql://mysqldb:3306/docker spring.datasource.username=username spring.datasource.password=123456 spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver ``` **1.將專案打包成jar檔** **2.Dockerfile配置** ``` FROM openjdk:8 EXPOSE 8080 ADD target/spring-boot-docker.jar test1.jar ENTRYPOINT ["java","-jar","/test1.jar"] spring-boot-docker.jar是專案打更成jar檔的黨名 test1.jar是打包到docker重新命名的名稱 ENTRYPOINT是把参数拼成一条命令java -jar test1.jar) ``` **建立image檔案 cd到自己的專案打指令** ``` sudo docker build -t springbootmysql . ``` **查看image** username@DESKTOP-4SUA6UQ:~/Desktop/work/Login$ sudo docker images **sudo**看目前使用的權限,再決定要不要加 ``` sudo docker images ``` **建立跟mysql的連線** ``` sudo docker ps ``` **查看帳號** ``` SELECT User,Host FROM mysql.user; ``` **查帳號權限** ``` SHOW GRANTS FOR usernamer; ``` # **Docker Compose建立連線(第二種方法)** **到專案新增yaml檔 (docker-compose.yml)** docker-compose.yml ``` version: '3' services: loginserver: build: . ports: - 8080:8080 networks: - loginbridge environment: - spring.datasource.url=jdbc:mysql://mysqldbcompose:3306/dockerr - spring.datasource.username=usernames - spring.datasource.password=123456 - spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver depends_on: - mysqldbcompose mysqldbcompose: image: mysql:8 ports: - '3307:3306' environment: MYSQL_DATABASE: 'dockerr' MYSQL_USER: 'usernames' MYSQL_PASSWORD: '123456' MYSQL_ROOT_PASSWORD: '123456' volumes: - /app/mysql/db:/var/lib/mysql - /app/mysql/conf/my.cnf:/etc/my.conf - /app/mysql/init:/docker-entrypoint-initdb.d networks: - loginbridge networks: loginbridge: # external: true 如果你的network是現有的 要加這句,docker引擎會先去找聲明過的不然會報錯 #MYSQL_USER:username、MYSQL_PASSWORD: password要跟properties的對到 ``` cd進入到該專案 ``` sudo docker-compose config -q #查看yml格式對不對 ``` 啟動docker ``` sudo docker-compose up ``` **Dockerfile(3步驟)** 基本規定 ``` - 保留字都須使用大寫,後面至少要跟一個參數 - 指令上到下執行 - 表示注釋 - 每條指令都會創建新的鏡像層並提交 ``` 建置流程 ``` - docker從基礎image運行一個容器 - 執行一條Dockerfile指令對容器做修改 - 執行類似docker commit的操作提交一個新的image層 - docker再基於剛提交的image層運行一個新容器 - 再執行Dockerfile的下一條指令,直到指令都執行完成 ``` 編寫docker文件 ``` FROM 基礎IMAGE,此鏡像作為模板建新鏡像 MAINTAINER 鏡像作者訊息 RUN 構建IMAGE執行的命令,每RUN一次都會構建一層IMAGE VOLUME 定義數據卷,用於數據保存和持久化 USER 指定鏡像以哪種身分去執行,默認是root WORKDIR 指定創建容器後,終端默認進來的工作目錄,一個落腳點 ARG 變量屬性值,但不在容器內部起作用 EXPOSE 暴露端口 ENV 構建IMAGE時,設定環境變量,可以在後續的任何Run指令使用,假如這裡設定變量路徑, 可以在WORKDIR指定這個變量路徑 ADD 將本機目錄下的文件複製到IMAGE且會自動處理URL和解壓TAR包 (假如要在IMAGE安裝JDK8,就可以複製本機的JDK8.tar進去) COPY 拷貝文件和目錄到IMAGE中 COPY src dest COPY ["src","dest"] <src原路徑>:原文件或目錄 <dest目標路徑>:容器內的指定路徑,會自動建立 CMD 容器啟動後的命令,如果有多個則以最後一個為準,也可以為ENTRYPOINT提供參數 ENTRYPOINT 容器進入時執行的命令 ENTRYPOINT 和 CMD 使用可看下圖 ``` 實際使用 ``` FROM openjdk:8 EXPOSE 8080 ADD target/spring-boot-docker.jar test1.jar ENTRYPOINT ["java","-jar","/test1.jar"] spring-boot-docker.jar是專案打更成jar檔的檔名 test1.jar是打包到docker重新命名的名稱 ENTRYPOINT是把参数拼成一条命令java -jar test1.jar) ``` docker build構建image docker run image運行container # **Docker-Compose** **定義** Docker公司推出的工具軟體,只需要定義一個YAML格式的配置文件,寫好多個容器間的調用關係,一個指令就能啟動、關閉。 **安裝Docker Compose** 在下載Compose (v2.6.1) ``` sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 使用curl將Compose文件下載到/usr/local/bin目錄中。 ``` 增加寫的權限 ``` sudo chmod +x /usr/local/bin/docker-compose 下載完成後,使用chmod修改docker-compose文件可執行權限。 ``` 驗證安裝是否成功 ``` docker-compose --version 輸出將包含docker-compose版本信息docker-compose version v2.6.1。 ``` Docker指令 Image 查看鏡像列表 ``` docker images ``` 刪除指定 id 的鏡像 ``` docker rmi image-id ``` 創建新的image docker commit -m="描述訊息" -a="作者名" 當前容器id 鏡像名:版本號 docker commit -m="solve bash-4.4" -a="lai" 5d9d5cc6e877 lai/mysql:8 Network ``` 作用 - 容器間互連、端口映射 - 容器ip變動時可以透過network_Name直接網路通信而不受影響 ``` docker跟本機交流、容器和容器間的交流 ``` docker啟動後,打ifconfig指令會發現多一個docker0的虛擬網橋 username@DESKTOP-4SUA6UQ:~$ ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:c3ff:fe3c:7962 prefixlen 64 scopeid 0x20<link> ether 02:42:c3:3c:79:62 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 19 bytes 1706 (1.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker透過docker0和本機做交流、容器間交流 ``` 列出網路 ``` root@DESKTOP-4SUA6UQ:/home/username# docker network ls NETWORK ID NAME DRIVER SCOPE fe410a2099d8 bridge bridge local 27ec28bbe5be host host local 9801a0aa540c none null local 預設會有3種模式bridge、host、none bridge:為每個容器分配、設置IP...,並將容器連接到docker0,虛擬網橋 --(默認模式) host :容器不會虛擬出自己的網卡、配置IP等,都是使用本機的IP、端口 none :容器有獨立的Network namespace,但並沒有任何網路設定 --(幾乎不用) container:新建的容器沒有自己的網卡和自己的IP,而是和指定容器共享IP、端口範圍等 ``` bridge模式 ``` 使用network bridge指定,不寫就 默認用docker0 ``` host模式 ``` 使用network host指定 ``` none模式 ``` 使用network none指定 ``` container模式 ``` 使用network container:NAME或是容器ID指定 ``` 創建網路 ``` docker network create xx_network ``` 查看網路 ``` docker network inspect xx_network ``` 移除網路 ``` docker network rm xx_network ``` 將image專案run在container中(-d為不跑console)(--name為取的名字)(forecast-app是跑的image) ``` docker run -p 8080:8050 -d --name forecast-app1 forecast-app ``` # **Container** **查看當前運行中的容器** ``` docker ps ``` **查看所有容器** ``` docker ps -a ``` **刪除指定 id 的容器** ``` docker rm container-id ``` 掛載資料 docker run -it --privileged=true -v /**本機絕對路徑**:/**容器內目錄:ro** **容器名** 將本機儲存位置掛載到容器內目錄,當容器刪除時,資料還會保留在本機 ``` docker run -it --privileged=true -v /app/mysql/db:/var/lib/mysql login-mysqldbcompose-1 :ro是設定唯讀,預設是rw 如果沒有要特別設定的話就不用打這個 ``` **掃描容器的配置 ** ``` docker inspect 容器id ``` "Mounts": 掛載位置 ``` "Mounts": [ { "Type": "bind", //綁定類型 "Source": "/app/mysql/db", //本機儲存的位置 "Destination": "/var/lib/mysql", //container內儲存的位置 "Mode": "rw", "RW": true, "Propagation": "rprivate" }, { "Type": "bind", "Source": "/app/mysql/conf/my.cnf", "Destination": "/etc/my.conf", "Mode": "rw", "RW": true, "Propagation": "rprivate" }, { "Type": "bind", "Source": "/app/mysql/init", "Destination": "/docker-entrypoint-initdb.d", "Mode": "rw", "RW": true, "Propagation": "rprivate" } ], ``` 查看 volume 列表 ``` docker volume ls ``` 停止/啟動指定 id 的容器 ``` docker stop/start container-id ``` --- # **Docker部屬** **JAVA流程** ``` docker #打包 docker save [image] -o file.tar #上傳伺服器後執行 docker load -i file.tar #DB docker run -p 3306:3306 -v /etc/localtime:/etc/localtime:ro --name mariadb -e MYSQL_ROOT_PASSWORD=123456 -d docker.io/library/mariadb:10.3 #JAVA docker run -d -v /etc/localtime:/etc/localtime:ro --link mariadb:mariadb --name teacherresource-20221210 -p 8080:8080 teacherresource-app #Nuxt docker run -d -v /etc/localtime:/etc/localtime:ro --link teacherresource-app:teacherresource-app --name nuxt-app:v1 -p 3000:3000 nuxt-app:v1 #查詢container IP docker inspect --format '{{ .NetworkSettings.IPAddress }}' mariadb CREATE SCHEMA `tkb_demo` DEFAULT CHARACTER SET utf8mb4; #外面匯入SQL進container cat teacher_resource.sql | docker exec -i mariadb mysql -u root --password=123456 teacher_resource ``` --- # **Docker-MySQL Workbench** 在Docker 使用MySQL container時,是沒有GUI操作介面的,用指令修改資料是比較耗時的,所以我們如何幫container中的MySQL建立一個Workbench來使用呢,作法就是把本機的port連到container內的port。 **第一步: run mysql/mysql-server:5.7 image** docker run -p 3400:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=root -d mysql/mysql-server:5.7 **第二步: 進到MySQL container內** ``` docker exec -it my-mysql /bin/bash ``` **第三步: 登入MySQL** ![](https://i.imgur.com/0UWBGuU.png) ``` docker exec -it my-mysql /bin/bash ``` ``` mysql -uroot -p -A ``` **第四步: 查看所有使用者及host** ``` select user,host from mysql.user; ``` **第五步: 把root user的host改為 %** 指令: update mysql.user set host=’%’ where user=’root’ 因為localhost表示你只能在container進行連線,外部連線不了 ``` update mysql.user set host='%' where user='root'; ``` **第六步: 更新特權** ``` flush privileges ``` **第七步: 在windows中打開workbench設定連線** 1. Connection 名稱 2. 主機連線到mysql container內的port號 (上面我設3400:3306),所以是3400 3. 設定密碼(建立mysql container時我設的密碼環境變數為root) ![](https://i.imgur.com/l5TTy2o.png) 點擊Test Connection ![](https://i.imgur.com/AEYcPzz.png) 完成 **P.S.參考文件** https://flannel-october-6b3.notion.site/Docker-f73f5ac983394c73bc5b70b1dc191561 --- # **Docker Compose** **建立dockerCompose.yml** 放入組態設定 ``` yml(yaml) version: '3.7' # Service services: # Database MySQL app-db: image: mariadb container_name: app-mariadb #restart: always volumes: - mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: mms_db MYSQL_USER: springboot MYSQL_PASSWORD: springboot ports: - "3306:3306" networks: - app-server-network # APP Server app-server: depends_on: - app-db image: mms/member-manage-system:0.0.1 build: context: ./ dockerfile: Dockerfile ports: - "8080:8080" environment: # Pass environment variables to the service DATASOURCE_HOST: app-db DATASOURCE_POST: 3306 DATASOURCE_NAME: mms_db DATASOURCE_USERNAME: springboot DATASOURCE_PASSWORD: springboot networks: - app-server-network # Volume volumes: mysql-data: # Network networks: app-server-network: ``` ``` docker docker-compose -d up ``` --- # **nuxt dockerize 流程** **1. 建立Nuxt專案** ``` PowerShell npx create-nuxt-app 專案名稱 ``` **2. 在nuxt.config.js設定好server host 及 port 及 axios 連線** 這裡設定正式環境host為0.0.0.0, port為3000 ``` JavaScript export default { ... server: { host: process.env.NODE_ENV === 'development' ? '127.0.0.1' : '0', port: process.env.NODE_ENV === 'development' ? 8500 : 3000, }, axios: { baseURL: process.env.NODE_ENV === 'development' ? 'http://127.0.0.1:4000/' // 實際會連線到此網站的ip : 'https://p22sg03.csofe.org/' }, ... } ``` **3. 更新連線後端IP** ``` JavaScript // /server/app.js ... const API_URL = process.env.NODE_ENV === 'development' ? 'http://172.18.48.25:8765/api' // api server的container ip : 'http://172.17.0.3:8080/api' ... ``` **4. 在根目錄新增Dockerfile** ``` yml(yaml) FROM node:16-bullseye WORKDIR /app ENV NUXT_HOST=0.0.0.0 ENV NUXT_PORT=3000 COPY . /app RUN npm cache clean --force RUN npm install RUN npm run build EXPOSE 3000 CMD ["npm", "run", "start"] ``` **5. 在專案根目錄將專案 build 成 image** ``` PowerShell docker build -t nuxt-app:v1 . ``` **6. 運行成container ``` PowerShell // 依專案設定 ``` **7. 成功! 可以用 https://p22sg03.csofe.org/ 來連線此專案 ** yaml 配置規劃 https://ithelp.ithome.com.tw/articles/10191753