运行docker compose up时遇permission denied错误(Golang微服务)
问题
我尝试运行docker compose up -d --build启动一个已通过docker-compose build成功构建的Golang微服务项目DeathStarBench。
项目Dockerfile内容如下:
FROM golang:1.21 as builder WORKDIR /workspace COPY go.sum go.sum COPY go.mod go.mod COPY vendor/ vendor/ COPY cmd/ cmd/ COPY dialer/ dialer/ COPY registry/ registry/ COPY services/ services/ COPY tls/ tls/ COPY tracing/ tracing/ COPY tune/ tune/ COPY config.json config.json RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go install -ldflags="-s -w" -mod=vendor ./cmd/...
docker-compose.yaml中每个微服务都配置了entrypoint和对应卷,以recommendation服务为例:
# <其他服务配置> recommendation: configs: - source: server_config target: /config.json environment: - TLS - GC - JAEGER_SAMPLE_RATIO - LOG_LEVEL build: . image: deathstarbench/hotel-reservation:latest entrypoint: ./cmd/recommendation depends_on: - mongodb-recommendation - consul restart: always deploy: replicas: 1 restart_policy: condition: any # ... volumes: # ... recommendation: # ... configs: server_config: file: ./config.json
每个cmd目录下的服务,entrypoint都设为entrypoint: ./cmd/<服务名>,配置看似正确。
运行环境为Ubuntu 22.04,Docker版本26.1.1, build 4cf5afa。
执行命令时出现错误:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./cmd/recommendation": is a directory: unknown: permission denied
每次失败的服务名称可能不同。
我尝试了以下方法但均未解决:
- 给./cmd下所有服务添加全权限,修改Dockerfile添加权限配置;
- 使用sudo运行docker compose up命令;
- 将当前用户加入docker组并重启系统;
- 修改docker socket权限为666。
请问该如何解决此问题?我的尝试操作是否存在问题?
解决方法
核心问题
错误提示已经明确指出:你试图执行的./cmd/recommendation是一个目录,而非可执行文件。
看Dockerfile中的RUN命令,go install会把编译好的可执行文件放到Golang容器默认的$GOPATH/bin目录(即/go/bin),不会留在./cmd/<服务名>目录下。你在docker-compose里指定的entrypoint路径完全错误,自然找不到可执行文件。
两种修复方案
直接修正docker-compose的entrypoint路径
把每个服务的entrypoint改为/go/bin/<服务名>,比如recommendation服务:entrypoint: /go/bin/recommendation所有服务都需要对应修改为
/go/bin/<服务名>。修改Dockerfile,将可执行文件复制到指定目录
在Dockerfile的builder阶段之后,添加步骤把/go/bin下的可执行文件复制到/workspace/cmd目录:RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go install -ldflags="-s -w" -mod=vendor ./cmd/... # 新增复制步骤 RUN cp /go/bin/* /workspace/cmd/这样原来的entrypoint
./cmd/recommendation就能找到可执行文件了。
你之前尝试的问题
你做的权限修改、sudo运行、调整docker组或socket权限,都没有触及核心问题——执行路径指向的是目录而非可执行文件,这些操作自然无法解决错误。
内容的提问来源于stack exchange,提问作者OmG

