iT邦幫忙

0

[Day 3]Docker從零學習筆記

  • 分享至 

  • xImage
  •  

Docker 挑戰 - Day 3

目標

  1. 甚麼是 Dockerfile
  2. 練習打包自己的 Docker Image
  3. Docker-compose
  4. 進階專案(會部署到 Render) (上半部,因為太多了)

一、甚麼是 Dockerfile

Dockerfile 是一份文字檔案裡面寫著

  • 映像檔資訊
  • 需要安裝甚麼
  • 映像檔要怎麼操作
  • 啟動指令

Image就是根據 Dockerfile 所做成的

二、練習打包自己的 Docker Image

先建立一個資料夾

Step1: 在桌面建立docker-node-app資料夾

在資料夾裡建一些檔案,建立 Node.js 小專案

Step1: 建立 package.json -> 這個是Node.js專案的設定檔,檔案內容如下:

{
  "name": "docker-node-app",
  "version": "1.0.0",
  "description": "A simple Node.js app running in Docker",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

Step2: 建立 app.js -> 會開一個 Web Server,檔案內容如下:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello from Docker + Node.js!');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

Step3: 初始化 npm
到 Terminal 中 cd 到剛剛建立的 docker-node-app資料夾下
npm install -> 資料夾中會有node_modules

寫 Dockerfile 打包專案

Step1: 建立一個新檔案 Dockerfile,內容如下:

# 使用官方 Node.js base image
FROM node:18
# 建立 app 目錄
WORKDIR /usr/src/app
# 複製 package.json + package-lock.json
COPY package*.json ./
# 安裝 app dependencies
RUN npm install
# 複製整個專案到容器內
COPY . .
# 對外開放 3000 port
EXPOSE 3000
# 啟動指令
CMD [ "npm", "start" ]

提醒: Dockerfile 沒有副檔名,不要存成Dockerfile.txt

開始建 Docker Image & 啟動它

Step1:到 Terminal 中 cd 到剛剛建立的 docker-node-app資料夾下,輸入指令:
docker build -t docker-node-app .

部份 說明
-t 你想取的Image名字 幫Image取個名字
. 表示在目前這個資料夾下尋找 Dockerfile

執行容器

輸入docker run -d -p 3000:3000 docker-node-app,成功後接著打開瀏覽器,輸入:
http://localhost:3000 ,看到以下畫面表示成功:
執行容器,成功會看到的畫面

三、Docker-compose 組合

docker-compose 可以解決多容器管理的問題,可以一鍵啟動前後端+資料庫
也是一個純文字檔,叫做 docker-compose.yml,用來告訴 Docker 的容器設定內容像是:

  • 用到哪些 Images
  • 要啟動甚麼
  • 需要建立哪些 Volume 及 Network
  • 用到甚麼 port
    docker-compose up 就能一次全部啟動

實際操作看看

在剛建立的 docker-node-app 資料夾哩,新增一個檔案: docker-compose.yml
檔案內容如下:

services:
  web:
    build: .
    ports:
      - "3000:3000"
部份 說明
build: . 直接用現在資料夾的 Dockerfile 來 build
ports: 把容器內的 3000 port,綁到主機的 3000 port

提醒: 是.yml,不是.yaml喔

現在可以來啟動 docker-compose

在 docker-node-app/ 資料夾下打開 Terminal,輸入:
docker-compose up -d

可以來看看有沒有成功跑起來輸入: docker ps
docker-compose up -d 加 docker ps

提醒: 要先檢查有沒有容器正在佔用 port 3000,有的話手動停掉刪掉啟動的容器

四、進階專案

相信做到這裡的人應該對 Docker 有一定的熟悉了,以下有些動作都有做過,就不多做解釋了。

建立新的資料夾結構

預計結構如下:

docker-node-mysql/
├── backend/
│   ├── app.js
│   └── package.json
├── docker-compose.yml

Step1: 在桌面建立一個新的資料夾docker-node-mysql
Step2: 在 docker-node-mysql 資料夾下建立一個叫 backend 的資料夾
Step3: 在 docker-node-mysql/backend/下建立兩個檔案: package.json、app.js,檔案內容如下:
package.json

{
  "name": "docker-node-mysql",
  "version": "1.0.0",
  "description": "Node.js + MySQL docker-compose example",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mysql2": "^3.2.0"
  }
}

app.js

const express = require('express');
const mysql = require('mysql2');
const app = express();
const port = 3000;

// 設定資料庫連線(主機用 mysql --> 等下Compose會自動解析)
const db = mysql.createConnection({
  host: process.env.DB_HOST,       // 這邊填 "mysql"(service 名稱)
  port: process.env.DB_PORT,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME
});

// 測試資料庫連線
db.connect(err => {
  if (err) {
    console.error('資料庫連線失敗:', err);
    return;
  }
  console.log('資料庫連線成功!');
});

// 路由
app.get('/', (req, res) => {
  db.query('SELECT NOW() AS now', (err, results) => {
    if (err) throw err;
    res.send(`Database time: ${results[0].now}`);
  });
});

// 啟動 Server
app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});

Step4: 在 docker-node-mysql/下新增: docker-compose.yml
檔案內容如下:

services:
  mysql:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: testdb
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3307:3306"
  backend:
    build: ./backend
    ports:
      - "3000:3000"
    depends_on:
      - mysql
volumes:
  mysql_data:
服務 說明
mysql 用官方mysql:5.7 image
backend 用自己寫的 Node.js(從 backend 資料夾裡 build)
depends_on backend 一定會在 mysql 之後才啟動
volumes 把 MySQL 資料存起來
ports 對外開放 port3307給MySQL 和 port3000給Web Server

Step4: 在 backend/ 資料夾下再新增: Dockerfile,內容如下:

FROM node:18
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]

備註: 跟之前的很像,唯一差別是這次是給 backend/ 使用的

Step5: 在 Terminal 先 cd 到 docker-node-mysql,輸入:
docker-compose up -d -> 會自動用 MySQL imagebuild backend image啟動 backend+mysql建立 Volume

打開瀏覽器輸入http://localhost:3000 驗證成果,成功的話會顯示當下資料庫的時間,這表示 Node.js 有成功連線到 MySQL 並查詢資料回來,畫面如下:
https://ithelp.ithome.com.tw/upload/images/20250429/20172668ibqM6tnRH0.png

上傳專案到 GitHub

這邊的操作簡單帶過~
Step1: 到 GitHub Repository 新增一個 New repository,叫 docker-node-mysql
提醒: 要選 Public,因為 Render 免費版只支援 Public
Step2: 把專案 push 到 GitHub

git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/你的GitHub帳號/docker-node-mysql.git
git push -u origin main

在 Render 部署 Node.js 後端

Step1: 先去登入或註冊 Render帳號 (用GitHub註冊或登入)
Step2: 創建 Web Service,點 New -> Web Service -> 連接到你的 GitHub -> 用 docker-node-mysql repo
設置畫面如下:

設置 內容
Name docker-node-mysql-backend
Language Docker
Branch main
Region Singapore (Southeast Asia)
Root Directory backend (因為剛剛把 Dockerfile 放在 backend 資料夾裡)
Instance Type Free
Environment Variables DB_HOST, DB_NAME, DB_PASSWORD, DB_PORT, DB_USER(這些Key的Value等等填

去 Railway 部署 Node.js 後端

Render 現在免費版只有支援 PostgreSQL!,為了能免費做完,我們現在需要去 Railway 註冊帳號
Step1: 點選 new project -> Deploy MySQL ( 接下來就可以把剛剛 render 裡面的沒設完的 Value 填完)
railway deploy mysql 完畫面應該長這樣:
https://ithelp.ithome.com.tw/upload/images/20250429/20172668eZfnCNDjsA.png

Environment Variables 剛 Deploy 的 MySQL 裡的 variables 對照填入
DB_HOST MYSQL_PUBLIC_URL 注意要複製的是中間那段 @中間:
DB_NAME MYSQLDATABASE
DB_PASSWORD MYSQLPASSWORD
DB_PORT MYSQL_PUBLIC_URL 注意要複製冒號後面的數字
DB_USER MYSQLUSER

Last Step: 回 Render 點 Deploy Web Service (Render 就會自動 clone 你的 repo,用backend/Dockerfile build,並啟動一個 Node.js server)

部署完成可以根據 Render 給的公開網址連看看!
成功的話,表示有顯示資料庫現在的時間,代表 Node.js 成功連到 Railway 的 MySQL 資料庫了!畫面如下:
成功畫面

有到這邊的應該都快發瘋了,這套流程就像公司專案會使用的標準了,恭喜!!下次再來做一個更加進階完整功能的專案,期待一下哈哈
[上一篇] Day2
[下一篇] Day4


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
shaolin5525
iT邦新手 5 級 ‧ 2025-04-30 10:21:31

docker compose的version應該都拿掉囉~

image可以記得加上tag,不然都會被帶上latest。

Judy46kg iT邦新手 5 級 ‧ 2025-04-30 16:38:18 檢舉

好的我還在學習,謝謝提醒!!
馬上修改/images/emoticon/emoticon08.gif

我要留言

立即登入留言