mattes / migrate

Database migrations. CLI and Golang library.
Other
2.29k stars 326 forks source link

Created Docker image #226

Open sagikazarmark opened 7 years ago

sagikazarmark commented 7 years ago

I created a docker image for your software:

https://github.com/webplates/docker-migrate

Useful when you want to run it in CI processes (which is where I use this image).

It's currently based on an Ubuntu base image, but I intend to make the image smaller:

https://github.com/webplates/docker-migrate/issues/1

Unfortunately the pre-built binaries do not work neither in an alpine nor in a scratch image. I'm still investigating why.

I just wanted to let you know about the image (maybe you would accept it as a contribution?), feel free to close this issue.

mattes commented 7 years ago

did you see https://github.com/mattes/migrate/blob/master/cli/examples/Dockerfile ?

please let me know what you find out regarding alpine. would be nice to make sure we could get that to work as well.

sagikazarmark commented 7 years ago

Ah, no, I missed it. I might have a few improvement ideas though, also: is it on Docker Hub? Would be nice to have an "official" migrate image.

please let me know what you find out regarding alpine.

Will do.

mattes commented 7 years ago

Not on docker hub. Yes, please feel free to open any PRs to help improve! Thanks!

sagikazarmark commented 7 years ago

Do you plan to publish it on Docker Hub?

mattes commented 7 years ago

What's the best namespace to host it? Ideally the docker push happens within travis.

sagikazarmark commented 7 years ago

I guess it would be your namespace. Pushing docker images from travis is quite easy. Take a look at this example:

https://github.com/deshboard/boilerplate-model-service/blob/master/.travis.yml#L44

You need to add DOCKER_USER and DOCKER_PASS env vars either to your travis config or on the dashboard. Done.

mattes commented 7 years ago

sounds good. I can do that. You said you had some ideas for Dockerfile improvements? Do you want to create a PR with a Dockerfile in the /cli dir?

sagikazarmark commented 7 years ago

I also played a bit with the alpine issue. It seems to be working after all, but not with the binaries you built on travis. I used the same Makefile. The only difference might be the Go version.

Would you prefer a scratch, an alpine or an ubuntu container?

mattes commented 7 years ago

I don't have any preferences. The smaller the image, the better.

stepankuzmin commented 7 years ago

Any news on that?

sagikazarmark commented 6 years ago

With the new multi build stage we can easily create a scratch image and still avoid involving travis into the process.

See this dockerfile.

If you are happy with it I can provide a PR with the content, all you have to do is configuring Docker Hub to automatically build an image whenever you release a new version.

As a side note: my example downloads the prebuilt binaries which we probably can't do in an official image, because we would have to wait for travis to finish and build the binaries and unfortunately we can't guarantee that. We could probably configure build hooks from travis to docker hub, but that requires a bit more playing and testing.

In the meantime @stepankuzmin you can use my image.

alecmev commented 6 years ago

@sagikazarmark The pre-built migrate binary is dynamically linked against glibc (see #241), which means that it shouldn't work in neither scratch nor alpine. I've pulled your image, and it panics with this:

standard_init_linux.go:178: exec user process caused "no such file or directory"

Please, consider deriving from frolvlad/alpine-glibc instead, until the issue I linked to is fixed (and then maybe switch to alpine in place of scratch, it's kind of nice to have ash, just in case).

Edit: Didn't want to wait, so created my own version, published as jeremejevs/mattes-migrate.

sagikazarmark commented 6 years ago

Oh wow, thanks @jeremejevs , dunno how I missed this, I built the image locally and it worked.

I moved to the aformentioned image for now.

Regarding the base image: although it's not that big, I kinda like using scratch images instead of alpine for these kind of projects. That way an image is nothing more, but a wrapper for the application. Normally you could just use the pre-built binary as well, Docker image in this case is just a convenience layer. That being said, I'm convincable if you can tell me what you can achieve with a shell that you can't do without it (given that you can only use migrate, but nothing else) ;)

alecmev commented 6 years ago

Well, okay, it's nice to have the whole package, not just a shell.

In general, I'm not even sure that static linking makes much sense in the container world. I can have several applications using the same alpine base, utilizing the same libc, saving traffic and space (I feel like migrate should probably be built against musl, since the original alpine is much more popular and more battle-tested than the glibc variant).

Also, say, later it may turn out that migrate needs ca-certificates for some rare edge case. I could fix that locally by just deriving from the image and adding RUN apk add ca-certificates. Before multi-stage, it would be a bit of a hurdle without a base OS.

Another usecase is having an ability to docker run --rm -it some-complex-app [b]ash and just explore the internals of the container. I could run some command inside of it, without mounting any volumes, and be sure that it won't damage/pollute the host. I do this regularly, when something doesn't work as expected. For example, when I derived from alpine and ran migrate, it panicked. So I opened ash and ran ldd to see what it links to, case solved. On scratch I could do nothing of such sort, not without hoop jumping.

sagikazarmark commented 6 years ago

In general, I'm not even sure that static linking makes much sense in the container world.

Well, migrate is not primarily created for the container world. I really hope migrate will be able to avoid dynamic linking once. Until then we don't have too much choice anyway.

Also, say, later it may turn out that migrate needs ca-certificates for some rare edge case.

If that happens, we can always replace the base image. A (hardly) possible future use case does not qualify as an argument for me to use alpine.

Another usecase is having an ability to docker run --rm -it some-complex-app [b]ash and just explore the internals of the container

In case of a container like this one (wrapping migrate) it's like saying you want to disassemble the binary. What is it that you want to/can inspect within the container that's (again) related to migrate?

Debugging seems to be the only acceptable argument, but even then it only makes sense when the problem you encounter is directly related to running inside the container which is IMO limited to a very few cases. (For those we have this) Otherwise one should debug migrate itself.

But as long as migrate uses dynamic linking we don't have much choice.

alecmev commented 6 years ago

Fair points. Thanks for the link, didn't know you could "leech" onto a container like that.

Well, migrate is not primarily created for the container world.

I mentioned the "container world" assuming that we could potentially build a special migrate binary for Docker, e.g. dynamically linked against musl.

Another argument for alpine is "Why not? Why scratch?". It's almost guaranteed to be in the cache (due to all official images having alpine-based editions), and if it isn't, then that's a one-time 5MB investment. A portion of that 5MB is the C library, some of which is otherwise integrated in the static binary (so a dynamically-linked migrate layer is smaller than a statically-linked one = less bytes to download). You get all the debugging/extension possibilities for essentially free. Negligible gain for migrate but, again, why not have it, if it's free?

But I personally don't mind either way. I'm happy as long as migrate:v1 is dockerized too 🙂