謎のgo starting container process caused “exec: “command”: permission denied”: unknownにハマった話

  • 事象
  • 解決方法
  • 原因について考えてみる

事象


こちらの記事で、SwaggerEditorで生成したGo-Serverをコンテナで動かすDockerfileを作成しました。

FROM golang:latest
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
    go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
# go build
RUN go build -o api
# API実行コマンドの実行
CMD ["./api"]

ディレクトリ構造は以下の通りです。

$ tree api/
api/
├── Dockerfile
└── src
    ├── api
    │   └── swagger.yaml
    ├── go
    │   ├── README.md
    │   ├── api_user.go
    │   ├── logger.go
    │   ├── model_user.go
    │   └── routers.go
    └── main.go

上記のDockerfileをビルドして実行すると、以下のエラーが発生しました。このようなエラーは大抵ユーザー権限がない場合に出るのですが、rootユーザーでの実行のため不思議でした。

docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"./api\": permission denied": unknown.

念のためgouserに権限を持たせて実行してみましたが、事象は同じでした。

FROM golang:latest
# gouserの作成
RUN useradd -m -s /bin/bash gouser
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
RUN chown gouser:gouser /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
    go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY --chown=gouser:gouser ./src .
# go build
RUN go build -o api &&\
    chown gouser:gouser api
# gouserに変更
USER gouser
# API実行コマンドの実行
CMD ["./api"]

解決方法


rootでの実行なのにエラーが出るので試行錯誤しましたが、結果的には以下の方法で解決しました。

解決方法:ビルドファイルの名前をapiから別の名前に変更する

FROM golang:latest
# コンテナ作業ディレクトリの変更
WORKDIR /go/src/api
# モジュールのダウンロード
RUN go get -u github.com/gorilla/mux &&\
    go get -u "go.mongodb.org/mongo-driver/mongo"
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
# go build
RUN go build -o koratta-api
# API実行コマンドの実行
CMD ["./koratta-api"]

原因について考えてみる


よく考えると、apiという名前のディレクトリが同じ階層にありました。

ディレクトリ名をapi→yamlに変更して再度実行したところ、実行ファイルがapiでもエラーが解消されました。

$ mv src/api src/yaml

以上です。まさかこんなことにハマるなんて。。。