<p>To copy into the image or to mount volumes--my advice:</p>
<ul>
<li>if the files will change infrequently, then copy them into the image, with the understanding that if they need to be modified, you will need to rebuild the image.</li>
<li>if you need to frequently change the files, or store some kind of state about the files (and re-use them with future container instances of the image), then mount them as volumes.</li>
</ul>

CC BY-SA 4.0
2020-12-10T17:00:50.057Z
That's a good point ! My second thought is about immutability. You ship a packaged application in production. So no need to worry about the filesystems and base code deployment.
kero_zen
CC BY-SA 4.0
2020-12-09T21:07:23.760Z
2020-12-09T21:07:23.760Z
mikequentel
<p>Standard practice in non-development environments is to <code>COPY</code> the application code into the image, and to set the standard <code>CMD</code> there too.</p>
<pre class="lang-sh prettyprint-override"><code>...
COPY . .
RUN composer install
# php:fpm-alpine image already provides the correct CMD
</code></pre>
<p>There are a couple of important advantages to doing this:</p>
<ul>
<li>You can just run the Docker image directly on the target system; you don't have to copy the Docker image, and also the application code separately.</li>
<li><code>RUN composer install</code> happens only once during the build sequence.  <code>command: composer install ...</code> runs on every restart, which is slower, uses network bandwidth, and can fail.</li>
<li>If you give a unique tag to each image, you can easily roll back to an earlier image by changing the tag back.  It's hard to do this with a volume mount.</li>
<li>You'll <code>docker run</code> an identical image in all environments; you don't need to worry that the host-directory copy of the application is slightly different on that one system.</li>
</ul>
<p>There's no specific rule that a Docker image needs to be very small; the only practical issue I've encountered is that multi-gigabyte images don't transfer across the network well.  Indeed, I'd recommend the opposite choice around <code>COPY</code> vs. volumes that you've suggested: <code>COPY</code> the application code in, and use volumes for config files and other things that aren't &quot;your code&quot;, and that need to be directly accessed from the host.  (You do want to rebuild your application when the application changes; you don't want to rebuild your application when the database URL changes.)</p>

CC BY-SA 4.0
2020-12-21T11:16:27.297Z
2020-12-21T11:16:27.297Z
David Maze
<p>I want to dockerize my php application and deploy it in production. Here is my application structure :</p>
<pre><code>api
|
+-- src
+-- config
+-- vendor
+-- tests
+-- public
</code></pre>
<p>I need to embed <code>api/*</code> in my container, and I'm confused about the best approach.
Here is mine :</p>
<ol>
<li><p>A light multi-stage docker image (around 85 mb but can be more optimized)</p>
<pre><code>FROM php:7.4-fpm-alpine AS base

WORKDIR /var/www/html
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN apk update &amp;&amp; \
  docker-php-ext-install mysqli tokenizer pdo_mysql &amp;&amp; \
  curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

FROM base AS dev

COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug-dev.ini
RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS &amp;&amp; \
  pecl install xdebug-2.9.1 &amp;&amp; \
  docker-php-ext-enable xdebug &amp;&amp; \
  touch /tmp/xdebug.log &amp;&amp; \
  chmod -R 666 /tmp/xdebug.log &amp;&amp; \
  apk del -f .phpize-deps
</code></pre>
</li>
<li><p>A mounted volume (docker-compose.yml)</p>
<pre><code>api:
  volumes:
    - ./api:/var/www/html
  command: composer install &amp;&amp; php-fpm;
</code></pre>
</li>
</ol>
<p>I saw a lot of docker images using <code>COPY ..</code> instruction in <code>Dockerfile</code> instead of volumes. I believe <code>COPY</code> is great to copy small config files (or a small build for compiled languages), but it's not optimized to keep the images small (basic rule with docker).</p>
<p>Am I missing something?
For example, is it bad practice to handle volumes from outside the dev environment ?</p>

<docker><docker-compose>
Use a volume or copy my artefacts into docker image
kero_zen
# Use a volume or copy my artefacts into docker image

(Asked by: username_0 on 2020-12-08)

I want to dockerize my php application and deploy it in production. Here is my application structure :
api
|
+-- src
+-- config
+-- vendor
+-- tests
+-- public

I need to embed api/* in my container, and I'm confused about the best approach.
Here is mine :

A light multi-stage docker image (around 85 mb but can be more optimized)
FROM php:7.4-fpm-alpine AS base

WORKDIR /var/www/html
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN apk update && \
  docker-php-ext-install mysqli tokenizer pdo_mysql && \
  curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

FROM base AS dev

COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug-dev.ini
RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS && \
  pecl install xdebug-2.9.1 && \
  docker-php-ext-enable xdebug && \
  touch /tmp/xdebug.log && \
  chmod -R 666 /tmp/xdebug.log && \
  apk del -f .phpize-deps


A mounted volume (docker-compose.yml)
api:
  volumes:
    - ./api:/var/www/html
  command: composer install && php-fpm;



I saw a lot of docker images using COPY .. instruction in Dockerfile instead of volumes. I believe COPY is great to copy small config files (or a small build for compiled languages), but it's not optimized to keep the images small (basic rule with docker).
Am I missing something?
For example, is it bad practice to handle volumes from outside the dev environment ?

**Tags:** docker, docker-compose


---

## 2 answers

### Answer by username_2 on 2020-12-21. Score: 3 | Accepted answer

Standard practice in non-development environments is to COPY the application code into the image, and to set the standard CMD there too.
...
COPY . .
RUN composer install
# php:fpm-alpine image already provides the correct CMD

There are a couple of important advantages to doing this:

You can just run the Docker image directly on the target system; you don't have to copy the Docker image, and also the application code separately.
RUN composer install happens only once during the build sequence.  command: composer install ... runs on every restart, which is slower, uses network bandwidth, and can fail.
If you give a unique tag to each image, you can easily roll back to an earlier image by changing the tag back.  It's hard to do this with a volume mount.
You'll docker run an identical image in all environments; you don't need to worry that the host-directory copy of the application is slightly different on that one system.

There's no specific rule that a Docker image needs to be very small; the only practical issue I've encountered is that multi-gigabyte images don't transfer across the network well.  Indeed, I'd recommend the opposite choice around COPY vs. volumes that you've suggested: COPY the application code in, and use volumes for config files and other things that aren't "your code", and that need to be directly accessed from the host.  (You do want to rebuild your application when the application changes; you don't want to rebuild your application when the database URL changes.)


---

### Answer by username_1 on 2020-12-09. Score: 4

To copy into the image or to mount volumes--my advice:

* if the files will change infrequently, then copy them into the image, with the understanding that if they need to be modified, you will need to rebuild the image.
* if you need to frequently change the files, or store some kind of state about the files (and re-use them with future container instances of the image), then mount them as volumes.

> **Comments:**
> **username_0**: That's a good point ! My second thought is about immutability. You ship a packaged application in production. So no need to worry about the filesystems and base code deployment.  

---

