This has erupted from quite a turbulent meeting between two senior developers, a lead developer and an engineering lead, and after 90mins reached no resolution.
We create Spring Boot Java services which are then dockerised before being deployed to an environment.
As part of our automated build our services are compiled via Maven, resulting in a jar, which then gets pushed to the package registry within gitlab. We then containerise this jar (we don't obtain via the package registry, it just receive it via previous stages in the pipeline) using Docker, which we then push to the container repository.
This means for our service we have the Docker container available, as well as the jar. Note, we don't dockerise anything else, and configuration is held within these jars.
Points raised were following.
- Storing both the jar and the container takes up space. This was the point everyone agreed on. It does. However we don't have limits on space we can take up within our organisation and can easily set up expiries only keeping certain jars, e.g. latest within the package registry.
- We have access to the Docker container. Why do we need the jar as well. This was a VERY contentious point. With arguments being made if an issue arised and you needed access to the jar, maybe to inspect it's contents such as configuration, it's much easier to download the jar, rather than obtain it via the Docker container. Counter point to that was you should be able to rebuild the application at a certain point, this is why tagging exists. Counter counter point. Builds take time. More importantly what you build locally you can't guarantee will be the same as what has been built by CI. Different Java versions and implementations to begin with (Azul vs Coretto, 17.0.1 vs 17.0.2) not to mention architecture (we're using a mix of Intel and M1 Macs which alone has caused issues) doesn't guarantee it will be built the same. There was further disagreement in that Java doesn't work this way, ending in 'yes it does' vs 'no it doesn't'. Locally it's worth noting we don't rebuild the application against a version number, we just use 'local' (
mvn version
is used prior to building on master to properly set the version within our apps). - It's not a package. We deploy Java libraries and DTOs to our package registry mainly to make them available to other projects via the package registry. This is the way we use it for the main. Chances are extremely low (unless we make something that requires the jar, such as a new testing thing) that we will need to obtain the service like we typically do with DTOs and other libraries.
- Outside of our team. We can't see anyone else is doing this. This sets some organisation precendent. However engineering practices tend to get set on a team by team basis, such as tools/languages/coding/dev standards. And no other teams have a deployment pipeline quite like ours. But there doesn't seem to be a defined rule on this.
- Doing this is 'Bad Practice'. There appears to be nothing online either way about this being good or bad practice. Hence the question is being asked on here.
Ultimately in theory you might want to have the jar available, in practice, you may never need to. But:
It's better to have it and not need it. Then need it and not have it.
So ultimately the question is this. Is storing both our Jar and container good, bad, or actually there's no engineering precedent for this. It's down to your organisation. Are there big arguments either way which have been missed. I'm however scared of this being a discussion, which I presume are off topic here, hence why I think this is an option.
Full disclaimer. I am in the camp of why are we spending so long arguing about this. Does it really matter. There are reasons we may want to access the jar rather than recompiling it (which may not be the same as that produced on CI), and storage is cheap. I don't think it's practice either way. I have in fact had to download a jar to check a version number before. This version number can be obtained via the running container, however to run the container it required a bunch of other containers, and was quicker and easier to just check the file within the jar.