Docker 部署一个用 Python 编写的 Web 应用

文章目录

    • 1. 安装 docker
    • 2. 编写代码
    • 3. 编写 Dockerfile
    • 4. 上传镜像
    • 5. 修改镜像

learn from 《深入剖析Kubernetes》

1. 安装 docker

在 WSL2 中安装 docker https://www.runoob.com/docker/ubuntu-docker-install.html
会报错:

# Executing docker install script, commit: 93d2499759296ac1f9c510605fef85052a2c32beWSL DETECTED: We recommend using Docker Desktop for Windows.
Please get Docker Desktop from https://www.docker.com/products/docker-desktopYou may press Ctrl+C now to abort this script.
+ sleep 20

去下载安装 windows 下的 docker
在这里插入图片描述
在这里插入图片描述

2. 编写代码

使用 Flask 框架启动了一个 Web 服务器,而它唯一的功能是:如果当前环境中有 “NAME” 这个环境变量,就把它打印在 “Hello” 后,否则就打印 “Hello world”,最后再打印出当前环境的 hostname

import os
from flask import Flask 
import socket 
from gevent import pywsgi
app = Flask(__name__) @app.route('/') 
def hello(): html = "<h3>Hello {name}!</h3>" \"<b>Hostname:</b> {hostname}<br/>" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname()) if __name__ == "__main__": server = pywsgi.WSGIServer(('0.0.0.0', 12345), app)server.serve_forever()

导出依赖包

pip freeze >requirements.txt
Flask==2.0.1
gevent==21.8.0
greenlet==1.1.1
itsdangerous==2.0.1
Jinja2==3.0.1
MarkupSafe==2.0.1
Werkzeug==2.0.1
zope.event==4.5.0
zope.interface==5.4.0

3. 编写 Dockerfile

# 使用官方提供的 Python 开发镜像作为基础镜像 
FROM python:3.8-slim # 将工作目录切换为 /app 
WORKDIR /app # 将当前目录下的所有内容复制到 /app 下 ADD . /app# 使用 pip 命令安装这个应用所需要的依赖 
# RUN pip install --trusted-host pypi.python.org -r requirements.txt 
RUN pip install --trusted-host https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt 
# 国内的源更快# 允许外界访问容器的 12345 端口 
EXPOSE 12345 # 设置环境变量 
ENV NAME World # 设置容器进程为:python app.py,即:这个 Python 应用的启动命令 
CMD ["python", "app.py"]
# CMD 前面 隐式的包含了 ENTRYPOINT , /bin/sh -c

在这里插入图片描述
在 WSL 里操作 :

  • 让 docker 制作镜像,-t 加 tag,自动加载 Dockerfile,执行里面的语句
docker build -t helloworld .
[+] Building 17.4s (10/10) FINISHED=> [internal] load build definition from Dockerfile                                                       0.1s=> => transferring dockerfile: 757B                                                                       0.0s=> [internal] load .dockerignore                                                                          0.1s=> => transferring context: 2B                                                                            0.0s=> [internal] load metadata for docker.io/library/python:3.8-slim                                         2.9s=> [auth] library/python:pull token for registry-1.docker.io                                              0.0s=> [1/4] FROM docker.io/library/python:3.8-slim@sha256:4dd66d1ccaddaa0587851cb92b365bf3090dccb41393c6f8b  0.0s=> [internal] load build context                                                                          0.1s=> => transferring context: 813B                                                                          0.0s=> CACHED [2/4] WORKDIR /app                                                                              0.0s=> [3/4] ADD . /app                                                                                       0.1s=> [4/4] RUN pip install --trusted-host https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt     13.6s=> exporting to image                                                                                     0.6s=> => exporting layers                                                                                    0.6s=> => writing image sha256:390d32b9f7a20ccd347361bd31450807d3e63d052e334865cf8460968ffceff4               0.0s=> => naming to docker.io/library/helloworld                                                              0.0sUse 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
  • 查看镜像
(k8s)PC:/mnt/d/gitcode/k8s$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
helloworld   latest    390d32b9f7a2   About a minute ago   169MB
  • 启动容器
docker run -p 4000:12345 helloworld

因为在 Dockerfile 中已经指定了 CMD。否则,就得把进程的启动命令加在后面 python app.py

  • 查看容器启动
(base) $ docker ps
CONTAINER ID   IMAGE        COMMAND           CREATED         STATUS         PORTS                                         NAMES
f6e051d1af6b   helloworld   "python app.py"   2 minutes ago   Up 2 minutes   0.0.0.0:4000->12345/tcp, :::4000->12345/tcp   upbeat_elion

通过 -p 4000:12345 告诉 Docker,把容器内的 12345 端口映射在宿主机的 4000 端口上

这样做的目的是,只要访问宿主机的 4000 端口,就可以看到容器里应用 返回的结果

curl http://localhost:4000
# <h3>Hello World!</h3><b>Hostname:</b> dc1c1343e366<br/>

使用容器完成了一个应用的开发与测试

4. 上传镜像

注册 docker hub,docker login 命令登录

docker tag helloworld kobe24o/helloworld:v0

kobe24o 是账号名(镜像仓库),helloworld 镜像名,v0自己分配的版本号

docker push kobe24o/helloworld:v0
(k8s) $ docker push kobe24o/helloworld:v0
The push refers to repository [docker.io/kobe24o/helloworld]
931022d457d6: Pushing [================>                                  ]  16.07MB/47.27MB
c76dc68917fc: Pushed
047ca6dfe9ab: Pushed
d82f4c466b47: Mounted from library/python
5aa75f4e55e7: Mounted from library/python
74d6903a940b: Mounted from library/python
2f9c2b8e82bd: Mounted from library/python
ba5a5fe43301: Mounted from library/python

5. 修改镜像

(base) $ docker ps
CONTAINER ID   IMAGE        COMMAND           CREATED         STATUS         PORTSNAMES
dd3bf057cb09   helloworld   "python app.py"   7 seconds ago   Up 5 seconds   0.0.0.0:4000->12345/tcp, :::4000->12345/tcp   compassionate_carver(base) $ docker exec -it dd3bf057cb09 /bin/sh
# pwd
/app
# touch newfile.txt
# ls
Dockerfile  app.py  newfile.txt  requirements.txt
# exit(base) $ docker commit dd3bf057cb09 kobe24o/helloworld:v1
sha256:ca8880f84040f9bdd7ef13763b9c64f8bd4a513a74bc2b095be06aae5b60268a

上面操作,新加了一个文件到镜像里,commit 保存

docker inspect --format '{{ .State.Pid}}' dd3bf057cb09
1763
# 查看正在运行的容器的进程号 PID 

通过查看宿主机的 proc 文件,看到这个 进程的所有 Namespace 对应的文件

root:/# ls -l /proc/{PID}/ns/
total 0
lrwxrwxrwx 1 root root 0 Sep 14 11:15 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Sep 14 11:15 ipc -> 'ipc:[4026532220]'
lrwxrwxrwx 1 root root 0 Sep 14 09:49 mnt -> 'mnt:[4026532218]'
lrwxrwxrwx 1 root root 0 Sep 14 11:15 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Sep 14 11:15 pid -> 'pid:[4026532221]'
lrwxrwxrwx 1 root root 0 Sep 14 11:15 pid_for_children -> 'pid:[4026532221]'
lrwxrwxrwx 1 root root 0 Sep 14 11:15 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Sep 14 11:15 uts -> 'uts:[4026532219]'

一个进程,可以选择 加入 到某个进程已有的 Namespace 当中,从而达到 “进入” 这个进程所在容器的目的,这正是 docker exec 的实现原理

  • push 到 hub
(base) $ docker push kobe24o/helloworld:v1
The push refers to repository [docker.io/kobe24o/helloworld]
dfee38b42dbb: Pushed
931022d457d6: Layer already exists
c76dc68917fc: Layer already exists
047ca6dfe9ab: Layer already exists
d82f4c466b47: Layer already exists
5aa75f4e55e7: Layer already exists
74d6903a940b: Layer already exists
2f9c2b8e82bd: Layer already exists
ba5a5fe43301: Layer already exists
v1: digest: sha256:7af7ff571ea9fd70d48abeaa2b38a1ed1c1a4e5a933b722d82af25d3e889f84e size: 2206

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/471674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三维网格精简算法java版_几种常见算法的精简版-

1 packagetest;23 importjava.nio.channels.SelectableChannel;45 importcom.itqf.bean.User;67 public classcTypeCode {89 /********************************************希尔排序和插入排序*******推荐严慧敏的那本数据结构&#xff0c;思想步骤我都加入到算法里面了&#…

DokuWiki 命名空间管理

为了更好的组织结构&#xff0c;Dokuwiki提供了命名空间这个功能&#xff0c;那怎么管理命名空间的&#xff0c;其实可以安装插件去管理 Add New Page Plugin&#xff1a;新建界面 https://www.dokuwiki.org/plugin:addnewpage Move Plugin&#xff1a;方便移动页面和命名空间 …

css样式子绝父相,子绝父相_HTML+CSS前端基础知识教程_腾讯视频

更多资料源码请加3252897743第1天 html 1、HTTP协议 2、html是纯文本3、html骨架4、DTD文档类型5、head标签6、body标签7、html基本语法8、h系列的标签9、p标签10、img标签11、a标签12、div和span含义第2天 html1、无序列表2、有序列表3、定义列表6、表格基础7、合并单元格…

shell命令查阅端口信息_linux运维实用的42个常用命令总结

1.删除0字节文件复制代码代码如下:find -type f -size 0 -exec rm -rf {} \;2.查看进程按内存从大到小排列复制代码代码如下:ps -e -o "%C : %p : %z : %a"|sort -k5 -nr3.按cpu利用率从大到小排列复制代码代码如下:ps -e -o "%C : %p : %z : %a"|sort -nr…

python 代码文件路径注意事项

检查代码的工作路径&#xff0c;是不是代码文件所在路径 导入别处的包 基于该代码的工作路径写如下的代码&#xff0c;加入相对路径&#xff0c;可以找到要导入的文件 import sys import os sys.path.append("../xxx/") sys.path.append("../../xxx") fro…

uva 10635 Prince and Princess(LCS成问题LIS问题O(nlogn))

标题效果&#xff1a;有两个长度p1和q1该序列。的各种元素的每个序列不是相互同。并1~n^2之间的整数。个序列的第一个元素均为1。求出A和B的最长公共子序列长度。 分析&#xff1a;本题是LCS问题&#xff0c;可是p*q<62500,O(pq)的算法显然会LE。在这里有一个条件&#xff0…

微信小程序独立服务器的好处,微信小程序的优势和缺点

原标题&#xff1a;微信小程序的优势和缺点微信小程序从刚开始面世就引起了很多人的关注&#xff0c;虽然截止到目前&#xff0c;官方仍没有大肆宣传和推广&#xff0c;但是微信小程序的所带来的影响还是很大的&#xff0c;甚至让苹果&#xff0c;百度&#xff0c;阿里都头疼不…

LeetCode 2007. 从双倍数组中还原原数组(map)

文章目录1. 题目2. 解题1. 题目 一个整数数组 original 可以转变成一个 双倍 数组 changed &#xff0c;转变方式为将 original 中每个元素 值乘以 2 加入数组中&#xff0c;然后将所有元素 随机打乱 。 给你一个数组 changed &#xff0c;如果 change 是 双倍 数组&#xff…

ajax和rxjs,javascript – RxJS 5 Observable和Angular2 http:调用ajax一次,保存结果,随后的ajax调用使用缓存结果...

下面的代码是我目前拥有的简化版本&#xff1a;name.service.tsInjectable()export class NameService {const nameURL "http://www.example.com/name";getName() {return this.http.get(nameURL);}}name1.component.tsComponent({templateUrl: ./name1.component.h…

怎么画韦布尔分布_手机按键寿命测试的样本数量怎么定?一文看懂 简述威布尔分布及其应用...

有一种手机按键的质量要求是&#xff0c;95%的产品的按压寿命需要达到1万次。根据这一要求&#xff0c;QC部门需要进行1.2万次的按压测试。那么QC部门需要选取多少按键来进行测试&#xff08;不允许有失效&#xff09;&#xff0c;才能保证95%的按键按压寿命达到1万次呢&#x…

Chrome浏览器报错:Origin null is not allowed by Access-Control-Allow-Origin.

问题&#xff1a;Chrome浏览器报错&#xff1a;Origin null is not allowed by Access-Control-Allow-Origin. 原因&#xff1a;.js文件中使用load()方法&#xff0c;而Chrome浏览器出于安全起见&#xff0c;不允许load本地文件。 方法&#xff1a;给Chrome添加启动参数--allow…

LeetCode 2008. 出租车的最大盈利(DP)

文章目录1. 题目2. 解题1. 题目 你驾驶出租车行驶在一条有 n 个地点的路上。 这 n 个地点从近到远编号为 1 到 n &#xff0c;你想要从 1 开到 n &#xff0c;通过接乘客订单盈利。 你只能沿着编号递增的方向前进&#xff0c;不能改变方向。 乘客信息用一个下标从 0 开始的二…

plotplay恢复默认设置_手把手解答win10系统potplayer经常弹出自动更新提示的还原技巧...

电脑犹如汽车&#xff0c;在使用过程中需要正确的方法&#xff0c;否则就会有win10系统potplayer经常弹出自动更新提示的情况出现&#xff0c;要处理win10系统potplayer经常弹出自动更新提示的问题&#xff0c;对于电脑专业人士来说并非难事&#xff1b;新手小白翻遍了整个网络…

华为服务器清除系统日志,清空服务器日志

清空服务器日志 内容精选换一换为加强对系统数据的容灾管理&#xff0c;云堡垒机支持配置日志备份&#xff0c;提高审计数据安全性和系统可扩展性。本小节主要介绍如何在系统配置FTP/SFTP服务器参数&#xff0c;将日志远程备份至FTP/SFTP服务器。开启远程备份后&#xff0c;系统…

动态行转列小记

数据库环境&#xff1a;SQL SERVER 2005 最近在整理数据时&#xff0c;要将查询到的数据张贴到Excel中。在Excel中&#xff0c;要展示的行数是固定的&#xff0c;列数不固定&#xff0c; 一个一个数据的复制张贴太烦人。想了一个偷懒的方法&#xff0c;直接将查询的数据进行行转…

使用swiper_关于使用swiper制作web轮播图

我这个方法是很适用于小白的&#xff0c;利用swiper插件的应用。https://www.swiper.com.cn/这个是swiper中文官网的网址&#xff0c;上面有关于swiper的说明和使用方法。想要用到swiper插件要在官网下载swiper文件&#xff0c;如下图所示&#xff0c;在导航条上面找到下载swip…

服务器换完主板后无盘进不了系统,更换主板后主板认不出硬盘无法进入系统的办法 – 手机爱问...

系统重装技术问题只需要一张系统光盘&#xff0c;和一张随机驱动光盘。如果没有驱动光盘&#xff0c;在安装系统前&#xff0c;用超级兔子或“驱动精灵”。备份驱动程序。安装好系统后恢复驱动即可。其它不需要方法&#xff1a;步骤:首先进入BIOS设置光驱优先。1)首选按Del键进…

动态规划_数字三角形

问题描述&#xff1a;在下面的数字三角形中寻找一条从顶部到底边的路径&#xff0c;使得路径上所经过的数字之和最大&#xff0c;路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可&#xff0c;不必给出具体路径。 输入数据的要求&#xff1a;三角形的行数大于1小…

LeetCode 2012. 数组美丽值求和

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的整数数组 nums 。对于每个下标 i&#xff08;1 < i < nums.length - 2&#xff09;&#xff0c;nums[i] 的 美丽值 等于&#xff1a; 2&#xff0c;对于所有 0 < j < i 且 i < k < nums.length - 1 …

arcgis 属性表 汇总_ArcGIS实践教程(19)ArcGIS/ArcMap中属性表的合并方法

merge: 功能一&#xff1a;可以联合 一般的属性表&#xff0c;合并属性或者说挂接属性&#xff01;例如&#xff1a;县polygon&#xff0c;只有name属性&#xff0c;现在需要添加他的邮编、区号、人口、面积、代码等等信息&#xff0c;现在搜集到了这些信息&#xff0c;并且放到…