17

new to Docker here and I am trying to make it right.

I want to create a docker container to 'deep freeze' an application created with bash scripts and a lot of dependencies, so that I don't have to maintain it as much anymore. I think docker is going to help me with that. Is it a good practice to put update/upgrade statements inside the Dockerfile like 'apt-get upgrade'? Wouldn't that potentially break the application in the future which is what docker should prevent?

MortyAndFam
  • 181
  • 1
  • 1
  • 3

4 Answers4

9

The main reason why you'll want to either use an updated base image (which itself been built from up-to-date packages) or update it yourself (eg, apt-get upgrade) is to get security fixes, as well as other bug fixes.

You don't say much about what software is in there, but "a lot of dependencies" probably means there will be security fixes to track.

The overall idea for using containers is that you build an up-to-date image with the software you need, test it, it then stays frozen throughout its lifetime and later gets discarded as a whole when a new version is released and a new image is deployed.

From a security perspective, this of course implies regular releases.

As for what you will get in terms of updated packages in Debian (if we assume Debian, from your use of apt-get), they have stable (ie, unchanging) releases. Ie, they don't ship new versions of the packaged software (with rare exceptions), but backport fixes to their packaged version.
This may be helpful in your "deep freeze" effort, as the chance of changed behaviour is much lower than with new versions.

Håkan Lindqvist
  • 33,741
  • 5
  • 65
  • 90
  • Thank you for your response! Do you think that docker is a reasonable choice to deep freeze my software? Or should I be looking somewhere else for a solution? – MortyAndFam Aug 01 '18 at 10:45
  • Do you think I should use bare Debian instead of Ubuntu 16? Which linux/unix distro do you think would be the most stable for such an effort? Thanks again. – MortyAndFam Aug 01 '18 at 10:51
  • @MortyAndFam If you are sticking to packages in `main` only, Ubuntu LTS is probably a reasonable choice too (but `universe` is not reliably updated, that may be a no-no). As for Ubuntu, it might make more sense to start at the latest LTS release (18.04 as of now), as that will be maintained for 5 years from this year instead of 5 years from two years ago with 16.04. That bit is entirely about how long runway you have before you need to do a major upgrade to keep getting updates. Generally, it appears the slower moving distros best suit your desires, Debian, Ubuntu LTS, RHEL (/CentOS), etc. – Håkan Lindqvist Aug 01 '18 at 11:06
  • @MortyAndFam As for Docker, it mostly lets your application and its dependencies live in a separate little bubble, unaffected what happens around it. It doesn't magically remove the need for updates, but may make it easier to maintain control. If you truly want to deep freeze your application, one approach to reduce the need for updates is if you can keep it isolated from the rest of the world; however, that may of course make your application, depending on its nature, entirely useless in the process. – Håkan Lindqvist Aug 01 '18 at 11:13
2

You are correct, apt-get upgrade will of course upgrade packages in the future, but what you are trying to do with the Dockerfile is to build the docker container in the correct state. After the docker image is built, it's frozen, and the apt-get upgrade won't run anymore.

If you re-build your image, well, then of course the packages are updated, well, don't use apt-get upgrade!. You only need to run apt-get update to refresh the package list.

So what you need to do is to run apt update when building, then install specific versions of each package you need:

apt-cache madison openssl
    openssl | 1.1.0f-3+deb9u2 | http://deb.debian.org/debian stretch/main amd64 Packages
   openssl | 1.1.0f-3+deb9u2 | http://security.debian.org/debian-security stretch/updates/main amd64 Packages

So, to install openssl 1.1.0f-3+deb9u2 , do apt-get install openssl=1.1.0f-3+deb9u2.

You would need to do this for each and every package that needs a specific version.

Another way could be to not run apt-get update at all, but with Debian, packages are upgraded because of security issues, then are no longer available in the regular distribution sites, so that might break your docker build in the future. Depending on the way your scripts are built and the dependencies needed it might be worth a shot. Since it doesn't cost anything to build images (more than disk space), try both!

DiskJunky
  • 103
  • 4
Fredrik
  • 528
  • 2
  • 10
1

If you want to run apt you will need to update because its repository is empty on Docker initialisation.

As of upgrade, I wouldn't suggest it if you really want to "deep freeze" it. Your best bet is to start with an apt update and then install specific versions of your dependencies so you won't grab an incompatible version at some point in the future.

Other than that - yes, running apt in containers is completely normal when your application has dependencies that don't need to be in their own containers.

Neekoy
  • 269
  • 1
  • 6
  • 14
1

The update, as others mention, is needed because that retrieves the repository details needed to install packages. Docker images typically ship without this cache to conserve disk space. And if they did, it would quickly be out of date and you'd need to run a fresh update.

The upgrade would only be needed if your base image shipped with an older package. Instead of running an upgrade, you should be rebuilding your base image, or pulling a new version of that base image with the newer packages. Not only will this get you updates that have been applied to upstream images, but it will reduce your image size since you don't need both the old and new version of a package (the docker layered filesystem does not fully delete files replaced or deleted in parent images).

For stability, I see two options:

  1. Install specific package versions with the pkg=ver syntax. You may want to do this with specific packages, while letting the remainder install the latest version. If you do this, I'd recommend passing the package version in as a build arg so it can be easily updated.

  2. Install the latest of everything, but always version your image so you can go back to the prior image tag if there are issues.

Often, you will end up doing both, but the biggest risk to #1 is forgetting to update to new releases with security and bug fixes.

BMitch
  • 5,189
  • 1
  • 21
  • 30