Podman 教程

Containerfile 构建镜像

前面介绍了 Containerfile 的基础知识和常用指令,下面介绍如何通过 podman build 命令基于 Containerfile 构建自己的镜像。

使用 Podman 基于 Containerfile 构建镜像的过程与 Docker 类似,但 Containerfile 是 Podman 推荐的镜像构建文件名称。以下是详细步骤和说明:

构建镜像的基本命令

在 Containerfile 所在目录执行以下命令构建镜像:

podman build -t <镜像名称:标签> .

选项说明:

  • -t <镜像名称:标签>    指定镜像的名称和标签(如 myapp:v1),标签可选,默认为 latest。

  • .    表示构建上下文(Context)的路径,即 Podman 会将该目录下的所有文件发送到构建引擎,Containerfile 通常位于此目录。

例如:

# 假设当前目录有 Containerfile
podman build -t myapp:v1 .

# 若文件名为其他(如 custom-containerfile),需用 -f 指定
podman build -t myapp:v1 -f custom-containerfile .

  

实战步骤

准备 Containerfile

创建一个名为 Containerfile 的文件,示例如下(以构建一个简单的 Python 应用为例):

# 基础镜像(从容器仓库拉取,如 quay.io、docker.io 等)
FROM python:3.9-slim

# 设置工作目录(容器内的目录)
WORKDIR /app

# 复制当前目录的文件到容器的 /app 目录(. 表示构建上下文根目录)
COPY . .

# 安装依赖(执行容器内的命令)
RUN pip install --no-cache-dir -r requirements.txt

# 暴露端口(仅声明,实际运行时需通过 -p 映射)
EXPOSE 5000

# 容器启动时执行的命令(启动应用)
CMD ["python", "app.py"]

准备构建上下文

确保 Containerfile 所在目录包含构建所需的所有文件(如上例中的 app.py、requirements.txt),目录结构示例:

myapp/
├── Containerfile
├── app.py
└── requirements.txt

其中:

  • requirements.txt   Python 库的依赖信息,如下:

Flask==2.2.3
Werkzeug==2.2.3
  • app.py   应用代码,如下:

from flask import Flask
from datetime import datetime

app = Flask(__name__)

@app.route('/date')
def get_current_date():
    # 获取当前日期,格式为YYYY-MM-DD
    current_date = datetime.now().strftime('%Y-%m-%d')
    return current_date

if __name__ == '__main__':
    # 监听所有网络接口的8080端口
    app.run(host='0.0.0.0', port=8080)

现在本地验证程序是否能够正常运行,步骤如下:

(1)执行 pip install -r requirements.txt 命令安装依赖库

(python312) C:\Users\hxstri\app> pip install -r requirements.txt
Defaulting to user installation because normal site-packages is not writeable
Collecting Flask==2.2.3 (from -r requirements.txt (line 1))
  Downloading Flask-2.2.3-py3-none-any.whl.metadata (3.9 kB)
Collecting Werkzeug==2.2.3 (from -r requirements.txt (line 2))
  Downloading Werkzeug-2.2.3-py3-none-any.whl.metadata (4.4 kB)
...
Installing collected packages: Werkzeug, Flask
  Attempting uninstall: Werkzeug
    Found existing installation: Werkzeug 3.1.3
    Uninstalling Werkzeug-3.1.3:
      Successfully uninstalled Werkzeug-3.1.3
  Attempting uninstall: Flask
    Found existing installation: Flask 2.0.1
    Uninstalling Flask-2.0.1:
      Successfully uninstalled Flask-2.0.1
Successfully installed Flask-2.2.3 Werkzeug-2.2.3                                                                                                                                                 

(python312) C:\Users\hxstri\app>

(2)执行 python app.py 运行脚本

(python312) C:\Users\hxstri\app> python app.py
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8080
 * Running on http://10.124.24.133:8080
Press CTRL+C to quit

运行成功,使用浏览器访问 http://127.0.0.1:8080/date 地址,效果如下图:

Containerfile 构建镜像

上下文准备完成,继续。

  

执行构建命令

进入 app 目录,执行:

podman build -t my-python-app:1.0 .

构建过程中,Podman 会按 Containerfile 中的指令依次执行:拉取基础镜像、创建临时容器、执行命令、提交层等。

输出日志会显示每一步的执行结果,若某一步失败,构建会终止,需修复后重新执行。

完整构建过程如下:

C:\Users\hxstri>cd app

C:\Users\hxstri\app> dir
 驱动器 C 中的卷是 Windows
 卷的序列号是 76F0-23E3

 C:\Users\hxstri\app 的目录

2025/11/17  17:01    <DIR>          .
2025/11/17  16:56    <DIR>          ..
2025/11/17  17:01               373 app.py
2025/11/17  16:55               523 Containerfile
2025/11/17  17:07                29 requirements.txt
               3 个文件            925 字节
               2 个目录 23,122,247,680 可用字节

C:\Users\hxstri\app> podman build -t my-python-app:1.0 .
STEP 1/6: FROM python:3.9-slim
Resolving "python" using unqualified-search registries (/home/user/.config/containers/registries.conf)
Trying to pull docker.io/library/python:3.9-slim...
Getting image source signatures
Copying blob sha256:38513bd7256313495cdd83b3b0915a633cfa475dc2a07072ab2c8d191020ca5d
Copying blob sha256:fc74430849022d13b0d44b8969a953f842f59c6e9d1a0c2c83d710affa286c08
Copying blob sha256:b3ec39b36ae8c03a3e09854de4ec4aa08381dfed84a9daa075048c2e3df3881d
Copying blob sha256:ea56f685404adf81680322f152d2cfec62115b30dda481c2c450078315beb508
Copying config sha256:085da638e1b8a449514c3fda83ff50a3bffae4418b050cfacd87e5722071f497
Writing manifest to image destination
STEP 2/6: WORKDIR /app
--> bdd0f5292787
STEP 3/6: COPY . .
--> 9d60ee70accd
STEP 4/6: RUN pip install --no-cache-dir -r requirements.txt
Collecting Flask==2.2.3
  Downloading Flask-2.2.3-py3-none-any.whl (101 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 101.8/101.8 kB 225.5 kB/s eta 0:00:00
Collecting Werkzeug==2.2.3
  Downloading Werkzeug-2.2.3-py3-none-any.whl (233 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 233.6/233.6 kB 6.6 kB/s eta 0:00:00
Collecting Jinja2>=3.0
  Downloading jinja2-3.1.6-py3-none-any.whl (134 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.9/134.9 kB 17.5 kB/s eta 0:00:00
Collecting itsdangerous>=2.0
  Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Collecting importlib-metadata>=3.6.0
  Downloading importlib_metadata-8.7.0-py3-none-any.whl (27 kB)
Collecting click>=8.0
  Downloading click-8.1.8-py3-none-any.whl (98 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.2/98.2 kB 38.5 kB/s eta 0:00:00
Collecting MarkupSafe>=2.1.1
  Downloading markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (20 kB)
Collecting zipp>=3.20
  Downloading zipp-3.23.0-py3-none-any.whl (10 kB)
Installing collected packages: zipp, MarkupSafe, itsdangerous, click, Werkzeug, Jinja2, importlib-metadata, Flask
Successfully installed Flask-2.2.3 Jinja2-3.1.6 MarkupSafe-3.0.3 Werkzeug-2.2.3 click-8.1.8 importlib-metadata-8.7.0 itsdangerous-2.2.0 zipp-3.23.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip is available: 23.0.1 -> 25.3
[notice] To update, run: pip install --upgrade pip
--> 42867bf73e21
STEP 5/6: EXPOSE 5000
--> 6ef68685e974
STEP 6/6: CMD ["python", "app.py"]
COMMIT my-python-app:1.0
--> 690ae9ddddad
Successfully tagged localhost/my-python-app:1.0
690ae9ddddad54bfb07c0975e8d5c99a5df84eb9ffbf7a5585e4a2afc1bcff24

构建完成后,使用 podman images 命令看看镜像:

C:\Users\hxstri\app> podman images
REPOSITORY                             TAG            IMAGE ID      CREATED        SIZE
localhost/my-python-app                1.0            690ae9ddddad  3 minutes ago  138 MB

执行“podman run -p 8080:8080 my-python-app:1.0”创建容器并运行:

C:\Users\hxstri\app> podman run -p 8080:8080 my-python-app:1.0
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8080
 * Running on http://172.24.87.179:8080
Press CTRL+C to quit
172.24.87.179 - - [17/Nov/2025 09:23:09] "GET /date HTTP/1.1" 200 -
172.24.87.179 - - [17/Nov/2025 09:23:10] "GET /date HTTP/1.1" 200 -
172.24.87.179 - - [17/Nov/2025 09:23:10] "GET /date HTTP/1.1" 200 -

到这里整个构建流程就结束了。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号