o2r-project / containerit

Package an R workspace and all dependencies as a Docker container
https://o2r.info/containerit/
GNU General Public License v3.0
289 stars 29 forks source link

Custom COPY additions not exported #171

Open MarkEdmondson1234 opened 4 years ago

MarkEdmondson1234 commented 4 years ago

Hello :)

I was trying to replicate the exact Dockerfile from a folder, but had to override the COPY line as there was no option to add a custom one like Cmd() - I had to use the below:

 docker <- suppressWarnings(dockerfile(deploy_folder,
     image = "trestletech/plumber",
     offline = FALSE,
     cmd = Cmd("api.R"),
     maintainer = NULL,
     container_workdir = NULL,
     entrypoint = Entrypoint("R",
                   params = list("-e",
                                 "pr <- plumber::plumb(commandArgs()[4]); pr$run(host='0.0.0.0', port=as.numeric(Sys.getenv('PORT')))")),
     filter_baseimage_pkgs = TRUE,
     ...))

  addInstruction(docker) <-containerit:::Copy(".","./")

print(docker)
#FROM trestletech/plumber
#COPY ["./", "./"]
#ENTRYPOINT ["R", "-e", "pr <- plumber::plumb(commandArgs()[4]); pr$run(host='0.0.0.0', port=as.numeric(Sys.getenv('PORT')))"]
#CMD ["api.R"]

Could there be a Copy() function exported to achieve similar to above?

nuest commented 4 years ago

There is a Copy() function, but it is not exported: https://github.com/o2r-project/containerit/blob/master/R/Class-Copy.R

After exporting that, I'm happy to add a paramter to main method: dockerfile(.., copy = list(Copy("from", "to"), Copy("from2", "to2")). The tricky thing is where to put the custom COPY statements. The later they come in the file, the less impact they have on build caching, so I'd say put them right before the ENTRYPOINT. Do you agree?

I'll take a stab at this, possibly next week and also fix #172 (Don't you run into that error? That is why my example below does not filter base image packages..). Until then, you can append further instructions with addInstruction(..):

> docker <- suppressWarnings(dockerfile(expression("library(plumber)"),
     image = "trestletech/plumber",
     offline = FALSE,
     cmd = Cmd("api.R"),
     maintainer = NULL,
     container_workdir = NULL,
     entrypoint = Entrypoint("R",
                   params = list("-e",
                                 "pr <- plumber::plumb()")),
     filter_baseimage_pkgs = FALSE))

> addInstruction(docker) <- containerit:::Copy("host", "container")
> print(docker)
FROM trestletech/plumber
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
  && apt-get install -y git-core \
    libcurl4-openssl-dev \
    libssl-dev \
    make
RUN ["install2.r", "assertthat", "backports", "crayon", "curl", "desc", "digest", "fastmap", "formatR", "fs", "futile.logger", "futile.options", "htmltools", "httpuv", "jsonlite", "lambda.r", "later", "magrittr", "mime", "miniUI", "pillar", "pkgconfig", "promises", "R6", "Rcpp", "remotes", "rlang", "rprojroot", "semver", "shiny", "shinyFiles", "stevedore", "stringi", "stringr", "tibble", "xtable"]
RUN ["installGithub.r", "goldingn/versions@de231cb523aa9134a1bd4e947c8204a7a08f3daa"]
COPY ["host", "container"]
ENTRYPOINT ["R", "-e", "pr <- plumber::plumb()"]
CMD ["api.R"]
MarkEdmondson1234 commented 4 years ago

The tricky thing is where to put the custom COPY statements. The later they come in the file, the less impact they have on build caching, so I'd say put them right before the ENTRYPOINT.

Yes that is where I tend to put them.

I'll take a stab at this, possibly next week and also fix #172 (Don't you run into that error? That is why my example below does not filter base image packages..).

Ah work in progress so not come across it yet, not tried it beyond test scripts without heavy library dependencies yet.

MarkEdmondson1234 commented 4 years ago

Its for a Cloud Build package which incidentally is my preferred alternative to docker_build now - https://github.com/MarkEdmondson1234/cloudRunner