docker相关知识和优化

张开发
2026/4/6 2:26:30 15 分钟阅读

分享文章

docker相关知识和优化
关于dockerfile常用命令对比CMD RUN ENTRYPOINTRUN是构建时运行的命令CMD ENTRYPOINT是运行时执行的命令 不同点在于 docker run 的参数 会直接替换CMD里命令而 ENTRYPOINT 是直接追加在命令后 所以对于不想影响格式 固定执行的命令 使用 ENTRYPOINT再通过ENTRYPOINT / CMD执行脚本文件 sh时要注意使用 exec格式的写法 shell格式的写法 防止传入docker run 后续的执行命令无效比如docker run --name ... npm run builddockerfile内部ENTRYPOINT .sh 直接使用shell写法 会将命令处理为 /bin/sh -c 脚本.sh 内部脚本$获取后续执行命令为空如果直接使用exec写法 ENTRYPOINT [.sh] 则会自动传入$ (推荐写法)或者 写shell格式的时候 额外处理 显示的生命传入的执行命令 ENTRYPOINT .sh $传入环境变量的注意点兜底处理# 定义默认变量可被-e覆盖 ENV APP_FILEbuild.js ENV NODE_PATH/var/lib/jenkins/nodejs16 # 复制脚本赋权 COPY start.sh /usr/local/bin/ RUN chmod x /usr/local/bin/start.sh # ✅ exec格式脚本直接继承容器环境变量 ENTRYPOINT [start.sh]#!/bin/bash set -e # 出错立即退出 # 1. 验证变量是否接收调试用 echo 容器全局环境变量 env | grep -E APP_FILE|NODE_PATH # 能看到-e传递的变量证明未失效 # 2. 变量兜底防止未传 APP_FILE${APP_FILE:-build.js} NODE_PATH${NODE_PATH:-/var/lib/jenkins/nodejs16} # 3. 执行核心命令exec保证信号传递 exec $NODE_PATH/bin/node $NODE_PATH/$APP_FILE关于容器间的网络通信最近进一步学习docker容器间的网络通信发现除了上面的容器端口映射到宿主机 然后进行外部访问 还可以通过添加到自定义网络即自定义bridge 进行容器间的网络访问 具体如下docker create network [net1] //这里的net1是指自定义网络的名字docker run --name [contianer1] --network net1docker run --name [contianer2] --network net1假如contianer1为前端项目 container2为后端服务项目的容器名称 在前端项目的nginx配置中 直接通过proxy_pass http://[contianer2]通过容器名称直接进行容器间的自定义网络通信这样的好处是 比容器端口映射到宿主机 进行端口和端口之间的访问相应要快的多docker 网络通信host模式 即容器和宿主机在同一个网络环境 不需要-p 端口映射 但是端口资源有限 会造成资源抢占bridge模式 可以通过-p端口映射 或者 docker inspect 容器名 获取ipadress 在nginx 里配置proxy_pass到后端ip实际操作中的坑点1. 当环境为多用户环境时有可能因为docker内外的用户 uid/gid不一致 导致denied permission 权限错误 可以使用gosu进行权限降级注意传入的 -e变量 兜底处理RUN cat /usr/local/bin/ci-entrypoint.sh EOF#!/bin/sh set -euo pipefail CLI_EXEC_UID {CLI_EXEC_UID:-0} CLI_EXEC_GID{CLI_EXEC_GID:-0} mkdir -p /app chown -R {CLI_EXEC_UID}:{CLI_EXEC_GID} /app || trueexec gosu {CLI_EXEC_UID}:{CLI_EXEC_GID} env $ EOFRUN chmod x /usr/local/bin/ci-entrypoint.sh在镜像里增加脚本运行 EXTRYPOINT 对文件权限进行统一 和环境变量的转化对应处理 降权的目的是为了不影响容器运行1.-v 绑定时 文件同步所以需要在容器内给文件运行时赋予宿主机相同的文件权限默认root权限但是对于不同环境上操作 文件的操作权限可能不一致 直接docker run -e 指定运行的权限2.对于nginx 默认80端口 需要root权限但是文件权限可能不是root ,需要开始使用root 运行nginx 时 gosu降权到普通用户权限说白了都是为了解决 -v文件挂载 但是容器内外的权限不统一题外话 关于sh脚本的编写可以使用echo / 是完全覆盖文件内容 是增加内容 用于逐行增加 或者EOF ...脚本内容......EOF 推荐EOF可读性更好docker run -e CLI_EXEC_UID脚本里$是完整接收docker run 外部参数传给env防止多个参数造成格式混乱2.对于依赖的漂移 这个不属于镜像范畴但是需要注意管控再dockerfile内安装依赖 生产环境直接npm ci --no-dry 对依赖版本和package.json进行检测 如果不对应则报错退出本地为了方便开发调试可以开放到 npm i --no save (不更新package.json -lock.json)但是需要对commit 进行commitlint 使用husky pre-commit钩子前 npm ci --no-dry防止开发者提交错乱版本 如果需要npm update 则 git diff 获取变更文件 校验 如果有package.json commitmessage需要特别格式说明 其他关于多平台兼容问题可详见笔者另外一篇参考内容https://cloud.tencent.com/developer/article/2383395https://www.cnblogs.com/evakang/p/10407330.html

更多文章