techschool / simplebank

Backend master class: build a simple bank service in Go
MIT License
5.18k stars 939 forks source link

May I ask why an exec format error occurs during docker run? #109

Closed moluzhui closed 8 months ago

moluzhui commented 9 months ago

I followed the video to learn how to build the image. When I ran the container, the following error occurred.

$ docker run --rm simplebank:latest
exec /app/start.sh: exec format error

My Dockerfile is as follows

# Build stage
FROM golang:1.21-alpine3.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o main main.go
RUN apk add curl
RUN curl -L https://github.com/golang-migrate/migrate/releases/download/v4.16.2/migrate.linux-amd64.tar.gz | tar xvz

# Run stage
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/migrate ./migrate
COPY app.env .
COPY start.sh .
COPY wait-for.sh .
COPY db/migration ./migration

EXPOSE 8000
CMD [ "/app/main" ]
ENTRYPOINT [ "/app/start.sh" ]

But when I comment out ENTRYPOINT, there are no errors and the debug log of the gin framework can be printed normally.

And when I use the following docker compose to run, this error will not be reported, and the debug log of the gin framework can be printed normally.

version: "3.9"
services:
  postgres:
    image: postgres:14-alpine
    environment:
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=simple_bank
    ports:
      - "5432:5432"
  api:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    environment:
      - DB_SOURCE=postgresql://root:secret@postgres:5432/simple_bank?sslmode=disable
    depends_on:
      - postgres
    entrypoint:
      [
        "/app/wait-for.sh",
        "postgres:5432",
        "--",
        "/app/start.sh"
      ]
    command: [ "/app/main" ]

My start.sh is as follows, and also granted executable permissions

#/bin/sh
set -e

echo "run db migration"
source /app/app.env
/app/migrate -path /app/migration -database "$DB_SOURCE" -verbose up

echo "start the app"
exec "$@"

I don't know where the error is caused. Look forward to your reply.

PS: OS is centos8

$ docker version
Client: Docker Engine - Community
 Version:           24.0.2
 API version:       1.43
 Go version:        go1.20.4
 Git commit:        cb74dfc
 Built:             Thu May 25 21:53:10 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.2
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.4
  Git commit:       659604f
  Built:            Thu May 25 21:52:10 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
yokaimeow commented 9 months ago

chmod +x start.sh

yokaimeow commented 9 months ago

chmod +x wait-for.sh

moluzhui commented 9 months ago

chmod +x wait-for.sh

@yokaimeow I added executable permissions, then rebuilt the image and ran it. But the error persists, and I try to enter directly through the following command when running the image. The files have permissions.

$ docker run --rm -it --entrypoint="" simplebank:latest sh
/app # ls -lah
total 62M
drwxr-xr-x    1 root     root          23 Nov 30 17:16 .
drwxr-xr-x    1 root     root          18 Dec  1 17:04 ..
-rw-rw-r--    1 root     root         204 Nov 23 14:28 app.env
-rwxr-xr-x    1 root     root       13.1M Nov 30 16:33 main
-rwxr-xr-x    1 1001     ntp        48.7M Jun 11 22:21 migrate
drwxr-xr-x    2 root     root         138 Nov 16 15:54 migration
-rwxrwxr-x    1 root     root         164 Nov 30 17:15 start.sh
-rwxrwxr-x    1 root     root        4.2K Nov 29 15:16 wait-for.sh

Then I go in and execute the following command, and the debug log can be printed normally. This question is a bit strange

/app # /app/start.sh /app/main
run db migration
start the app
...
gin log
yokaimeow commented 9 months ago

I think the container not on the same docker network.

docker compose up -d --build
frogfromlake commented 8 months ago

It seems like your shebang in your start.sh is not correct: #!/bin/sh You are missing the "!". The shebang (#!) is used to tell the system what interpreter to use to parse the rest of the file, so it could be causing your error.

moluzhui commented 8 months ago

It seems like your shebang in your start.sh is not correct: #!/bin/sh You are missing the "!". The shebang (#!) is used to tell the system what interpreter to use to parse the rest of the file, so it could be causing your error.

thank you very much. I made such a low-level mistake.