1

Let's I have a Dockerfile

FROM python:3
ADD script.py /
CMD [ "python", "script.py" ]

script.py endlessly prints some logs into output.

I would like to run a container built from this Dockerfile that will prin logs into output, and remove script.py in this container AUTOMATICALLY.

For example I can change a Dockerfile or I can change the options of 'docker run' command

I tried something like:

docker run -it my_image /bin/bash -c "python /script.py; rm /script.py"

But I was not succeed. Also I tried to move two instructions into CMD, but it was not succeed as well

GolovDanil
  • 133
  • 2
  • 11
  • 1
    What is the goal in removing the script.py? Are you trying to ship an image without the source, conserve disk/network, reduce clutter, or something else? – BMitch Apr 27 '20 at 13:27
  • @BMitch, let's say, want to ship an image without source and reduce clutter. I can not understand, how to change Dockerfile (maybe use a few RUN commands or something else). Or it worth to add some arguments for "docker run" command – GolovDanil Apr 27 '20 at 14:24
  • You can compile the python script and ship the `script.pyc` instead of the `script.py`. There's not really a lot of benefit to doing that, but it's possible. – Joachim Sauer Apr 27 '20 at 14:47
  • @JoachimSauer, ok, I see. Let's say this is some kind of theoretical task. What should I do then? – GolovDanil Apr 27 '20 at 14:52
  • @GolovDanil: theoretical questions like that are less likely to get answers, because understanding the motivation is likely to help guide the best approach to solving it. For example to avoid [XY problems](https://xyproblem.info). – Joachim Sauer Apr 27 '20 at 14:54
  • @JoachimSauer, I have only one (Y) problem) I just want to remove the source code that is executed in container. If there any ways to do it in Dockerfile or in arguments of "docker run"? – GolovDanil Apr 27 '20 at 23:17
  • @GolovDanil: I think my answer already does that, so I don't understand why you still ask this. If there's something about my answer that doesn't meet your requirements, then please tell us what it is. – Joachim Sauer Apr 28 '20 at 08:33

3 Answers3

1

This is the purpose behind multi-stage builds. You can build your app, or in your case, your output file, in one stage. Then copy the resulting artifact to a later stage with a minimal base image. E.g.

FROM python:3 as build
ADD script.py /
RUN [ "python", "script.py" ]

FROM minimal_base_image as release
COPY --from=build /script.out /

Note this is not seen in interpreted languages like python very often since the purpose of shipping an image is usually to ship the application, not the application output, and you need the python runtime to execute a python script.

BMitch
  • 231,797
  • 42
  • 475
  • 450
1

If I understand correctly you want to provide a Docker image without the source of a python script, but that's still able to execute that Python script.

You can do that with 2 relevant features:

  • Python can compile .py files into .pyc files (which are basically just pre-parsed python files, they are not native code).
  • Docker can use multiple images during the build process to allow images that don't contain the whole "history" of the build.

Assuming a Python script called hello.py you can do something like this Dockerfile:

FROM python:3 as build
ADD hello.py /
RUN [ "python", "-m", "compileall", "-l", "-b", "."]

FROM python:3 as release
COPY --from=build /hello.pyc /
CMD [ "python", "hello.pyc" ]
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • good solution. Thanks I tried something like this with a Dockerfile in my description: docker run -it _myimage /bin/bash -c "python /script.py; rm /.py" But I was not suceed – GolovDanil Apr 27 '20 at 15:05
0

You could add a line at the end of the script to delete itself.

rm -- "$0"

Reference

Brand
  • 347
  • 2
  • 11