<blockquote>
  <p>Is that possible without any hack? </p>
</blockquote>

<p>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.</p>

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

<blockquote>
  <p>If yes, what are the big lines to follow?</p>
</blockquote>

<p>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.</p>

<p>So the general route is:</p>

<ul>
<li>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.</li>
<li>Those base images usually are pretty small. Hence, your next step is to use <code>RUN apt install...</code> (or whatever package manager your base image uses) to add any standard packages you like.</li>
<li>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 <code>ADD</code> them in.</li>
<li>The last step is to (optionally) create a <code>ENTRYPOINT</code>, i.e., a command that is run when the image is started up, as well as <code>EXPOSE</code> routing information, run as non-root <code>USER</code> or set <code>ENV</code>ironment variables.</li>
</ul>

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

<ul>
<li>Switch the base image to a smaller one. <code>alpine</code> is good.</li>
<li>For each <code>RUN</code>call, make sure there are no temporary/unneccessary files left afterwards. For example, <code>apt install</code> leaves you with a lot of cache junk in <code>/var</code> (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 <em>within the same <code>RUN</code> command</em>, you cannot clean up in a second <code>RUN</code>. If you google, you will find plenty of examples.</li>
<li>You probably pulled in too many packages with your package manager, fix that.</li>
<li>For installing your own software, the same applies. Avoid having temporary <code>.tar</code> archives lying around which you don't need anymore.</li>
</ul>

<p>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.</p>

<p>The final step is to optimize everything:</p>

<ul>
<li>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.</li>
<li>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.</li>
<li>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.</li>
</ul>

CC BY-SA 4.0
2018-05-29T17:43:43.857Z
2018-05-29T19:30:01.257Z
2018-05-29T19:30:01.257Z
AnoE
<p>I think @AnoE answer is correct as far as answering the question OP asked and providing some good tips. </p>

<p>I also feel like the comment @Tensibai left is really important as well.</p>

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

<p>Though that isn't always true either ^. </p>

<p>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. </p>

CC BY-SA 4.0
2018-05-29T18:13:34.567Z
There's better alternatives than dockefiles for those uses cases, I think about http://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
CC BY-SA 4.0
2018-05-29T18:01:49.070Z
2018-05-29T18:01:49.070Z
Levi
<p>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.</p>

CC BY-SA 4.0
2018-05-29T18:17:02.063Z
You missed the point about docker and about the question I think.
Tensibai
CC BY-SA 4.0
2018-05-29T16:58:55.700Z
2018-05-29T16:58:55.700Z
Rick Carter
<p>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.</p>

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

CC BY-SA 4.0
2018-05-26T16:11:54.043Z
You shouldn't because containers are not lightweight VM and are not supposed to run multiples softwares within only one.
Tensibai
<docker>
How can I convert a production Linux server into a docker Image or container?
Marwen Trabelsi
# How can I convert a production Linux server into a docker Image or container?

(Asked by: username_0 on 2018-05-25)

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?

**Tags:** docker

> **Comments:**
> **username_1**: You shouldn't because containers are not lightweight VM and are not supposed to run multiples softwares within only one.  

---

## 3 answers

### Answer by username_2 on 2018-05-29. Score: 3

> 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 `ENV`ironment 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 `RUN`call, 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.


---

### Answer by username_3 on 2018-05-29. Score: 1

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

I also feel like the comment @username_1 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. -username_1

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.

> **Comments:**
> **username_1**: There's better alternatives than dockefiles for those uses cases, I think about http://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.  

---

### Answer by username_4 on 2018-05-29. Score: -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.

> **Comments:**
> **username_1**: You missed the point about docker and about the question I think.  

---

