当前位置:   article > 正文

Docker---最详细的服务部署案例

Docker---最详细的服务部署案例

提供python服务的docker一键部署,示例已配置负载均衡,不需要的在nginx.conf和docker-compose注释相关代码即可

文件结构

1、dockerfile

  1. # 服务的dockerfile
  2. # 服务依赖的镜像
  3. FROM python:3.7
  4. # 设置容器内服务的工作目录
  5. WORKDIR /app
  6. # 复制当前文件夹所有文件到容器的工作目录,可以选择性按照选择依次COPY
  7. COPY . /app
  8. # 安装服务所需依赖
  9. RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r req.txt
  10. # 服务启动的接口,要与服务启动文件里面的保持一致
  11. EXPOSE 1000
  12. # 服务启动命令
  13. CMD ["sh", "start.sh"]

2、docker-compose.yml

  1. version: '3.3'
  2. networks:
  3. python_app_net: # 定义容器间网络的名称
  4. driver: bridge
  5. services:
  6. mysql_app:
  7. image: mysql:5.7
  8. container_name: mysql_app
  9. environment:
  10. MYSQL_DATABASE: 'polls' # 数据库名称
  11. MYSQL_USER: 'user' # 新建数据库用户
  12. MYSQL_PASSWORD: '123' # 新建用户的密码
  13. MYSQL_ROOT_PASSWORD: '123' # 数据库root账号的密码
  14. volumes:
  15. - ../mysql:/var/lib/mysql
  16. ports:
  17. - "1002:3306"
  18. networks:
  19. - python_app_net
  20. redis_app:
  21. image: redis:latest
  22. container_name: redis_app
  23. ports:
  24. - "1003:6379"
  25. volumes:
  26. - ../redis:/data
  27. networks:
  28. - python_app_net
  29. python_app: # 服务的名称
  30. build:
  31. context: . # Dockerfile所在的目录路径
  32. dockerfile: dockerfile # dockerfile的文件名称,有自定义名称的话按照这个寻找
  33. container_name: python_app # 指定容器名称,nginx使用docker部署的时候用得上
  34. image: python_image:1.0 # 镜像的名称与tag
  35. volumes:
  36. - ../python-app:/app # 服务挂载的卷,挂载以后可以在宿主机直接更改文件,容器内会同步修改,反之亦然,前面为宿主机路径,后面为容器内路径(宿主机路径选择为目前项目路径,新指定路径的话需要将文件都提前放进去,因为是先创建容器再将宿主机挂载的目录整个copy进容器,如果指定了其他路径里面为空的话容器内的工作目录会被覆盖为空,服务无法启动)
  37. # ports: # 如果走nginx代理,则不需要将服务的端口暴露出去
  38. # - "1000:1000" # 容器对外映射的端口,前面为宿主机,后面为容器内,容器内端口需要与服务的端口,dockerfile的expose端口保持一致
  39. depends_on: # 在其他指定容器只后启动
  40. - redis_app
  41. - mysql_app
  42. networks:
  43. - python_app_net
  44. python_app1: # 服务的名称
  45. build:
  46. context: . # Dockerfile所在的目录路径
  47. dockerfile: dockerfile # dockerfile的文件名称,有自定义名称的话按照这个寻找
  48. container_name: python_app1 # 指定容器名称,nginx使用docker部署的时候用得上
  49. image: python_image:1.0 # 镜像的名称与tag
  50. volumes:
  51. - ../python-app:/app # 服务挂载的卷,挂载以后可以在宿主机直接更改文件,容器内会同步修改,反之亦然,前面为宿主机路径,后面为容器内路径(宿主机路径选择为目前项目路径,新指定路径的话需要将文件都提前放进去,因为是先创建容器再将宿主机挂载的目录整个copy进容器,如果指定了其他路径里面为空的话容器内的工作目录会被覆盖为空,服务无法启动)
  52. # ports: # 如果走nginx代理,则不需要将服务的端口暴露出去
  53. # - "1000:1000" # 容器对外映射的端口,前面为宿主机,后面为容器内,容器内端口需要与服务的端口,dockerfile的expose端口保持一致
  54. depends_on: # 在其他指定容器只后启动
  55. - redis_app
  56. - mysql_app
  57. networks:
  58. - python_app_net
  59. nginx_app:
  60. image: nginx:latest
  61. container_name: nginx_app
  62. ports:
  63. - "1001:80"
  64. volumes:
  65. - ./nginx.conf:/etc/nginx/nginx.conf
  66. depends_on:
  67. - python_app
  68. networks:
  69. - python_app_net

3、main.py

  1. import os
  2. import redis
  3. import pymysql
  4. import socket
  5. import logging
  6. from flask import Flask, jsonify
  7. from flask_cors import CORS
  8. app = Flask(__name__)
  9. app.json.ensure_ascii = False
  10. CORS(app, supports_credentials=True)
  11. @app.route('/', methods=['GET'])
  12. def index():
  13. # 连接redis
  14. redis_client = redis.Redis(host='redis_app', port=6379, db=0,
  15. decode_responses=True) # host为容器名称,port为容器内端口,不是容器暴露的端口
  16. num = redis_client.get('key') or 1
  17. redis_client.set('key', int(num) + 1)
  18. # 连接mysql
  19. mysql_connection = pymysql.connect(host='mysql_app', user='root', password='Admin123.', database='polls',
  20. port=3306) # host为容器名称,port为容器内端口,不是容器暴露的端口
  21. try:
  22. with mysql_connection.cursor() as cursor:
  23. cursor.execute('SELECT VERSION()')
  24. res = cursor.fetchone()
  25. msg = f'mysql的版本为:{res}'
  26. except Exception as e:
  27. msg = f'连接mysql失败,{e}'
  28. finally:
  29. mysql_connection.close()
  30. hostname = socket.gethostname()
  31. ip_address = socket.gethostbyname(hostname)
  32. pid = os.getpid()
  33. return jsonify({'code': 200, 'msg': 'success', 'mysql': msg, 'redis': f'这是你第{num}次访问',
  34. 'data': f'ip: {ip_address}, pid: {pid}'})
  35. if __name__ == '__main__':
  36. app.run(debug=False, host='0.0.0.0', port=1000) # 用容器启动的话host必须为0.0.0.0,不然无法被其他容器访问

4、req.txt

  1. flask==3.0.3
  2. gunicorn==22.0.0
  3. flask_cors
  4. redis
  5. pymysql

5、start.sh

  1. # --daemon 后台运行的指令不需要,会让容器启动的时候发现进程结束了,直接关闭容器
  2. # --reload会在配置了挂载目录的时候在宿主机的文件更改直接生效,不需要重启容器
  3. # --bind必须绑定0.0.0.0,因为在容器里面,从其他容器访问的话使用127.0.0.1是无法访问到的
  4. gunicorn --reload -w 4 --bind 0.0.0.0:1000 main:app

6、启动命令

  1. # -d会让容器后台运行,不会直接挂在打印台
  2. docker-compose up -d

注意:如果运行拉取镜像报错,可以先单独docker pull 指定镜像,拉取到本地,然后运行docker-compose

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/850766
推荐阅读
相关标签
  

闽ICP备14008679号