Introduction
Frankly speaking, I don't know how that worked on Windows because RUN
is an instruction at build time. When you docker run
, in this case, the CMD
from the base image is executed, which is [R]
as you can see in the code.
Execute at build time
If you want to run your script at build time, stick to the run instruction (make sure file paths work) and it will look something likes this:
$ docker build --progress=plain --no-cache -t tester:latest .
#0 building with "default" instance using docker driver
#1 [internal] load .dockerignore
#1 transferring context:
#1 transferring context: 2B done
#1 DONE 0.2s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 108B done
#2 DONE 0.2s
#3 [internal] load metadata for docker.io/rocker/r-base:latest
#3 DONE 0.5s
#4 [1/3] FROM docker.io/rocker/r-base:latest@sha256:eb220139e120247ff6208e2c2556c5142250c7de02a5ea4c77151cbfdffd186e
#4 CACHED
#5 [internal] load build context
#5 transferring context: 31B done
#5 DONE 0.1s
#6 [2/3] COPY myScript.R .
#6 DONE 0.3s
#7 [3/3] RUN Rscript myScript.R
#7 1.153 [1] "AAS"
#7 DONE 1.4s
#8 exporting to image
#8 exporting layers
#8 exporting layers 0.4s done
#8 writing image sha256:904e0a8893b593c2c73423bb7b9705c63135172fac909789aea735b0c121139d 0.0s done
#8 naming to docker.io/library/tester:latest 0.1s done
#8 DONE 0.5s
Where you can see your script being run in layer 7.
Execute the script at run time
If you want to run your script at runtime, there are basically three different options: use CMD
, use ENTRYPOINT
or add the command to the docker run
instruction. To understand the differences, theres is a good Answer on stackoverflow.
CMD
To do this you need to adjust your Dockerfile like so:
FROM rocker/r-base:latest
COPY myScript.R .
CMD Rscript myScript.R
You can see that the script is not executed at build time anymore:
$ docker build --progress=plain --no-cache -t tester:latest .
#0 building with "default" instance using docker driver
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.2s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 108B done
#2 DONE 0.2s
#3 [internal] load metadata for docker.io/rocker/r-base:latest
#3 DONE 0.9s
#4 [1/2] FROM docker.io/rocker/r-base:latest@sha256:eb220139e120247ff6208e2c2556c5142250c7de02a5ea4c77151cbfdffd186e
#4 CACHED
#5 [internal] load build context
#5 transferring context: 31B done
#5 DONE 0.1s
#6 [2/2] COPY myScript.R .
#6 DONE 0.4s
#7 exporting to image
#7 exporting layers
#7 exporting layers 0.1s done
#7 writing image sha256:1a5f360b2406fd7617aa56b4a4ac91261672cb0fe5760b1c2dc87776556cd334 0.0s done
#7 naming to docker.io/library/tester:latest 0.0s done
#7 DONE 0.2s
So now you can run your image and it will execute the script with the command you specified:
$ docker run --rm tester
[1] "AAS"
Execute with ENTRYPOINT
Similar to the above you can use the ENTRYPOINT
instruction in your image.
Your Dockerfile then looks like this:
FROM rocker/r-base:latest
COPY myScript.R .
ENTRYPOINT Rscript myScript.R
And the output from the build also without executing the script:
$ docker build --progress=plain --no-cache -t tester:latest .
#0 building with "default" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 115B done
#1 DONE 0.2s
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.3s
#3 [internal] load metadata for docker.io/rocker/r-base:latest
#3 DONE 0.6s
#4 [1/2] FROM docker.io/rocker/r-base:latest@sha256:eb220139e120247ff6208e2c2556c5142250c7de02a5ea4c77151cbfdffd186e
#4 CACHED
#5 [internal] load build context
#5 transferring context: 31B done
#5 DONE 0.1s
#6 [2/2] COPY myScript.R .
#6 DONE 0.4s
#7 exporting to image
#7 exporting layers
#7 exporting layers 0.1s done
#7 writing image sha256:00a6237bc2ce599c55175db0a1cb3753cf32be092499f22959b2b91cbf05554b 0.0s done
#7 naming to docker.io/library/tester:latest 0.0s done
#7 DONE 0.2s
Then at runtime again, you will receive the expected output:
$ docker run --rm tester
[1] "AAS"
Execute via docker run
Last but not least you can shrink your image a little more to this:
FROM rocker/r-base:latest
COPY myScript.R .
This makes your build process even shorter:
$ docker build --progress=plain --no-cache -t tester:latest .
#0 building with "default" instance using docker driver
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.2s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 83B done
#2 DONE 0.2s
#3 [internal] load metadata for docker.io/rocker/r-base:latest
#3 DONE 0.5s
#4 [1/2] FROM docker.io/rocker/r-base:latest@sha256:eb220139e120247ff6208e2c2556c5142250c7de02a5ea4c77151cbfdffd186e
#4 CACHED
#5 [internal] load build context
#5 transferring context: 31B done
#5 DONE 0.1s
#6 [2/2] COPY myScript.R .
#6 DONE 0.3s
#7 exporting to image
#7 exporting layers
#7 exporting layers 0.2s done
#7 writing image sha256:cb724210554cce6c9ef0fc93e4bdef5b39c1782527ba21c28f5ec13e5850a637 0.0s done
#7 naming to docker.io/library/tester:latest 0.0s done
#7 DONE 0.2s
Now when you run the container, pass the arguments:
$ docker run --rm tester Rscript myScript.R
[1] "AAS"