Search code examples
dockergodocker-composedockerfile

docker-compose with golang, nginx and postgres cannot find ./main


I am trying to run a docker-compose setup with 3 containers: golang app (api), postgres and nginx. I created the docker-compose file and a Dockerfile for golang. I tried different approaches, but I still have an error "Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./main": stat ./main: no such file or directory: unknown" coming from the Dockerfile. Some how the RUN go build -o main . is creating the bin in a different location. Here is my docker-compose file located at the root of my project:

version: '3.8'

services:
  apigateway:
    build:
      context: .
      dockerfile: .docker/go/Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - ./apigateway:/apigateway
    depends_on:
      - postgres
    networks:
      - app-network

  nginx:
    image: nginx:1.26.0
    ports:
      - "80:80"
    volumes:
      - ./.docker/nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - apigateway
    networks:
      - app-network
  postgres:
    image: postgres:16.2
    ports:
      - "5210:5432"
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network
volumes:
  postgres_data:

networks:
  app-network:

The Dockerfile is located in .docker/go/Dockerfile and it contains:

FROM golang:1.22-alpine

RUN apk update && apk upgrade && \
    apk add --no-cache bash openssh

WORKDIR /apigateway

COPY ./apigateway/go.mod ./apigateway/go.sum ./

RUN go mod download

COPY ./apigateway .

RUN go build -o main .

EXPOSE 8080

CMD ["./main"]

Any help is really appreciated.

I tried to create the bin and copy it to be executed but it's not working as the bin is built in macos and cannot be executed in linux. I played also a lot with the path in the Dockerfile but didn't get any success


Solution

  • The volumes: block in your Compose file overwrites everything in your image with content from the host. That includes the compiled binary: your image should have a /apigateway/main binary, but because the entire /apigateway directory is hidden by the bind mount, you can't see it.

    You can safely delete the volumes: block, and then you will use the binary built into the image.

    services:
      apigateway:
        # volumes:                      <-- delete
        #   - ./apigateway:/apigateway  <-- delete