第一次用 Docker 把一个 Python 小脚本打包运行:从 Dockerfile 到端口映射

举报
yd_221894022 发表于 2026/10/29 16:56:40 2026/10/29
【摘要】 用一个最简 Python HTTP 服务做例子,从写 Dockerfile、逐行解释,到构建镜像、运行容器和端口映射,并给出端口占用与镜像拉取慢的排查思路。

一、问题引入:本地能跑,换台机器就跑不起来

我写完第一个 Python 小服务时,在自己电脑上一运行就能打开页面。可把代码发给同事,对方却说启动报错、端口不对,依赖版本也不一样。问题往往不在代码本身,而在运行环境:不同电脑上的 Python 版本、依赖和端口都可能不同。Docker 就是把代码和运行环境装进同一个镜像,走到哪里都按同一份说明启动。

二、准备一个最简 Python HTTP 服务

新建文件夹 mini-http,写一个 app.py,只用标准库,不用装第三方包:

from http.server import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        body = "Hello from Docker!".encode("utf-8")
        self.send_response(200)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

if __name__ == "__main__":
    HTTPServer(("0.0.0.0", 8000), Handler).serve_forever()

它监听 8000 端口,收到请求就返回一句问候。这里写 0.0.0.0 很关键:在容器里只监听 127.0.0.1 时,容器外常常访问不到。先本地运行 python app.py,打开 http://localhost:8000 能看到问候语,再继续打包。

三、编写 Dockerfile,并逐行解释

在同一目录新建无扩展名的 Dockerfile:

FROM python:3.12-slim
WORKDIR /app
COPY app.py .
EXPOSE 8000
CMD ["python", "app.py"]

FROM python:3.12-slim 是选择已装好 Python 3.12 的较小基础镜像。WORKDIR /app 把容器工作目录设为 /app。COPY app.py . 把本地脚本复制到该目录,点号就是当前目录。EXPOSE 8000 只是声明容器服务用 8000 端口,真正打通内外端口要靠运行时的 -p。CMD 是容器启动时默认执行的命令,即运行这个脚本。

四、构建镜像、运行容器与端口映射

docker build -t mini-http:1.0 .
docker run -d -p 8080:8000 --name mini-http mini-http:1.0

build 的 -t 是给镜像起名和打标签,最后的点号表示 Dockerfile 在当前目录。run 的 -d 是后台运行,--name 是给容器起名。最关键的是 -p 8080:8000:冒号左边是宿主机端口,右边是容器端口,访问本机 8080 时,请求会被转发到容器里的 8000。打开 http://localhost:8080 能看到问候语,说明映射成功。之后可用 docker ps 查看容器,docker logs mini-http 看日志,docker stop mini-http 停止容器。

五、两个常见报错及排查思路

一是端口占用。启动时提示端口已被占用,先用 docker ps 看看有没有旧容器还在运行,有就先停掉;也可以不动容器端口,只换宿主机端口,例如改成 -p 8081:8000,再访问 8081。二是镜像拉取很慢。第一次构建要下载基础镜像,网络不好时等待会比较长,先确认是在下载而不是卡死;经常遇到时,可在合规前提下配置可用的镜像加速地址,或先单独拉取基础镜像,不要反复取消重来。

六、小结

第一次打包 Python 脚本,记住一条主线就够了:本地跑通小服务,用 Dockerfile 描述运行环境,构建镜像,再用 -p 宿主机端口:容器端口 暴露服务。端口方向最容易记反,左边是自己电脑的端口,右边是容器里的端口。跑通这一步,再学挂载目录、环境变量和多阶段构建都会顺畅很多。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。