在日常服务器运维中,我们可能需要不同的编译环境,这个时候通过 docker 的方式来构建不同的环境会比较方便。比如,我们的服务器系统为 CentOS,GLIBC 的版本低于 node 18.xx.x 的运行要求时,如果直接升级 GLIBC 可能导致一些未知问题,此时我们就可以选择通过运行一个 docker 容器环境来构建这个编译环境。以下我们就以此场景举例说明。
创建 init.sh
脚本
在当前目录下创建一个名为 init.sh
的文件,内容如下:
#!/bin/sh
# init.sh
# 此为示例,根据实际情况修改,比如多环境,可添加 ENV=${1:-dev} 等环境变量
yarn config set registry 'https://registry.npmmirror.com/'
yarn install
yarn run build:prod
添加可执行权限
chmod a+x init.sh
注意
- 该脚本用于配置 Yarn 的注册表、安装依赖和构建项目。
- 虽然我们将通过
sh -c
来执行脚本,仍然需要为其添加可执行权限。
方案一:使用 Docker Compose
docker-compose.yml
command: ["sh", "-c", "./init.sh"]
如果脚本直接执行,默认机制可能直接当作可执行的命令直接运行,必须给文件添加可执行权限(机智的你可能会说:那干嘛自找麻烦加-c
参数?因为不加直接就跑不了了)。
基于以上推测,将命令改为command: ["sh", "-c", "sh ./init.sh"]
,果然可以成功在不授权的情况下运行脚本文件。
version: '3.8'
services:
node:
image: node:18.20.5
container_name: node
volumes:
- .:/app # 将当前目录映射到容器的 /app 目录
working_dir: /app # 设置工作目录为 /app
#command: ["sh", "-c", "./init.sh"] # 默认执行 init.sh 脚本
# 在脚本文件前再调用一次 sh 则不需要给 init.sh 添加可执行权限,更方便一点
command: ["sh", "-c", "sh ./init.sh"]
# 如果需要直接执行命令,可以将上面的行替换为以下行:
# command: ["sh", "-c", "yarn config set registry 'https://registry.npmmirror.com/' && yarn install && yarn run build:prod"]
restart: "no" # 不自动重启容器
启动容器(不推荐)
使用以下命令启动容器:
sudo docker compose up --force-recreate
清理容器(不推荐)
在容器执行完命令后,使用以下命令清理已停止的容器:
sudo docker compose down
使用 docker compose run --rm
(推荐)
如果你希望在执行完命令后自动清理容器,可以使用 docker compose run --rm
命令:
sudo docker compose run --rm node
这将运行 node
服务并在完成后自动删除容器。
方案二:使用 Docker 直接运行
直接执行命令和通过脚本运行
使用以下命令在 Docker 中执行 init.sh
脚本,默认使用脚本运行:
sudo docker run --rm \
-v "$(pwd):/app" \ # 将当前目录映射到容器的 /app 目录
-w /app \ # 设置工作目录为 /app
node:18.20.5 \ # 使用 node:18.20.5 镜像
sh -c "./init.sh" # 执行 init.sh 脚本
# 如果需要直接执行命令,可以将上面的行替换为以下行:
# sh -c "yarn config set registry 'https://registry.npmmirror.com/' && yarn install && yarn run build:prod"
总结
- Docker Compose 方案适合于需要管理多个服务的情况,使用
docker-compose.yml
文件进行配置。对于长命令,可以将其放入脚本文件(如init.sh
),并在docker-compose.yml
中通过command
字段执行该脚本。 - Docker 直接运行 方案适合于简单的单个命令执行,可以选择直接在命令行中执行命令或通过脚本文件执行,默认使用脚本运行。
- 使用脚本文件(如
init.sh
)可以更好地维护和管理长命令,使得命令更加清晰和易于修改。 - 使用
docker compose run --rm
可以在执行完命令后自动清理容器,适合于临时任务的执行。
评论区