Docker極簡入門:使用Docker-Compose 運行網站瀏覽量統計Demo


Docker-Compose 是一個可以對 Docker 容器集群的快速編排的工具,能夠減輕您心智和手指的負擔。

簡單的來說 Docker-Compose 就是將你運行多個容器的命令編寫到了一起,類似於你會為一系列重復操作寫一個 doSomething.sh 文件,只不過 Docker-Compose 提供了更簡便的語法。

當然如果想管理多主機多容器還是推薦使用 k8s。

我們的 demo 是一個基於 node.js 的網站服務,當用戶訪問當前服務器的根目錄時,將 redis 中的瀏覽量計數增加1。

先不看具體的業務代碼,這其實無關緊要。假設我們已經寫好了 node 服務,那么我們下一步就是寫一個Dockerfile文件去構建鏡像,然后執行 docker run 命令,這樣整個服務就啟動了。

FROM node:18-alpine

WORKDIR '/app'

COPY package.json .
RUN npm install
COPY . .
CMD ["npm","start"]

這個Dockerfile 做的事情就是

  • 在容器中創建一個 app 目錄,並切換到該目錄。
  • 將宿主機當前目錄下的 package.json 文件拷貝到容器中的當前目錄(/app)下
  • 執行命令npm install
  • 將宿主機當前目錄下的所有文件拷貝到容器中(因為主體程序index.js還沒有拷貝到容器中)
  • 運行命令npm start啟動服務

因為我們的 node 服務用到了 redis,所以我們還需要啟動一個 redis 容器。

但 docker 的機制使得這兩個容器是互相隔離的,所以想要通信的話

  • 將 redis 端口與宿主機端口做映射,通過宿主機的端口訪問 redis
  • 創建 docker network,將兩個容器放在同一個 docker network下
  • 編寫 docker-compose.yml 文件,讓Docker-Compose幫我們創建 docker network 搞定一切

docker-compose.yml

version: '3'
services:
  ## 容器名
  redis-server: 
   ## 指定鏡像
   image: 'redis:6.0.16-alpine'
   ## 容器重啟策略
   restart: 'always'
  ## 容器名
  node-app:
   ## 當前目錄執行 docker build
   build: .
   ## 端口映射
   ports: 
     - "8888:8081"

雖然我們在文件中沒有寫任何有關 network 的代碼,但 Docker-Compose會自動幫我們創建一個network

運行命令

sudo docker-compose up --build ## 會執行yaml文件中的build命令

訪問 localhost:8888 你應該能看到類似這樣的界面

docker-compose 的命令跟 docker類似

docker-compose up -d ## 后台運行
docker-compose down ## 停止

最后是文件目錄結構和 index.js 以及 package.json的具體代碼

.
├── docker-compose.yml
├── Dockerfile
├── index.js
├── package.json

package.json

{
    "dependencies": {
        "express": "^4.17.3",
        "redis": "^4.0.6"
    },
    "scripts": {
        "start": "node index.js"
    }
}

index.js

const express = require('express');

const redis = require('redis');

const app = express();

const client = redis.createClient({
  url : 'redis://redis-server:6379' // redis-server會被docker解析並轉發
});

const db = {
  async set(key,value){
    return fun(async()=>{
      return await client.set(key,value)
    },key,value)
  },
  async get(key){
    return fun(async()=>{
      return await client.get(key)
    },key)
  }
}

async function fun(callback,key,value){
  return new Promise(async (res,rej)=>{
    await client.connect();
    let ok = callback(key,value);
    await client.quit();
    res(ok);
  })
}

db.set("visits",0);

async function cntVisits(){
  let cnt = await db.get("visits");
  await db.set("visits",parseInt(cnt)+1);
  return parseInt(cnt)+1;
}

app.get('/', (req, res) => { 
    cntVisits().then( result => {
        res.send('Number of visits is ' + result); 
    });
});
// 8081是容器內部的端口,我們需要訪問的是8888,因為在docker-compose.yml文件中已經做過端口映射了
app.listen(8081, () => { console.log('Listening on port 8081'); });


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM