Live data from Hacker News

Containerize Go and SQLite with Docker

awstip.com

71–80 of 90 posts

Re: Containerize Go and SQLite with Docker

#71
post #68

Earlier quoted context omitted.

Okay, I'll bite. > It's also a deployment format that provides horizontal scaling for free. Um. Docker does not provide horizontal scaling at all, for that you need orchestration. And those tools are anything but free if your time has any value.

I think what the OP means that using Docker you can use tools that give horizontal scaling for free (see: Cloud Run etc.)

The claim that horizontal scaling is free with Docker is simply not accurate.

Maybe it will be some day, but these orchestration and deployment tools built on Docker have enormous hidden costs.

IME, Docker takes an enormous amount of focus away from the customer problem and moves it to the how to get this mess working problem.

Now may be the right time in a given business to make that shift in focus, but to claim that it will be "free" is just misleading (IME).

Re: Containerize Go and SQLite with Docker

#72
post #67

It's hard to believe anyone is still promoting Docker. Has anyone actually used it? If you haven't jumped on the bandwagon yet, don't do it. It's a sucker's game. I got sucked into the Docker hype some years ago and the demos worked well enough in isolation. I pushed it on a small team that didn't need it. One of the biggest regrets of my career. Docker may be useful if an application has enormous reach and needs Goo…

> Docker may be useful if an application has enormous reach and needs Google scale, but very few apps do. > I got sucked into the Docker hype some years ago and the demos worked well enough in isolation. > I pushed it on a small team that didn't need it. One of the biggest regrets of my career.

It sounds like (no offence) issues that containerization solved were missed and you had no dedicated operations/build-engineer guy on your team that could've explained/fixed these things for you and steer your infra in a right direction.

> I still feel bad about it. The company could have run on a couple $400 machines under a desk for years, but instead spent tens of thousands on AWS services it didn't need.

Does not sound like a docker issue. If you actually plan to run a money making business that your livelihood depends on, then running it under your desk is not something that you can reliably do even 10-15 years ago.

AWS is a money hog with a lot of things that are a distraction for a small project and it is easy to assume that their products are necessary to run your app effectively, but most often it is not. There is plenty of cloud providers that are not as expensive, and are much easier to manage compared to AWS.

> K8s is a total disaster for a small team working on a small project.

This is truly a YMMV thing. in my experience managed k8s for a small team can be a godsend for infra management after some level of complexity is reached, while self-hosted bare-metal k8s can utterly decimate the team. But again YMMV.

I am currently running several clusters of Nomad for different types of workloads each. CI, HPC, VM's, public facing services you name it. Containerization makes it all possible to run (mostly) single-handedly.

Re: Containerize Go and SQLite with Docker

#73
post #23

If you are using Go (which solves most of your dependency problems) and SQLite (which means you don't need to integrate with an external database via service discovery) why do you need Docker at all?

I think the only reason I still use docker for everything is for automatic restarts without worrying about another tool for whatever language/framework I'm working with

Re: Containerize Go and SQLite with Docker

#74
Testing locally, adding the "-linkmode external -extldflags '-static'" flags doesn't bring down the binary size. The heavy lifting is done by '-s -w'. It is a good idea to drop privileges even if there's a small attack surface.

At $work we use the following template. Sharing in case you find it interesting:

    FROM golang:1.17.1-alpine3.14 as builder
    RUN apk update && apk add ca-certificates curl git make tzdata
    RUN adduser -u 5003 --gecos '' --disabled-password --no-create-home mycompany
    COPY . /app
    WORKDIR /app
    RUN make build
    
    FROM scratch
    COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
    COPY --from=builder /app/bin/app-3 /bin/app-3
    COPY --from=builder /etc/passwd /etc/passwd
    USER mycompany
    CMD ["app-3"]

And a very simple makefile:

    help:
     @echo "Please use 'make ' where  is one of the following:"
     @echo "  test                 to run unit tests."
     @echo "  build                to build the app as a binary."
     @echo "  build-image          to build the app container."
     @echo "  run                  to run the app with go."
    
    run:
     go run -ldflags="$(govvv -flags -pkg) -w -s" ./cmd/app-3/main.go
    
    test:
     go test -v -coverpkg=./... -coverprofile=profile.cov ./...
     go tool cover -func profile.cov
     rm profile.cov
    
    build:
     CGO_ENABLED=0 go build -mod=readonly -a -ldflags="$(govvv -flags -pkg $(go list ./info)) -w -s -linkmode external -extldflags '-static'" -o ./bin/app-3 ./cmd/app-3/*
    
    build-image:
     docker build -t mycompanytown/app-3:latest .

Re: Containerize Go and SQLite with Docker

#75
post #6
post #3

This is really interesting. Copying to the scratch container is powerful and I’ve used it a lot, regularly, but occasionally something comes up where I need to use a more fully featured base to support things. One other downside I’ve encountered with Scratch is no shell so doing docker exec or kubectl exec doesn’t work. Does anyone know a good solution to this problem?

We drop a statically compiled BusyBox binary on images like that as "sh". If we need more we can symlink to it in /tmp at debug time (or just call it directly). It strikes a good balance between slim and debuggable.

Been using containers and fighting this problem for a long time... I never thought of this simple solution, thank you for sharing it!

Re: Containerize Go and SQLite with Docker

#76
post #41
post #34

Earlier quoted context omitted.

In a production environment one would probably deploy using something like Fargate, Kubernetes or Fly.io.

> In a production environment one would probably deploy using something like Fargate, Kubernetes or Fly.io. Docker swarm mode is pretty good and terribly easy to get up and running in no time. I have a few small personal projects hosted on Herzner on a couple of Docker swarm mode deployments with 100% uptime in the past two years, and all it took to get that infra up and running is installing Docker on a bare Linux n…

I've worked with docker swarm extensively. I've managed it but also automated the deployment and implemented several features to ease deployment using the swarm API.

Swarm pros:

- Easy to setup

- Easy to run

- Relatively easy to debug

Swarm cons:

- Many problems persist for years. Some because of lack of resources, others because the problem is simply too hard.

- The community and automation around swarm is small

- Problems solved by third party tools, apps, etc. in kubernetes require in-house workarounds or solutions (e.g. there was an API to perform autoscaling, but we had to write the python app that will read data from prometheus and scale-in/out the deployment)

What I found it with Swarm is that it was extremely resilient. At some point the swarm cluster was running on AWS for ~2 years with minimal maintenance. That would have been impossible even for a managed EKS cluster for example. There are simply too many things that can go wrong.

Re: Containerize Go and SQLite with Docker

#77
post #5

Earlier quoted context omitted.

And if you can spare an extra ~150ms startup time: https://blog.filippo.io/shrink-your-go-binaries-with-this-on...

Serious question: Is upx worth the tradeoff in 2022? Trying to decide if it's worth working into the containers that I maintain.

Probably not for Go in containers since binaries end up compressed anyway as part of the OCI layers. But Go binaries do get quite large so if you're distributing them other ways, it might be useful.

Re: Containerize Go and SQLite with Docker

#78
post #71

Earlier quoted context omitted.

I think what the OP means that using Docker you can use tools that give horizontal scaling for free (see: Cloud Run etc.)

The claim that horizontal scaling is free with Docker is simply not accurate. Maybe it will be some day, but these orchestration and deployment tools built on Docker have enormous hidden costs. IME, Docker takes an enormous amount of focus away from the customer problem and moves it to the how to get this mess working problem. Now may be the right time in a given business to make that shift in focus, but to claim tha…

> IME, Docker takes an enormous amount of focus away from the customer problem and moves it to the how to get this mess working problem.

This is the opposite in my experience: Docker lets me focus on the business problem by making deployment easier.

Re: Containerize Go and SQLite with Docker

#79
post #74

Testing locally, adding the "-linkmode external -extldflags '-static'" flags doesn't bring down the binary size. The heavy lifting is done by '-s -w'. It is a good idea to drop privileges even if there's a small attack surface. At $work we use the following template. Sharing in case you find it interesting: FROM golang:1.17.1-alpine3.14 as builder RUN apk update && apk add ca-certificates curl git make tzdata RUN add…

What do you use the SSL certs in the container for? I always have run Docker behind either a reverse proxy like Nginx or in some kind of cloud platform that handles SSL at the perimeter.

Re: Containerize Go and SQLite with Docker

#80
post #47
post #42

Earlier quoted context omitted.

Yeah, but for Docker to handle the complexities of deployment, you first need to handle the complexities of Docker. So OP's question is valid: for most Go apps, all you have to do is compile a binary and copy it to the server - no Docker or other paraphernalia required. Of course that may not be so simple due to various reasons, but it helps to keep that possibility in mind...

> you first need to handle the complexities of Docker The complexity of Docker is not that big for a Go deployment though, especially if you have all the other bits for orchestrating your Docker containers (for the rest of your stack) already in place. You mostly just copy the binary into a slim image and you are done.

> You mostly just copy the binary into a slim image and you are done.

You don't need docker for that, just 'tar czf my-layer.tar.gz my-dir'. If you want a manifest file, you can get the digest using `sha256sum my-layer.tar.gz`.

Post reply on HN