<blockquote>
  <p>I understand this can be optimized to a level with multi-staged build.</p>
</blockquote>

<p>This is an understatement - you do not "optimize" that, but that's just the way you do it.</p>

<p>To answer your question: yes, by all means run the build inside a docker container. How else would you be sure that at build time every library or dependency is the same? There is no reason whatsoever not to do it.</p>

<p>Of course you need to pay a bit of attention when writing the Dockerfile. Ideally, whatever you change in your source code day-to-day, the only thing that happens when you re-run your build is the very last step of actually compiling your code and doing whatever it is you do with it afterwards (creating your deliverable archive...).</p>

<p>You <em>need</em> to use multi-staged builds afterwards to get rid of all the intermediate steps, and especially all the compile-time-only components (and it's pretty easy as well).</p>

<p>Note that there's usually some parts of your setup which are used by both the compile-time and run-time (unless you are just creating a .war file and sending that off to a webserver). I.e., if you have a ruby-on-rails application, the "ruby-on-rails" part could well be shared between compile-time and run-time. You want to make sure to put everything that is shared in this way <em>very early</em> in the process, and have a clean cut-off point that you can use as a <code>FROM</code> later on, copying the compiled files in as needed.</p>

CC BY-SA 4.0
2018-12-21T23:43:45.350Z
2018-12-21T23:43:45.350Z
AnoE
<p>There are significant performance gains to be had in some projects by not building inside the docker containers. If you are building multiple images you can benefit from shared package caches and shared build artefacts which is not possible when you are building every app in isolation inside it's own container.</p>
<p>In a previous project I worked on, we were building the same shared libraries 5 times in 5 different images. Building and running for example tests outside docker really helped speed up our CI/CD.</p>
<p>This is especially true when you are using cloud pipelines like Github actions where downloading and re-hydrating a full docker cache can take as much time as building it from scratch.</p>

CC BY-SA 4.0
2023-05-16T14:26:59.433Z
2023-05-16T14:31:50.170Z
2023-05-16T14:31:50.170Z
Dabaus
<p>The answer depends on your deployment. It sounds like you are wanting to create a generic "environment image" and then do something like mount whatever you want to run with a volume. In this case a multi stage build like doesn't much for you but it may still benefit you.</p>

<p>If you are going to containerize each application then a multi staged build makes the most sense I think. It does keep your final images "clean" since the build was done in a separate container.</p>

<p>The "trade-off" you mentioned should not be an issue. You should work to get your infrastructure to a point where deploying a new image isn't such a big deal therefore negating this problem.</p>

CC BY-SA 4.0
2018-11-16T13:34:12.550Z
2018-11-16T13:34:12.550Z
Pete
<blockquote>
  <p>But the trade-off is, we have to build the complete docker for the even a small code change that we build.</p>
</blockquote>

<p>No, not usually.  Generally in your Dockerfile the application build process will be after all of the system configuration (installing libraries and such), and so Docker will reuse cached layers for those.</p>

<p>If your concern is that you'll have to rebuild the entire application each time, rather than use some sort of build object caching in your build system, then yes, that does happen.  In development you can often mitigate this by using live-reload auto-rebuild systems that watch the filesystem for changes, combined with a Docker directory mount of the code from the local development machine.  This way when a developer saves a file, the changes are propagated to the running container, where the autobuild notices and rebuilds and restarts the application.</p>

<p>The other thing you should be careful of are bloated images.  If you install a bunch of development tools in the container, then even if you uninstall them later in the Dockerfile, the resultant image will include layers with them, which can increase the overall size of the image.</p>

CC BY-SA 4.0
2018-11-21T22:32:36.770Z
2018-11-21T22:32:36.770Z
Xiong Chiamiov
<p>I am dockerizing our applications to have the environments recreatable. As a process of dockerizing, we will be required to do the below steps:</p>

<ul>
<li>Build the application.</li>
<li>Prepare the environment as the container.</li>
<li>Deploy the application to the container.</li>
</ul>

<p>Is it fine to have the application build, inside the docker, as part of docker building? In that way we need not install the build dependencies in local.</p>

<p>But the trade-off is, we have to build the complete docker for the even a small code change that we build. I understand this can be optimized to a level with <a href="https://docs.docker.com/develop/develop-images/multistage-build/#use-an-external-image-as-a-stage" rel="noreferrer">multi-staged</a> build. </p>

CC BY-SA 4.0
2024-01-10T11:55:10.507Z
see https://stackoverflow.com/questions/33196474/is-it-better-to-build-and-test-in-a-container
Johan
<docker>
Should we build our application inside a docker container, or copy it in?
Kannan Ramamoorthy
# Should we build our application inside a docker container, or copy it in?

(Asked by: username_0 on 2018-11-16)

I am dockerizing our applications to have the environments recreatable. As a process of dockerizing, we will be required to do the below steps:

* Build the application.
* Prepare the environment as the container.
* Deploy the application to the container.

Is it fine to have the application build, inside the docker, as part of docker building? In that way we need not install the build dependencies in local.

But the trade-off is, we have to build the complete docker for the even a small code change that we build. I understand this can be optimized to a level with [multi-staged](https://docs.docker.com/develop/develop-images/multistage-build/#use-an-external-image-as-a-stage) build.

**Tags:** docker

> **Comments:**
> **username_1**: see https://stackoverflow.com/questions/33196474/is-it-better-to-build-and-test-in-a-container  

---

## 4 answers

### Answer by username_2 on 2018-12-21. Score: 4

> I understand this can be optimized to a level with multi-staged build.

This is an understatement - you do not "optimize" that, but that's just the way you do it.

To answer your question: yes, by all means run the build inside a docker container. How else would you be sure that at build time every library or dependency is the same? There is no reason whatsoever not to do it.

Of course you need to pay a bit of attention when writing the Dockerfile. Ideally, whatever you change in your source code day-to-day, the only thing that happens when you re-run your build is the very last step of actually compiling your code and doing whatever it is you do with it afterwards (creating your deliverable archive...).

You *need* to use multi-staged builds afterwards to get rid of all the intermediate steps, and especially all the compile-time-only components (and it's pretty easy as well).

Note that there's usually some parts of your setup which are used by both the compile-time and run-time (unless you are just creating a .war file and sending that off to a webserver). I.e., if you have a ruby-on-rails application, the "ruby-on-rails" part could well be shared between compile-time and run-time. You want to make sure to put everything that is shared in this way *very early* in the process, and have a clean cut-off point that you can use as a `FROM` later on, copying the compiled files in as needed.


---

### Answer by username_3 on 2023-05-16. Score: 2

There are significant performance gains to be had in some projects by not building inside the docker containers. If you are building multiple images you can benefit from shared package caches and shared build artefacts which is not possible when you are building every app in isolation inside it's own container.

In a previous project I worked on, we were building the same shared libraries 5 times in 5 different images. Building and running for example tests outside docker really helped speed up our CI/CD.

This is especially true when you are using cloud pipelines like Github actions where downloading and re-hydrating a full docker cache can take as much time as building it from scratch.


---

### Answer by username_4 on 2018-11-16. Score: 1

The answer depends on your deployment. It sounds like you are wanting to create a generic "environment image" and then do something like mount whatever you want to run with a volume. In this case a multi stage build like doesn't much for you but it may still benefit you.

If you are going to containerize each application then a multi staged build makes the most sense I think. It does keep your final images "clean" since the build was done in a separate container.

The "trade-off" you mentioned should not be an issue. You should work to get your infrastructure to a point where deploying a new image isn't such a big deal therefore negating this problem.


---

### Answer by username_5 on 2018-11-21. Score: 1

> But the trade-off is, we have to build the complete docker for the even a small code change that we build.

No, not usually. Generally in your Dockerfile the application build process will be after all of the system configuration (installing libraries and such), and so Docker will reuse cached layers for those.

If your concern is that you'll have to rebuild the entire application each time, rather than use some sort of build object caching in your build system, then yes, that does happen. In development you can often mitigate this by using live-reload auto-rebuild systems that watch the filesystem for changes, combined with a Docker directory mount of the code from the local development machine. This way when a developer saves a file, the changes are propagated to the running container, where the autobuild notices and rebuilds and restarts the application.

The other thing you should be careful of are bloated images. If you install a bunch of development tools in the container, then even if you uninstall them later in the Dockerfile, the resultant image will include layers with them, which can increase the overall size of the image.


---

