你的 Dockerfile 已经定义了:
dockerfile
VOLUME ["/config", "/logs"]
ENTRYPOINT ["python", "/app/app.py"]
CMD ["/config/config.json", "default_string"]
你的 Python 程序需要:
python
parser.add_argument("config")
parser.add_argument("rediskey")
也就是运行时等价:
bash
python /app/app.py /config/config.json default_string
关键点就是:把宿主机的配置文件挂载到容器的 /config 目录。
一、标准正确的 docker run 方法
假设宿主机配置文件:
text
/data/config.json
运行:
bash
docker run -d \
-v /data/config.json:/config/config.json \
-v /data/logs:/logs \
myimage
这样容器内:
/config/config.json ← 实际来自宿主机
/logs ← 日志目录
你的程序就能读取:
bash
/config/config.json
二、更推荐方式(挂整个目录)
生产环境更推荐:
bash
docker run -d \
-v /data/config:/config \
-v /data/logs:/logs \
myimage
目录结构:
宿主机:
/data/config/config.json
容器:
/config/config.json
这样以后增加配置不用改 docker run。
这是最佳实践 ⭐
三、如果要修改 rediskey 参数
可以覆盖 CMD:
例如:
bash
docker run -d \
-v /data/config:/config \
-v /data/logs:/logs \
myimage \
/config/config.json myrediskey
实际执行:
bash
python /app/app.py /config/config.json myrediskey
因为:
ENTRYPOINT 不变
CMD 被替换。
四、推荐生产运行方式
完整示例:
bash
docker run -d \
--name plc_app \
--restart always \
-v /data/plc/config:/config \
-v /data/plc/logs:/logs \
myimage \
/config/config.json plc_process_01
这样:
容器重启自动启动
日志持久化
配置外置。
五、如何确认容器看到文件
进入容器:
bash
docker exec -it plc_app bash
查看:
bash
ls /config
cat /config/config.json
如果能看到说明 OK。
六、常见错误(90%的人踩坑)
错误1
这样写:
bash
-v /data/config.json:/config
这是错误的,因为:
左边是文件
右边是目录。
必须:
bash
-v /data/config.json:/config/config.json
错误2 权限问题
如果程序报:
Permission denied
执行:
bash
chmod 644 /data/config/config.json
chmod 755 /data/config
或者:
bash
chmod -R 777 /data/config
(测试用)
七、企业级推荐写法(最干净)
Dockerfile:
dockerfile
ENTRYPOINT ["python", "/app/app.py"]
不要 CMD。
运行:
bash
docker run -d \
-v /data/config:/config \
-v /data/logs:/logs \
myimage \
/config/config.json plc01
更清晰。
八、更专业的做法(如果是工业PLC项目推荐)
建议改成:
支持环境变量:
python
import os
config = os.getenv("CONFIG_FILE","/config/config.json")
rediskey = os.getenv("REDIS_KEY","default")
docker run:
bash
docker run -d \
-v /data/config:/config \
-e CONFIG_FILE=/config/config.json \
-e REDIS_KEY=plc01 \
myimage
工业项目基本都这样做。
更安全、更可维护。
实际run
shell
docker run -d --name s7_l1 -v /opt/s7/l1/config_192.168.10.101.json:/config/config.json -v /opt/s7/l1/logs:/logs --network waston --restart always s7_adapter:v1.0