-
Notifications
You must be signed in to change notification settings - Fork 443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Provide task to stage output in a format sufficient to build Docker images #236
Conversation
…mages. This creates a new docker config, and updates the stage task to create a Dockerfile which can create an image capable of running an application. It works with basic Java applications, and basic Play 2.2 applications.
Thanks. This looks very interesting. Can you provide a small description what this extension should offer for docker packaging? I just learned about docker and think this could fit nicely in an archetype. Wonder what the rest things, @jsuereth , @kardapoltsev , @aparkinson ? |
} | ||
)) | ||
|
||
private[this] def stageFiles(config: String)(cacheDirectory: File, to: File, mappings: Seq[(File, String)]): Unit = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably share this somewhere if you plan to use it over here too.
This looks like a really great start!!! Would love to see full docker support. I made a few notes on general architecture of native-packager and some adjustments I think should be made. Let me know what you think, if you have any questions. |
For the publishing side of things, either here or elsewhere: There are two ways I think one could build a Docker image: Another is to use the Docker remote API, which is what I'd prefer: http://docs.docker.io/reference/api/docker_remote_api_v1.10/
I would expect that publishing would allow the following settings:
|
I'm not convinced this should be an archetype, as I can imagine somebody wanting to create both a Debian package and a Docker image for a Play application... that isn't possible with archetypes? This seems to have more in common with the Universal config. |
Yes, it's possible. Since you set up Rpm and Debian setting you could run
It'll be nice to run docker:PackageBin and get Docker image. |
@kardapoltsev I'd like packageBin too, but I'm not sure of its utility. None of the native command-line tools have any interest in a tgz file or anything like that (unfortunately). It might be useful for sharing an image, except that a Docker registry seems to be a more standard method of transportation. |
I'm not suggesting that it should be an archetype. However, if you look at Debian/Rpm setups, they all have the hooks I described.
Then, the archetypes have mappings into both the Universal setting and The raw settings. |
The archetype was just an idea, so you can mixin your additional docker settings with one simple line |
@muuki88 I think docker is more like an "RPM", "DEB" thing. We actually want the inverse: Server/App archetypes should appropriately fill out docker info as needed. @garycoady can you give us more info into a docker registry, including how to publish to one? Also, to package for docker, would this require building on a docker instance, or can you do it from a different machine? |
Adds dockerPackageMappings which contains mappings specific to Docker build - defaults to reading from sourceDirectory/docker (overrideable). Builds mappings from dockerPackageMappings and universal:mappings (overrideable). Modifies "docker:stage" command to build a Docker context and Dockerfile from docker:mappings.
@jsuereth Updated code based on your initial comments. |
Docker registry: it should be possible to publish using the remote API I mentioned earlier, using a POST request to a /build endpoint on a HTTP server. The body should be a compressed tarball. You then should not need anything related to Docker to be present locally. I think this should also be possible without adding any new dependencies (dispatch is already required by sbt-native-packager), I'll try a proof of concept for this next. |
@garycoady What you have now actually looks good (and ready to merge if you want). As for publishing, you could try to do so through Ivy or just push w/ dispatch. I'm thinking whatever you do, it'd be fun if it could abide by the other ALso, sorry for the LONG delay in review. |
Fine by me. Should I merge? Future work will be another pull request. Thanks a lot @garycoady |
Yep. Merge is good |
I want to de-scope docker* settings to make them simpler to set, and re-use defaultLinuxInstallLocation instead of using defaultDockerInstallLocation. If you can wait until tomorrow, I'll push an update then. Other changes (but can wait for a different commit):
|
Sure, no problem :-) |
- Trait DockerPlugin should not extend DockerKeys - publishArtifact in Docker is false - do not generate POM/etc. - Tasks for stage do not depend on each other. - Change the CWD in the Docker container to install location. - Adding Docker-specific mappings happens outside mapGenericFilesToDocker - Use defaultLinuxInstallLocation instead of defaultDockerInstallLocation - dockerBaseImage is set outside Docker config, easier to override
In general about publishing, I'm still thinking of the best option. I don't like pulling dispatch/async-http-client/etc. into people's builds, it isn't a problem with bintray as it is only used when building this plugin. I would consider just using the docker binary, but I'd still like to manage credentials with SBT. Also: I can squash and/or rebase the commits here if people want? |
squashing is fine, doesn't matter. As far as publishing/credentials I think you could use the existing publish/ivy support we have, just with some "cleverness". If you need details, let's chat about that. I just restarted the build to see if we can get past the timeout issue. This LGTM as it is. |
Should we merge this? |
Yep! Tests now pass :) |
WIP: Provide task to stage output in a format sufficient to build Docker images
Feels good :) |
@garycoady this is really useful for many of us! :) great contribution |
@garycoady I wonder if it makes sense to allow for a hook-in in |
@ahjohannessen It probably would, but I'm going to concentrate on publish support first. It seems like an sbt.RawRepository enclosing an sbt.ResolverAdapter (implementing the appropriate Docker calls) should allow some kind of meaningful behaviour for publish and publishLocal. |
For those interested, I have this sample which uses sbt-native-packager with sbt-docker to build docker containers from sbt.
Sbt-docker is a good plugin, albeit young. I agree Docker is not an archetype- it's a package, and I think "pushing" to a registry should be handled as a separate task, a-la sbt-release or something similar. On the plus side, I like how sbt-docker asks you to build a dockerfile. This allows docker-specific customizations to occur independently of other build types, like exposing ports, setting environment variables, and running commands. |
Thanks for sharing. The sbt-docker plugin looks quite interesting. The |
I like the idea that docker is configured similarly to other targets; so the start script is the same in all cases; if I want to customize that start script, bashScriptExtraDefines will work similarly for all cases (the behaviour is consistent between RPM/Debian/Docker). So where you have a start script with: I might suggest
There is an advantage in this, in that the setup works across all packaged types. So while you are looking at how to make things different across build types, I was more considering how to keep them the same :-) But I agree that the Dockerfile API could perhaps be improved here. I had a more complex API initially, but it was unclear how to support the Dockerfile without adding complexity for complexity's sake. In the end, I went with a minimal wrapper that supported the EXEC and shell formats for execution. |
You're right, keeping things consistent should be the main goal. I'm not that familiar with docker, but would it be possible to build a debian/rpm package and package it within the docker file and install it with a command like |
For publishing, I have some code that creates an Ivy resolver, but I have to spend a bit more time on it to see how to generate an appropriate artifact URL. Something like this for publish:
I gave up on doing it without the binary files and server; not only do you need a HTTP client, but to support all protocols, you also need Unix sockets, so it adds a nasty set of dependencies. Perhaps working without local build tools/server could be added by an external plugin... For authentication; the docker client doesn't currently seem to support using credentials without adding them to the local docker configuration; I think this violates people's expectations about leaking of credentials from an SBT build, so I would currently assume that the user has already used the client to authenticate against the server they want to publish to (while providing an appropriate error message if this has not happened). |
@muuki88 It's certainly possible, but it then places a dependency on having a Debian or RedHat base image to install against. It would be nice to be able to have a very very minimal install: my current assumptions are:
|
I think this is a good approach. My described option would then only be a matter of configuration (removing the chown commands, setting task dependencies, etc.). Building docker locally is fine, too for the start. In 4 weeks I will start adding the option to build debian packages with JDeb. One of our main goals is to support the native-platform. So for debian build you need dpkg installed. Maybe an additional plugin is a good option as you mentioned, which does the nasty http/socket stuff. |
@garycoady thank you for the bash suggestion- much better approach. |
I've made some progress; with this (play 2.2.3) build.sbt:
Docker now does a publishLocal (to the local server), followed by publish (to the remote repository).
And the result is:
I'll try and clean up the code, do error checking, etc., before opening a pull request for it. |
@ahjohannessen Support for EXPOSE and VOLUME: |
@garycoady 👍 |
We will wait for some feedback on the |
@muuki88 Have you tried it? So far, my users are... me. If you have any concerns about the current functionality, or think there's something extra that would be useful to add before release, let me know. And it's my opinion that a Docker wrapper should just execute the appropriate script, not try and stick runit/daemontools/etc. inside the container. Restarting a failed service can be left to |
Yeah, that's the feeling I got to when reading and experimenting with docker. IMHO the less we do in the beginning the better. No magic is preferable ;) There will be a docker meetup in a few days here in munich and I will talk to the people there hoping for feedback. I hope to give a lightning talk on sbt-native-packager and docker on next meetup in a month or so and share the slides here. @jsuereth mentioned he had some requests, too. So I think there is a potential userbase out there, but we will need to promote this feature when it's packaged in a release. |
"So I think there is a potential userbase out there..." Absolutely. |
@garycoady "So far, my users are... me." Me too! 😄 It works great. "And it's my opinion that a Docker wrapper should just execute the appropriate script, not try and stick runit/daemontools/etc. inside the container. Restarting a failed service can be left to docker -d or geard/systemd, or whatever other service manager people want to use." That is the general consensus in the docker community, as well. |
Just catching up on this issue which someone pointed out to me. I thought you guys should know about sbt-docker. It just generates your |
It was pointed out a few days ago. I think the aim of sbt-docker looks different to what this code does. This does not try to write any possible Docker image; it creates a Docker image which runs the program configured with sbt-native-packager. sbt-docker looks a lot more like an unopinionated tool that can create any kind of image. So if you look at the differences in how the settings/tasks are defined, sbt-docker exports a Dockerfile representation, where this code (currently) keeps that hidden, and instead exports possible features (exported ports, volumes, ...), allows extra files to be added to the image, etc. Perhaps in the area of Dockerfile representation, and how to build/push images, some code could be shared. But I'm fairly happy with the the way the features are represented, in the context of this plugin. I did check that both plugins can be added at the same time, in case some keys conflicted. |
I contacted @marcuslonnberg to take a look at our project as sbt-docker was pointed out a few days ago. He read all of our discussion at is willing to help if we decide to reveal some of the underlying API to create the dockerfile. |
Revealing it could be useful, and the internal representation in sbt-docker is more complete. But I don't think it's a blocker for using Docker here. |
As @garycoady points out the plugins currently have different aims. Perhaps is it not necessary for this plugin to allow full configuration of the Dockerfile. I think that in a lot of cases (when using this plugin) the predefined Dockerfile with configurable ports, volumes etc are sufficient. In those other cases one could use sbt-docker with the output of this plugin in a Dockerfile, as in the example from above https://github.com/mhamrah/akka-docker-cluster-example. Another thing that you mentioned was to communicate with the docker server directly without using a local docker client. I started working on this for sbt-docker a while ago but other things got in the way, but I hope to pick that up soon. |
@marcuslonnberg I'd like to help if I can. I was all excited to write a docker plugin but the got just as excited when I learned that someone already wrote one ( multiple ones 😄 ). I'm still pretty motivated so let me know if I can help out on either side. I'm just getting into docker, once you get into docker. There's no getting out! |
@softprops Great to hear you want to help. Lets discuss that issue here: marcus-drake/sbt-docker#7 |
@marcuslonnberg cool. I may contribute an example for dockerized unfiltered in the /examples dir which I guess doesn't need to be help up by any release schedule but would be nice. |
This is a WIP to generate Docker images for applications which are packaged using sbt-native-packager.
It offers a docker:stage task which creates a directory sufficient to create images with
"docker build .", based on extending the layout from Universal.
It does not offer any deployment options, as that generally seems out of scope for this package.
I was wondering if you had any comments, or interest in merging functionality like this? Otherwise, it could also go into a separate plugin, and then might be able to include functionality to publish to Docker repositories.