4

I've a production Ubuntu that contains a huge number of software and dependencies, I want to 'clone' that VPS into a Docker image to be able to replicate the same environment and distribute them in different servers.

Is that possible without any hack? If yes, what are the big lines to follow?

1
  • 1
    You shouldn't because containers are not lightweight VM and are not supposed to run multiples softwares within only one. – Tensibai May 26 '18 at 16:11
2

Is that possible without any hack?

Yes, it is possible. While Docker is often used for microservice-oriented images (i.e., one single service per image), nothing keeps you from converting a monolithic old application to Docker by building a large image, and running arbitrarily many processes inside.

While it is true that a Docker image is not a standalone VM, it still contains everything an equivalent VM would contain - excluding the kernel. I.e., all OS libraries (libc, everything else...) are in there anyways.

If yes, what are the big lines to follow?

A Dockerfile is just a funky version of a plain old shell script which you could ordinarily use to provision your software with all its dependencies. That is, you chain a lot of commands, which are executed during the build process, and whatever ends up in the file system at the end gets packed up into an image.

So the general route is:

  • Pick a base image. Depending on your needs and security requirements, you can pick your favourite distribution from Dockerhub. At first, you can pick any Debian, Ubuntu or whatever distribution you prefer and are used to. See below for further considerations.
  • Those base images usually are pretty small. Hence, your next step is to use RUN apt install... (or whatever package manager your base image uses) to add any standard packages you like.
  • Finally, you have to install your own software somehow. If you follow the usual approach, you would prepare any binaries and other files you need in the host-side directory alongside your Dockerfile, and then ADD them in.
  • The last step is to (optionally) create a ENTRYPOINT, i.e., a command that is run when the image is started up, as well as EXPOSE routing information, run as non-root USER or set ENVironment variables.

These are the big lines. If you just do it naively, you will end up with a huge image (gigabytes), and create a new huge image everytime you rebuild, wich can pose serious problems. The next steps are thus:

  • Switch the base image to a smaller one. alpine is good.
  • For each RUNcall, make sure there are no temporary/unneccessary files left afterwards. For example, apt install leaves you with a lot of cache junk in /var (same for the other package managers). Due to the way Docker works with its onion-style layered file systems, you have to get rid of the junk within the same RUN command, you cannot clean up in a second RUN. If you google, you will find plenty of examples.
  • You probably pulled in too many packages with your package manager, fix that.
  • For installing your own software, the same applies. Avoid having temporary .tar archives lying around which you don't need anymore.

These steps should significantly reduce your image size already. Depending on what you are actually doing, 500'ish MB is a good target to avoid over-optimizing at this stage.

The final step is to optimize everything:

  • Make sure that you do not have to rebuild every single intermediate image each time, by ordering the lines in the Dockerfile appropriately. You can get away with large images if the "largeness" happens in the first few image layers, if those change seldom, and can be re-used by many final images.
  • For an intermediate image to be re-used, it must be bitwise identical to another one. So be sure to fix all variable information (like version numbers etc.) as best you can.
  • Obviously, if you get the hang of all of this, and get your complex, many-part application running inside a single Docker image, then it's time to split it apart across multiple images (rinse, repeat). Anything that communicates by TCP/IP should be an easy choice to do so.
0
1

I think @AnoE answer is correct as far as answering the question OP asked and providing some good tips.

I also feel like the comment @Tensibai left is really important as well.

You shouldn't because containers are not lightweight VM and are not supposed to run multiples softwares within only one. -Tensibai

Though that isn't always true either ^.

My advice to OP would be to take this time and break apart the different apps and dependencies into separate docker containers. This would be the "proper" way to do it. This would give you something much more flexible in the long run.

1
  • There's better alternatives than dockefiles for those uses cases, I think about habitat.sh but there's other packaging systems also, I take the OP question as: can I do something like Physical 2 Virtual with virtual being docker, and the answer to this is a clear no, rebuild is necessary. – Tensibai May 29 '18 at 18:13
-2

The whole reason for Docker is to not need an entire operating system underneath. If you want an entire operating system, just take a VM and clone it and distribute that.

1
  • You missed the point about docker and about the question I think. – Tensibai May 29 '18 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.