Go应用程序失败并在使用docker-compose运行时退出,但可与docker run命令配合使用

I am running all of these operations on a remove server that is a VM running Ubuntu 16.04.5 x64.

My Go project's Dockerfile looks like:

FROM golang:latest

ADD . $GOPATH/src/example.com/myapp
WORKDIR $GOPATH/src/example.com/myapp
RUN go build

#EXPOSE 80

#ENTRYPOINT $GOPATH/src/example.com/myapp/myapp
ENTRYPOINT ./myapp
#CMD ["./myapp"]

When I run the docker container using docker-compose up -d, the Go application exits and I see this in the docker logs:

myapp_1 | /bin/sh: 1: ./myapp: Exec format error docker_myapp_1 exited with code 2

If I locate the image using docker images and run the image like:

 docker run -it 75d4a95ef5ec 

I can see that my golang applications runs just fine:

viper environment is: development HTTP server listening on address: ":3005"

When I googled for this error some people suggested compiling with some special flags but I am running this container on the same Ubuntu host so I am really confused why this isn't working using docker.

My docker-compose.yml looks like:

version: "3"

services:
  openresty:
    build: ./openresty
    ports:
     - "80:80"
     - "443:443"
    depends_on:
      - myapp
    env_file:
     - '.env'
    restart: always

  myapp:
    build: ../myapp
    volumes:
     - /home/deploy/apps/myapp:/go/src/example.com/myapp
    ports:
      - "3005:3005"
    depends_on:
      - db
      - redis
      - memcached
    env_file:
      - '.env'

  redis:
    image: redis:alpine
    ports:
    - "6379:6379"
    volumes:
     - "/home/deploy/v/redis:/data"
    restart: always

  memcached:
    image: memcached
    ports:
      - "11211:11211"
    restart: always

  db:
    image: postgres:9.4
    volumes:
      - "/home/deploy/v/pgdata:/var/lib/postgresql/data"
    restart: always

Your docker-compose.yml file says:

volumes:
 - /home/deploy/apps/myapp:/go/src/example.com/myapp

which means your host system's source directory is mounted over, and hides, everything that the Dockerfile builds. ./myapp is the host's copy of the myapp executable and if something is different (maybe you have a MacOS or Windows host) that will cause this error.

This is a popular setup for interpreted languages where developers want to run their application without running a normal test-build-deploy sequence, but it doesn't really make sense for a compiled language like Go where you don't have a choice. I'd delete this block entirely.

The Go container stops running because of this:

WORKDIR $GOPATH/src/example.com/myapp
RUN go build

#EXPOSE 80

#ENTRYPOINT $GOPATH/src/example.com/myapp/myapp
ENTRYPOINT ./myapp

You are switching directories to $GOPATH/src/example.com/myapp where you build your app, however, your entry point is pointing to the wrong location.

To solve this, you either copy the app into the root directory and keep the same ENTRYPOINT command or you copy the application to a different location and pass the full path such as:

ENTRYPOINT /my/go/app/location