Hey, everybody! 🙌
This is a short note article that I can't help but share with the community, as I ran into this problem myself in my latest wonderful-readme-stats project.
So, this will be a very short post, but so important for anyone who wants to deploy a Go application that uses the built-in net/http package, in a Docker container.
OK, here we go!
📝 Table of contents
Description of the problem
I have a helper in my Go project that helps me make a request to the GitHub API and return a response. It is absolutely simple, but saves time as it is used in many places in the code (DRY):
// customHTTPClient makes an HTTP request to download the image from the given URL and returns the response.
func customHTTPClient(uri string) (*http.Response, error) {
// Check, if the URL is valid.
_, err := url.Parse(uri)
if err != nil {
return nil, err
}
// Create a new HTTP client with options.
client := &http.Client{
Timeout: 15 * time.Second,
Transport: &http.Transport{
TLSHandshakeTimeout: 10 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
}
// Make an HTTP request to download the image from the given URL.
req, err := http.NewRequest(http.MethodGet, uri, http.NoBody)
if err != nil {
return nil, err
}
defer req.Body.Close()
// Set authorization header.
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", os.Getenv("GITHUB_TOKEN"))
// Send the request to the HTTP server.
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
You may have noticed that I use strictly defined options to create a custom HTTP client. This is done for a reason! For more information, see this Cloudflare blog post.
📝 Note: Building the project for the Docker image is done automatically with GoReleaser. Therefore, I will not cover
Dockerfile
in detail.
Next, I run the finished image as always with this command on the remote server (Ubuntu 22.04):
docker run -d -p 9876:9876 koddr/wonderful-readme-stats:latest
But in the logs, I see the following error when trying to make a request from http.Client
to the GitHub API: tls: failed to verify certificate: x509: certificate signed by unknown authority
.
Wait a minute, why is that? 🤔
Useful links for explanation
Here are some useful links that helped me understand the cause of the problem and solve it:
- https://en.wikipedia.org/wiki/Certificate_authority
- https://stackoverflow.com/a/76309552
- https://support.hashicorp.com/hc/en-us/articles/8107320508947-x509-certificate-signed-by-unknown-authority-
Feel free to post your own in the comments.
Solving the problem
The solution was so simple that I didn't even believe it!
It was enough to add a Docker volume pointing to the directory of the server containing the certificates (/etc/ssl/certs
) when starting the container to make it work:
docker run -d \
-p 9876:9876 \
+ -v /etc/ssl/certs:/etc/ssl/certs:ro \
koddr/wonderful-readme-stats:latest
❗️ Important: Don't forget to add Docker volume in read-only mode (
:ro
).
And now the container works without errors and displays awesome statistics about the defined repository! 🎉
Photos and videos by
- Vic Shóstak https://github.com/koddr
P.S.
If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻
❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.
And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!
My main projects that need your help (and stars) 👇
- 🔥 gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
- ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
Top comments (3)
Great content. Sorry I only discovered it now. Thanks very much. This is the type of stuff no course teaches you!
Glad I could help. Thanks for the feedback!
very interesting post