1313
1414from traitlets import Dict
1515
16+ # Only use syntax features supported by Docker 17.09
1617TEMPLATE = r"""
1718FROM buildpack-deps:bionic
1819
19- # avoid prompts from apt
20+ # Avoid prompts from apt
2021ENV DEBIAN_FRONTEND=noninteractive
2122
2223# Set up locales properly
100101{% if build_script_files -%}
101102# If scripts required during build are present, copy them
102103{% for src, dst in build_script_files|dictsort %}
103- COPY {{ src }} {{ dst }}
104+ COPY --chown={{ user }}:{{ user }} {{ src }} {{ dst }}
104105{% endfor -%}
105106{% endif -%}
106107
107108{% for sd in build_script_directives -%}
108- {{sd }}
109+ {{ sd }}
109110{% endfor %}
110111
111112# Allow target path repo is cloned to be configurable
137138{% if preassemble_script_files -%}
138139# If scripts required during build are present, copy them
139140{% for src, dst in preassemble_script_files|dictsort %}
140- COPY src/{{ src }} ${REPO_DIR}/{{ dst }}
141+ COPY --chown={{ user }}:{{ user }} src/{{ src }} ${REPO_DIR}/{{ dst }}
141142{% endfor -%}
142143{% endif -%}
143144
144- {% if preassemble_script_directives -%}
145- USER root
146- RUN chown -R ${NB_USER}:${NB_USER} ${REPO_DIR}
147- {% endif -%}
148-
149145{% for sd in preassemble_script_directives -%}
150146{{ sd }}
151147{% endfor %}
152148
153- # Copy and chown stuff. This doubles the size of the repo, because
154- # you can't actually copy as USER, only as root! Thanks, Docker!
155- USER root
156- COPY src/ ${REPO_DIR}
157- RUN chown -R ${NB_USER}:${NB_USER} ${REPO_DIR}
149+ # Copy stuff.
150+ COPY --chown={{ user }}:{{ user }} src/ ${REPO_DIR}
158151
159152# Run assemble scripts! These will actually turn the specification
160153# in the repository into an image.
203196 os .path .dirname (os .path .abspath (__file__ )), "repo2docker-entrypoint"
204197)
205198
199+ # Also used for the group
200+ DEFAULT_NB_UID = 1000
201+
206202
207203class BuildPack :
208204 """
@@ -507,10 +503,12 @@ def binder_path(self, path):
507503 def detect (self ):
508504 return True
509505
510- def render (self ):
506+ def render (self , build_args = None ):
511507 """
512508 Render BuildPack into Dockerfile
513509 """
510+ build_args = build_args or {}
511+
514512 t = jinja2 .Template (TEMPLATE )
515513
516514 build_script_directives = []
@@ -569,6 +567,8 @@ def render(self):
569567 post_build_scripts = self .get_post_build_scripts (),
570568 start_script = self .get_start_script (),
571569 appendix = self .appendix ,
570+ # For docker 17.09 `COPY --chown`, 19.03 would allow using $NBUSER
571+ user = build_args .get ("NB_UID" , DEFAULT_NB_UID ),
572572 )
573573
574574 @staticmethod
@@ -612,7 +612,7 @@ def build(
612612 tarf = io .BytesIO ()
613613 tar = tarfile .open (fileobj = tarf , mode = "w" )
614614 dockerfile_tarinfo = tarfile .TarInfo ("Dockerfile" )
615- dockerfile = self .render ().encode ("utf-8" )
615+ dockerfile = self .render (build_args ).encode ("utf-8" )
616616 dockerfile_tarinfo .size = len (dockerfile )
617617
618618 tar .addfile (dockerfile_tarinfo , io .BytesIO (dockerfile ))
@@ -624,8 +624,8 @@ def _filter_tar(tar):
624624 # https://github.com/docker/docker-py/pull/1582 is related
625625 tar .uname = ""
626626 tar .gname = ""
627- tar .uid = int (build_args .get ("NB_UID" , 1000 ))
628- tar .gid = int (build_args .get ("NB_UID" , 1000 ))
627+ tar .uid = int (build_args .get ("NB_UID" , DEFAULT_NB_UID ))
628+ tar .gid = int (build_args .get ("NB_UID" , DEFAULT_NB_UID ))
629629 return tar
630630
631631 for src in sorted (self .get_build_script_files ()):
0 commit comments