前面介绍了 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 的文件,示例如下(以构建一个简单的 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 地址,效果如下图:

上下文准备完成,继续。
进入 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 -
到这里整个构建流程就结束了。