Docker Compose 练习:投票 App

Docker Compose 经典示例: Example Voting App 示例投票App

GitHub地址:https://github.com/dockersamples/example-voting-app

网络不好的同学,我已经把源码下载,地址:https://download.csdn.net/download/weixin_48447848/77354937

Example Voting App 示例投票App

跨多个Docker容器运行的简单分布式应用程序。

前期准备

下载适用于Mac或Windows的Docker Desktop。Docker Compose将自动安装。在Linux上,确保您拥有最新版本的Compose。

Linux 容器 示例

Linux 堆栈使用 Python、Node.js、.NET Core(或可选的 Java),使用 Redis 进行消息传递,使用 Postgres 进行存储。

如果您在 Windows 上使用 Docker Desktop,则可以通过切换到 Linux 容器来运行 Linux 版本,或者运行 Windows 容器版本。

在这个目录下运行:

docker-compose up

该应用程序将在http://localhost:5000运行,结果将在http://localhost:5001

或者,如果你想在Docker Swarm上运行它,首先确保你有一个 swarm。如果没有,请运行:

docker swarm init

一旦你有了你的 swarm,在这个目录中运行:

docker stack deploy --compose-file docker-stack.yml vote

上手操作一遍

下载源代码:https://download.csdn.net/download/weixin_48447848/77354937

查看并讲解

example-voting-app/docker-compose.yml

分析内容:
总共有5个要创建的容器:

  • vote 投票服务
  • result 后台查看投票结果
  • worker 消耗选票服务
  • redis 用于消息队列
  • db 数据库

volumes:挂载存储空间 db-data

networks: 2个 docker 网络,front-tierback-tier

# version is now using "compose spec"
# v2 and v3 are now combined!
# docker-compose v1.27+ required

services:
  vote:
    build: ./vote
    # use python rather than gunicorn for local dev
    command: python app.py
    depends_on:
      redis:
        condition: service_healthy  # vote服务 依赖redis healthy状态
    volumes:
     - ./vote:/app
    ports:
      - "5000:80"
    networks:
      - front-tier
      - back-tier

  result:
    build: ./result
    # use nodemon rather than node for local dev
    command: nodemon server.js
    depends_on:
      db:
        condition: service_healthy  # result服务 依赖db数据库 healthy状态
    volumes:
      - ./result:/app
    ports:
      - "5001:80"
      - "5858:5858"
    networks:
      - front-tier
      - back-tier

  worker:
    build:
      context: ./worker
    depends_on:
      redis: # worker服务 依赖 redis和db healthy状态
        condition: service_healthy  
      db:
        condition: service_healthy 
    networks:
      - back-tier

  redis:
    image: redis:5.0-alpine3.10
    volumes:
      - "./healthchecks:/healthchecks"
    healthcheck:
      test: /healthchecks/redis.sh # 检测脚本,每五秒执行一下
      interval: "5s"
    ports: ["6379"]
    networks:
      - back-tier

  db:
    image: postgres:9.4
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"
    volumes:
      - "db-data:/var/lib/postgresql/data"
      - "./healthchecks:/healthchecks"
    healthcheck:
      test: /healthchecks/postgres.sh # 健康检测脚本
      interval: "5s"
    networks:
      - back-tier

volumes:
  db-data:

networks:
  front-tier:
  back-tier:

example-voting-app/vote/Dockerfile

前台投票服务

# Using official python runtime base image
FROM python:3.9-slim

# add curl for healthcheck
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Set the application directory
WORKDIR /app

# Install our requirements.txt
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt

# Copy our code from the current folder to /app inside the container 将代码从当前文件夹复制到容器内的/app
COPY . .

# Make port 80 available for links and/or publish
EXPOSE 80

# Define our command to be run when launching the container 定义启动容器时要运行的命令
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--log-file", "-", "--access-logfile", "-", "--workers", "4", "--keep-alive", "0"] 

example-voting-app/result/Dockerfile

后台查看投票结果,node.js服务的Dockerfile

FROM node:10-slim

# add curl for healthcheck
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Add Tini for proper init of signals
ENV TINI_VERSION v0.19.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini

WORKDIR /app # 进入app目录

# have nodemon available for local dev use (file watching)
RUN npm install -g nodemon

COPY package*.json ./

RUN npm ci \
 && npm cache clean --force \
 && mv /app/node_modules /node_modules

COPY . .  # 将代码从当前文件夹复制到容器内的/app

ENV PORT 80

EXPOSE 80

CMD ["/tini", "--", "node", "server.js"]

example-voting-app/worker/Dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder

WORKDIR /Worker
COPY src/Worker/Worker.csproj .
RUN dotnet restore

COPY src/Worker/ .
RUN dotnet publish -c Release -o /out Worker.csproj

# app image
FROM mcr.microsoft.com/dotnet/core/runtime:3.1

WORKDIR /app
ENTRYPOINT ["dotnet", "Worker.dll"]

COPY --from=builder /out .

健康检测脚本 example-voting-app/healthchecks/

postgres.sh 数据库服务 检测脚本

#!/bin/bash
set -eo pipefail

host="$(hostname -i || echo '127.0.0.1')"
user="${POSTGRES_USER:-postgres}"
db="${POSTGRES_DB:-$POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD:-}"

args=(
	# force postgres to not use the local unix socket (test "external" connectibility)
	--host "$host"
	--username "$user"
	--dbname "$db"
	--quiet --no-align --tuples-only
)

if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then
	exit 0
fi

exit 1

redis.sh 检测脚本

#!/bin/sh
set -eo pipefail

host="$(hostname -i || echo '127.0.0.1')"

if ping="$(redis-cli -h "$host" ping)" && [ "$ping" = 'PONG' ]; then
	exit 0
fi

exit 1

执行

选择docker-compose.yml文件

docker-compose -f .\docker-compose.yml up -d

等待拉取和构建,上百行输入,省略……

查看容器创建情况

PS C:\Users\柏杉\Downloads\example-voting-app-master> docker-compose ps
               Name                             Command                  State                      Ports               
------------------------------------------------------------------------------------------------------------------------
example-voting-app-master_db_1       docker-entrypoint.sh postgres    Up (healthy)   5432/tcp                           
example-voting-app-master_redis_1    docker-entrypoint.sh redis ...   Up (healthy)   0.0.0.0:3161->6379/tcp             
example-voting-app-master_result_1   docker-entrypoint.sh nodem ...   Up             0.0.0.0:5858->5858/tcp,            
                                                                                     0.0.0.0:5001->80/tcp               
example-voting-app-master_vote_1     python app.py                    Up             0.0.0.0:5000->80/tcp               
example-voting-app-master_worker_1   dotnet Worker.dll                Up                                                
PS C:\Users\柏杉\Downloads\example-voting-app-master>

端口5000 投票服务
端口5001 查看投票结果

访问浏览器http://127.0.0.1:5000/ 进行投票。
同一个IP和浏览器算为一个用户,不能重复投票,可以开几个不同的浏览器Chrome,Firefox,Edge等

Docker Compose 练习:投票 App
Docker Compose 练习:投票 App

访问浏览器http://127.0.0.1:5001/ 查看投票结果。
CATS和DOGS,各投一张效果:
Docker Compose 练习:投票 App

体系结构

Docker Compose 练习:投票 App

  • 一个 PythonASP.NET Core中的前端 Web App,可让您在两个选项之间进行投票
  • 一个 用于收集新投票的RedisNATS 消息队列
  • 一个 .NET Core, Java 或者.NET Core 2.1,Worker 消耗选票并将其存储在…
  • 一个 用Docker volume 挂载PostgresTiDB的数据库
  • 一个 Node.js or ASP.NET Core SignalR 实时显示投票结果的Web App

注意

投票应用程序仅接受每个客户一票。如果客户已经提交了投票,它不会登记投票。

这不是一个合理架构的、设计完美的分布式App示例……它只是让您看到的各种类型的片段和语言(队列、持久数据等)以及如何在Docker 中处理它们的简单示例。

上一篇:plc模拟量数据波动的原因


下一篇:PLC编程器有什么功能