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 进行存储。
在这个目录下运行:
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 中处理它们的简单示例。