0

Let's consider such directory. (Note: A directory ends with \)

root\
|
-- some stuff
|
-- application\
|  |
|  -- app_stuff
|  |
|  -- out\
|  |
|  -- main.cpp
|
-- some stuff

I'm trying to build this app via docker. The Dockerfile looks like:

FROM emscripten/emsdk:latest 

RUN apt-get -q update 

RUN mkdir /app

WORKDIR /app

COPY . /app

RUN em++ application/main.cpp -o application/out/app.html

RUN pip3 install aiohttp

RUN pip3 install aiohttp_jinja2

RUN pip3 install jinja2

RUN ls application/out

The docker-compose looks like:

version: '3.8'

services:
    application:
        build: .
        volumes: 
            - ./application/out:/app/application/out
        command: python3 application/entry.py
        ports: 
            - "8080:8080"

As you may notice in Dockerfile (RUN em++ application/main.cpp -o application/out/app.html), whereas docker is processing it generates new files to the out-directory. However, once it's done I can't find those files.

Note: These files appear in application\out in container.

...
Step 10/10 : RUN ls application/out
 ---> Running in 603f6b99f4b0
app.html
app.js
app.wasm
...

Where have I admitted a mistake?

JuiceFV
  • 171
  • 11

2 Answers2

3

The Dockerfile gives instructions on how to build a docker image, and not on what happens in the live container.

If you mount a volume, either via docker-compose or via a docker run command, either way, the volume will only be mounted once the container is created.

So what happens is

  • first docker creates the image executing the commands in the Dockerfile, and stores the image as an image
  • then docker will create a container using the stored image
  • then docker will mount the volumes you defined in the docker-compose.yml file. (At this point if anything is already present in the target directory, either the mount will fail or the original content of the target directory will be moved to a 'lost-and-found' directory)
  • then the entrypoint or cmd command is run (so here that would be python3 application/entry.py)

So if you need to get the output files out in your host directory, you either need to create those files in the entrypoint script of copy them in the entrypoint script

so you can create a file you call myscript.sh with the following

#!/bin/bash
em++ /app/application/main.cpp -o /app/application/out/app.html
python3 /app/application/entry.py

in your Dockerfile you remove the line RUN em++ application/main.cpp -o application/out/app.html and replace it with

COPY ./myscript.sh /
ENTRYPOINT /myscript.sh

and you remove the line command: python3 application/entry.py from your docker-compose.yml file.

You can use the CMD command rather than ENTRYPOINT if you prefer, that's just a matter of personal preference.

Nathanael
  • 870
  • 5
  • 11
1

A Docker-compose volume can link a directory on the host to a directory inside of a container. You are overwriting the /app/application/out directory inside of the container with a volume to the host's ./application/out, effectively erasing any contents of /app/application/out originating from your built image.

Given the context, I presume your host's ./application/out directory is empty and you are overwriting the container's /app/application/out directory with nothing. You can test this by removing the volumes tag and see if the application is able to find files under /app/application/out afterwards.


Unrelated to your issue, take into consideration that your apt-get update command will cache Debian remote repository lists in your built image; this adds wasted space to your final image. See this post about deleting the cached lists.

concision
  • 6,029
  • 11
  • 29
  • I got the thing, thanks for detailed explanation. Though, may you advise me, is there a way to store generated files to local host to the same dir? – JuiceFV Oct 04 '20 at 13:03
  • @JuiceFV As far as I am aware, I do not think any configuration will populate the host's directory from the initial contents in your container's directory, when specifying a Docker volume. You could have another directory such as `/app/application/out-volume` (which can be mounted by the host) that is populated from the `out` folder on container startup, if `out-volume` is empty. This obviously will duplicate files in the container, though. Alternatively, if this is a one time thing, see this post for copying files from a built image: https://stackoverflow.com/q/25292198 – concision Oct 04 '20 at 13:15