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-tier
,back-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等
访问浏览器http://127.0.0.1:5001/
查看投票结果。
CATS和DOGS,各投一张效果:
体系结构
- 一个
Python
或ASP.NET Core
中的前端 Web App,可让您在两个选项之间进行投票 - 一个 用于收集新投票的
Redis
或NATS
消息队列 - 一个
.NET Core, Java
或者.NET Core 2.1
,Worker 消耗选票并将其存储在… - 一个 用Docker volume 挂载
Postgres
或TiDB
的数据库 - 一个
Node.js or ASP.NET Core SignalR
实时显示投票结果的Web App
注意
投票应用程序仅接受每个客户一票。如果客户已经提交了投票,它不会登记投票。
这不是一个合理架构的、设计完美的分布式App示例……它只是让您看到的各种类型的片段和语言(队列、持久数据等)以及如何在Docker 中处理它们的简单示例。