1. 程式人生 > 其它 >【入門1】順序結構 P1001 A+B Problem 加法

【入門1】順序結構 P1001 A+B Problem 加法

簡介

學習了Docker基礎知識後,我們已經可以使用Dockerfile和docker build命令建立一個映象,並使用docker run命令執行一個容器。但如果想要同時執行多個容器,並建立容器之間的依賴關係,僅僅依靠上述的命令就顯得十分複雜。因此,我們需要一個新的工具能夠高效地對多個容器進行執行管理(批量容器編排),這便是Docker Compose。
官方文件:

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see

the list of features.
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  3. Run docker-compose up and Compose starts and runs your entire app.

安裝

下載:

# 通過專案源地址下載
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 國內映象地址
https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose

修改可執行許可權:

sudo chmod +x /usr/local/bin/docker-compose

安裝成功確認:

docker-compose --version

Getting Started

官方文件:

https://docs.docker.com/compose/gettingstarted/

環境配置

  • 建立專案目錄:

    mkdir composetest
    cd composetest
    
  • 建立一個python應用,並將下列程式碼複製進去:

    vim app.py
    
    import time
    
    import redis
    from flask import Flask
    
    app = Flask(__name__)
    cache = redis.Redis(host='redis', port=6379)
    
    def get_hit_count():
        retries = 5
        while True:
            try:
                return cache.incr('hits')
            except redis.exceptions.ConnectionError as exc:
                if retries == 0:
                    raise exc
                retries -= 1
                time.sleep(0.5)
    
    @app.route('/')
    def hello():
        count = get_hit_count()
        return 'Hello World! I have been seen {} times.\n'.format(count)
    
  • 建立一個文字文件,並新增相應依賴:

    vim requirements.txt
    
    flask
    redis
    

建立Dockerfile檔案

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

Dcokerfile檔案中每一行地作用已在相應章節有過闡述,官方文件也對此進行了詳細說明:

  • Build an image starting with the Python 3.7 image.
  • Set the working directory to /code.
  • Set environment variables used by the flask command.
  • Install gcc and other dependencies
  • Copy requirements.txt and install the Python dependencies.
  • Add metadata to the image to describe that the container is listening on port 5000
  • Copy the current directory . in the project to the workdir . in the image.
  • Set the default command for the container to flask run.

在Docker Compose檔案中定義服務

在專案目錄下,建立一個docker-compose.yml檔案,並新增如下程式碼:

version: "3.9"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

該檔案定義了兩個服務:web和redis。其中web服務使用Dockerfile和build .命令在當前資料夾下構建,redis服務則直接使用官方映象"redis:alpine"。

構建並執行應用

在當前資料夾下執行命令docker-compose up,系統開始根據我們寫好的Dockerfile構建了一個新映象,並下載了一個redis映象。這時出現了一個Warning

WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Pulling redis (redis:alpine)...

根據提示重新構建映象:

docker-compose build

當提示構建成功之後,我們再次執行命令docker-compose up

可以發現應用已經重新啟動了。如果我們在另一個終端中使用docker ps命令,即可看到正在執行的兩個服務:

也可以使用docker images命令檢視到新增的映象:

還可以使用docker network ls命令檢視到新增的網路composetest_default

接著使用docker network inspect命令檢視該網路的詳細資訊,發現web和redis服務均在該網路下執行。因此一個應用下的多個服務均可以通過容器名訪問而無需使用ip地址:


另外,在app.py中我們已經定義了redis服務的服務名:

cache = redis.Redis(host='redis', port=6379)

因此通過服務名來訪問redis服務也是可以的:

最後,我們只要開啟web服務暴露的埠5000,即可看到app.py指令碼的實現:

服務的名稱(composetest_web_1和composetest_redis_1 )是有其命名規則的,第一項是我們的專案目錄composetest,第二項是具體的服務名(web和redis),第三項是一個編號。由於我們是單機啟動,編號自然為1。而如果是在一個叢集中同時執行這項服務,那麼編號便可以將這個叢集中的不同伺服器上執行的服務加以區分。

為服務添加掛載

修改我們之前建立的yml檔案:

version: "3.9"
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    environment:
      FLASK_ENV: development
  redis:
    image: "redis:alpine"

volume鍵值對使得專案目錄與web服務的工作目錄/code進行掛載,因此我們可以即時修改程式碼而不用重建映象。另外,environment鍵規定了flask在開發模式下執行,並在更改後重載程式碼。
隨後使用命令docker-compose up重啟應用,這時如果我們修改專案目錄裡的app.py中的輸出語句:

return 'Hello from Docker! I have been seen {} times.\n'.format(count)

就會發現localhost:5000顯示的網頁發生了改變:

yml檔案編寫規則

官方文件:

https://docs.docker.com/compose/compose-file/

配置檔案的編寫總共分為三層:

  1. 版本

    version: "3.x"
    
  2. 服務

    services: #服務
    
      redis:  # 服務1
        # 服務配置與docker容器配置相同
        image: redis:alpine
        ports:
          - "6379"
        networks:
          - frontend
      ......
      db:  # 服務2
        image: postgres:9.4
        volumes:
          - db-data:/var/lib/postgresql/data
        networks:
          - backend
        ......
    
  3. 其他配置

    networks:   # 網路
      frontend:
      backend:
    
    volumes:    # 掛載
      db-data:
    configs:    # 配置
      my_config:
        file: ./my_config.txt    
    ......
    

部署Wordpress部落格

官方文件:

https://docs.docker.com/compose/wordpress/