Reputation: 19
My goal is to compare two docker solutions for my golang app:
My Dockerfile is quite straight-forward, similar to:
FROM ubuntu:20.04
# FROM golang:alpine for alpine based images
# myApp binary is pre-built before running docker build
COPY bin/myApp app/myApp
COPY myApp-config.json app/myApp-config.json
CMD MYAPP_CONFIG=app/myApp-config.json ./app/myApp
With alpine-based images, I hit the same issue here, where /app/myApp cannot be started due to missing CGO dynamic links in my generated image. I addressed it by disabling CGO during go build:
CGO_ENABLED=0
Since I'm quite new to docker, my questions are:
net/http
which seems to be requiring presence of CGO during runtime.Thanks!
Upvotes: 0
Views: 1846
Reputation: 22097
If your app is net/http
based - then really the only consideration you may need to worry about is with DNS resolution.
TL;DR
The only gotchas you may see is in a kubernetes environment with a hostname
ending in .local
With CGO_ENABLED=1
(the go build default) it will use the native OS's DNS resolver.
With CGO_ENABLED=0
used with scratch
Docker builds - then Go's DNS resolver is used.
What's the difference? See the official Go docs:
The method for resolving domain names, whether indirectly with functions like Dial or directly with functions like LookupHost and LookupAddr, varies by operating system.
On Unix systems, the resolver has two options for resolving names. It can use a pure Go resolver that sends DNS requests directly to the servers listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C library routines such as getaddrinfo and getnameinfo.
By default the pure Go resolver is used, because a blocked DNS request consumes only a goroutine, while a blocked C call consumes an operating system thread. When cgo is available, the cgo-based resolver is used instead under a variety of conditions: on systems that do not let programs make direct DNS requests (OS X), when the LOCALDOMAIN environment variable is present (even if empty), when the RES_OPTIONS or HOSTALIASES environment variable is non-empty, when the ASR_CONFIG environment variable is non-empty (OpenBSD only), when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the Go resolver does not implement, and when the name being looked up ends in .local or is an mDNS name.
Personally, I've built dozens of net/http
based microservices running in kubernetes in scratch
Docker containers with CGO_ENABLED=0
without issue.
Upvotes: 6