Docker容器中Go应用CMD执行报错:./server未找到
Docker运行Go应用报错:./server: not found
报错信息
golang-api | /bin/sh: ./server: not found golang-api exited with code 127
相关配置文件
Dockerfile
FROM golang:1.18-alpine RUN apk add g++ && apk add make WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN make build EXPOSE 8000 CMD ./server
Makefile
LINUX_AMD64 = GOOS=linux GOARCH=amd64 CGO_ENABLED=1 GO111MODULE=on migrate: cd cmd/migrations/$(FOLDER) && go run main.go build: cd cmd && $(LINUX_AMD64) go build -a -v -tags musl -o server
docker-compose.yml
version: '3.1' services: api: build: dockerfile: Dockerfile context: . container_name: golang-api ports: - "8000:8000" restart: unless-stopped depends_on: - db environment: - "POSTGRES_URL=$POSTGRES_URL" db: image: postgres restart: always environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres ports: - '5432:5432'
完整构建运行输出
Building api Sending build context to Docker daemon 74.24kB Step 1/9 : FROM golang:1.18-alpine ---> 6078a5fce1f5 Step 2/9 : RUN apk add g++ && apk add make ---> Using cache ---> 2a85b9182b80 Step 3/9 : WORKDIR /app ---> Using cache ---> baf1e6b7047c Step 4/9 : COPY go.mod go.sum ./ ---> Using cache ---> 1f2d031bc1b0 Step 5/9 : RUN go mod download ---> Using cache ---> 471d6f24e6a9 Step 6/9 : COPY . . ---> eaa86ff7cb1b Step 7/9 : RUN make build ---> Running in d6ae6ce79222 cd cmd && GOOS=linux GOARCH=amd64 CGO_ENABLED=1 GO111MODULE=on go build -a -v -tags musl -o server internal/goos internal/goarch internal/race internal/unsafeheader internal/goexperiment runtime/internal/syscall internal/cpu sync/atomic runtime/internal/atomic internal/itoa math/bits internal/abi runtime/internal/math runtime/internal/sys unicode/utf8 unicode container/list crypto/internal/subtle crypto/subtle unicode/utf16 vendor/golang.org/x/crypto/cryptobyte/asn1 internal/nettrace vendor/golang.org/x/crypto/internal/subtle encoding github.com/mymachine/my-api/internal/controllers/dto github.com/mymachine/my-api/internal/controllers/helpers internal/bytealg math runtime internal/reflectlite sync internal/testlog internal/singleflight math/rand runtime/cgo errors sort internal/oserror strconv path vendor/golang.org/x/net/dns/dnsmessage io crypto/elliptic/internal/fiat syscall golang.org/x/text/internal/tag hash bytes strings hash/crc32 reflect crypto crypto/internal/randutil crypto/hmac crypto/rc4 net/http/internal/ascii vendor/golang.org/x/crypto/hkdf regexp/syntax github.com/jackc/chunkreader/v2 bufio crypto/elliptic/internal/nistec internal/syscall/unix time internal/syscall/execenv vendor/golang.org/x/text/transform golang.org/x/crypto/pbkdf2 golang.org/x/text/transform golang.org/x/text/runes golang.org/x/text/width regexp internal/poll io/fs context github.com/mymachine/my-api/internal/entities github.com/jackc/pgconn/internal/ctxwatch embed os github.com/jinzhu/inflection github.com/jinzhu/now internal/fmtsort encoding/binary crypto/ed25519/internal/edwards25519/field crypto/md5 crypto/sha512 crypto/cipher crypto/sha256 crypto/sha1 encoding/base64 fmt internal/godebug encoding/pem crypto/ed25519/internal/edwards25519 path/filepath vendor/golang.org/x/crypto/internal/poly1305 io/ioutil internal/intern vendor/golang.org/x/crypto/curve25519/internal/field vendor/golang.org/x/sys/cpu net/netip crypto/aes crypto/des vendor/golang.org/x/crypto/chacha20 github.com/jackc/pgio github.com/jackc/pgpassfile os/exec os/signal net vendor/golang.org/x/crypto/chacha20poly1305 math/big encoding/hex net/url compress/flate vendor/golang.org/x/crypto/curve25519 log vendor/golang.org/x/text/unicode/norm vendor/golang.org/x/text/unicode/bidi vendor/golang.org/x/net/http2/hpack mime mime/quotedprintable compress/gzip net/http/internal database/sql/driver github.com/mymachine/my-api/internal/pkg/errors encoding/json github.com/jackc/pgservicefile vendor/golang.org/x/text/secure/bidirule golang.org/x/text/internal/language database/sql golang.org/x/text/unicode/norm golang.org/x/text/unicode/bidi vendor/golang.org/x/net/idna os/user crypto/rand encoding/asn1 crypto/dsa crypto/elliptic crypto/ed25519 crypto/rsa github.com/jackc/pgproto3/v2 golang.org/x/text/internal/language/compact golang.org/x/text/secure/bidirule github.com/jackc/pgx/v4/internal/sanitize golang.org/x/text/language go/token vendor/golang.org/x/crypto/cryptobyte crypto/x509/pkix gorm.io/gorm/utils gorm.io/gorm/logger encoding/gob go/scanner golang.org/x/text/internal github.com/joho/godotenv crypto/ecdsa go/ast golang.org/x/text/cases github.com/joho/godotenv/autoload golang.org/x/text/secure/precis gorm.io/gorm/clause gorm.io/gorm/schema gorm.io/gorm net/textproto vendor/golang.org/x/net/http/httpproxy github.com/google/uuid crypto/x509 github.com/jackc/pgtype mime/multipart vendor/golang.org/x/net/http/httpguts crypto/tls gorm.io/gorm/migrator gorm.io/gorm/callbacks net/http/httptrace github.com/jackc/pgconn net/http github.com/jackc/pgconn/stmtcache github.com/jackc/pgx/v4 github.com/jackc/pgx/v4/stdlib gorm.io/driver/postgres github.com/mymachine/my-api/internal/infrastructure/repository github.com/mymachine/my-api/configs github.com/mymachine/my-api/internal/services github.com/mymachine/my-api/internal/services/transaction github.com/mymachine/my-api/internal/controllers/handlers/health github.com/gorilla/mux github.com/mymachine/my-api/internal/controllers/handlers/transaction github.com/mymachine/my-api/internal/router github.com/mymachine/my-api/cmd Removing intermediate container d6ae6ce79222 ---> 621aa6a266de Step 8/9 : EXPOSE 8000 ---> Running in 3cbd17d32c37 Removing intermediate container 3cbd17d32c37 ---> 754f71a7753e Step 9/9 : CMD ./server ---> Running in dfcdc8cd45ce Removing intermediate container dfcdc8cd45ce ---> 511dbf89a001 Successfully built 511dbf89a001 Successfully tagged my-api_api:latest Creating my-api_db_1 ... done Creating golang-api ... done Attaching to my-api_db_1, golang-api golang-api | /bin/sh: ./server: not found
问题原因
- 二进制文件路径错误:Makefile的
build命令中,执行cd cmd && ... go build -o server,生成的server二进制文件位于/app/cmd/目录下,但Dockerfile的WORKDIR是/app,CMD执行./server会在/app目录下查找,自然找不到。 - CGO依赖问题(路径修复后可能出现):当前构建开启了
CGO_ENABLED=1,生成的二进制文件依赖动态库,而alpine镜像默认缺少部分系统库,可能导致即使路径正确仍报错。
解决方案
方案1:修改CMD命令,指定正确路径
将Dockerfile中的CMD ./server修改为:
CMD ./cmd/server
方案2:调整Makefile,将二进制输出到/app目录
修改Makefile的build目标,将输出路径指向上级目录:
build: cd cmd && $(LINUX_AMD64) go build -a -v -tags musl -o ../server
方案3:关闭CGO,构建静态二进制(解决动态库依赖)
修改Makefile中的LINUX_AMD64变量,关闭CGO:
LINUX_AMD64 = GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GO111MODULE=on
重新构建后,生成的二进制不依赖系统动态库,能直接在alpine中运行。
内容的提问来源于stack exchange,提问作者joao
相关产品推荐
相关产品推荐

