我有一个非常简单的
config.yml
:
version: 2
jobs:
build:
working_directory: ~/app
docker:
- image: circleci/node:8.4.0
steps:
- checkout
- run: node -e "console.log('Hello from NodeJS ' + process.version + '\!')"
- run: yarn
- setup_remote_docker
- run: docker build .
它所做的一切:启动一个
node
图像,测试节点是否正在运行,执行一个yarn install
和一个docker build
。
我的 dockerfile 没什么特别的;它有一个副本和入口点。
当我使用 Docker Native 在 MacBook Air 上运行
circleci build
时,出现以下错误:
Got permission denied while trying to connect to the Docker daemon socket at unix://[...]
如果我将
docker build .
命令更改为:sudo docker build .
,一切都会按计划在本地按计划运行,circleci build
。Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
所以,总结一下:使用
sudo
在本地有效,但在 CircleCI 本身上无效。 Not 使用 sudo
适用于 CircleCI,但不适用于本地。
这是 CircleCI 工作人员必须解决的问题,还是我可以做些什么?
我为自己创建了一个解决方法。
在 config.yml 的第一步中,我运行以下命令:
if [[ $CIRCLE_SHELL_ENV == *"localbuild"* ]]; then
echo "This is a local build. Enabling sudo for docker"
echo sudo > ~/sudo
else
echo "This is not a local build. Disabling sudo for docker"
touch ~/sudo
fi
之后,你可以这样做:
eval `cat ~/sudo` docker build .
第一个片段检查CircleCI提供的环境变量
CIRCLE_SHELL_ENV
是否包含localbuild
。仅当在本地计算机上运行 circleci build
时才如此。
如果为 true,它会在主目录中创建一个名为 sudo
且内容为 sudo
的文件。
如果为 false,它会创建一个名为 sudo
的文件,主目录中没有任何内容。
第二个片段打开
~/sudo
文件,并使用您随后给出的参数执行它。如果 ~/sudo
文件包含“sudo
”,则此示例中的命令将变为 sudo docker build .
,如果不包含任何内容,它将变为 docker build .
,前面有一个空格,但会被忽略.
这样,本地 (
circleci build
) 构建和远程构建都可以工作。
重申 Jeff Huijsmans 的答案,
另一种版本是使用 Bash 变量
docker
:
- run:
name: Set up docker
command: |
if [[ $CIRCLE_SHELL_ENV == *"localbuild"* ]]; then
echo "export docker='sudo docker'" >> $BASH_ENV
else
echo "export docker='docker'" >> $BASH_ENV
fi
然后你可以在你的配置中使用它
- run:
name: Verify docker
command: $docker --version
有关 CircleCi 中环境变量的文档
您还可以通过以 root 身份运行 docker 映像来解决您的问题。在
user: root
参数下指定 image
:
...
jobs:
build:
working_directory: ~/app
docker:
- image: circleci/node:8.4.0
user: root
steps:
- checkout
...
...
如果您可以通过自托管运行器访问主机,则另一种方法是将
circleci
用户添加到 docker
组。
sudo usermod -aG docker circleci
sudo systemctl restart circleci-runner
在Linux系统上,只有属于
docker
组的用户才能运行没有sudo
的docker命令。
查找运行
circleci-runner
服务的用户。
systemctl show -pUser,UID circleci-runner
UID=1001
User=circleci
将
circleci
用户添加到 docker
组。
sudo usermod -aG docker circleci
重新启动
circleci-runner
服务以使更改生效。
sudo systemctl restart circleci-runner
这避免了对 config.yml 的任何更改