Skip to content

extra chown command pads image size and build time #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 tasks done
rgschmitz1 opened this issue Apr 25, 2022 · 8 comments · Fixed by #58
Closed
3 tasks done

extra chown command pads image size and build time #55

rgschmitz1 opened this issue Apr 25, 2022 · 8 comments · Fixed by #58

Comments

@rgschmitz1
Copy link
Contributor

rgschmitz1 commented Apr 25, 2022

My actions before raising this issue

Expected Behaviour

The --chown flag was introduced in v17.09.0-ce allows for copying files and changing ownership in one step, this would allow for copying files with non-root permissions without any additional container layer.

Current Behaviour

There's an additional RUN chown -R app:app ../ layer in several Dockerfiles that pads the overall image size and build time, this is especially noticeable as user specified requirements.txt grows.

Possible Solution

Add the --chown=app flag to any COPY command intended for non-root user (app) files, this will reduce overall build time and container image size.

or alternative...

Create an additional build stage (e.g. FROM python:* AS production) and copy over necessary build artifacts after testing finishes. This may require significant tweaking to the Dockerfiles to make this solution possible (e.g. using a virtualenv), however it may result in a much smaller container image?

Steps to Reproduce (for bugs)

  1. faas-cli template pull https://github.com/openfaas-incubator/python-flask-template
  2. faas-cli new --lang python3-http-debian hello-python
  3. Add several requirements to the hello-python/requirements.txt, example below
boto3
botocore
click
gensim
jmespath
joblib
nltk
numpy
pandas
python-dateutil
pytz
regex
s3transfer
scipy
simplejson
six
smart-open
tqdm
urllib3
  1. time faas-cli build --no-cache -f hello-python.yml
  2. Modify any file COPY command intended for non-root user files to include --chown=app
diff --git a/template/python3-http-debian/Dockerfile b/template/python3-http-debian/Dockerfile
index 624fb03..6396fd3 100644
--- a/template/python3-http-debian/Dockerfile
+++ b/template/python3-http-debian/Dockerfile
@@ -19,8 +19,8 @@ ENV PATH=$PATH:/home/app/.local/bin

 WORKDIR /home/app/

-COPY index.py           .
-COPY requirements.txt   .
+COPY --chown=app index.py           .
+COPY --chown=app requirements.txt   .
 USER root
 RUN pip install -r requirements.txt
 USER app
@@ -32,8 +32,7 @@ COPY function/requirements.txt        .
 RUN pip install --user -r requirements.txt

 USER root
-COPY function/   .
-RUN chown -R app:app ../
+COPY --chown=app function/ .

 ARG TEST_COMMAND=tox
 ARG TEST_ENABLED=true
  1. time faas-cli build --no-cache -f hello-python.yml
  2. Compare image size and build time

Context

I'm a college student working on a capstone project involving deploying open-source cloud native applications in Kubernetes and doing a comparison against vendor specific solutions.

I'm using python-flask-templates as a basis for my own custom functions and would love to contribute in any way I can.

Your Environment

  • FaaS-CLI version ( Full output from: faas-cli version ):
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|

CLI:
 commit:  b1c09c0243f69990b6c81a17d7337f0fd23e7542
 version: 0.14.2
  • Docker version docker version (e.g. Docker 17.0.05 ):
Docker version 20.10.14, build a224086
  • Are you using Docker Swarm or Kubernetes (FaaS-netes)?
    Kubernetes

  • Operating System and version (e.g. Linux, Windows, MacOS):

NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
  • Code example or link to GitHub repo or gist to reproduce problem:
    I can create a full gist if desired, but the requirements.txt provided in the "steps to reproduce" above matches my specific use case. To summarize my results, after implementing the first proposed solution produces a ~30 second decrease in build time and ~500mb decrease in image size.

  • Other diagnostic information / logs from troubleshooting guide

@rgschmitz1 rgschmitz1 changed the title extra chown command pads filesize and build time extra chown command pads image size and build time Apr 25, 2022
@LucasRoesler
Copy link
Member

I saw the same thing in an (unrelated) Node image recently, my solution for that image was to run the node install as the non-root user.

I think the --chown was relatively new when we first started these templates, but it has been 5 years, it is probably safe to use now? What do you think @alexellis ?

@alexellis
Copy link
Member

Hi @rgschmitz1 thanks for the detailed feedback and suggestions.

We don't use COPY --chown due to potential support problems with other container builders like Kaniko.

If you can show the build still works with kaniko, then I think we could take a PR for this change.

Separately, would you be open to a short chat to hear more about what you're doing with OpenFaaS?

Alex

@rgschmitz1
Copy link
Contributor Author

Hi @alexellis ,

It was in the back of my mind that other container builders might not support the same flags, but I just did a quick search and it does look like chown support was added fairly recently to Kaniko (GoogleContainerTools/kaniko#962). I haven't used Kaniko, but I'm willing to verify.

It might be worth while to test out a different the approach that @LucasRoesler mentioned if the --chown flag isn't standard for all the different build tools.

I saw the same thing in an (unrelated) Node image recently, my solution for that image was to run the node install as the non-root user.

Also, I'd be happy to send a message to fill you in on how I'm using OpenFaaS!

@rgschmitz1
Copy link
Contributor Author

rgschmitz1 commented Jun 9, 2022

Sorry for the delay in getting back to you all, I've been busy with taking care of my 7 month old and classes.

I just tested out Kaniko with COPY --chown=app and it appears to be working correctly. See the build log here,
https://gist.github.com/rgschmitz1/5b42f8d796b715287589e7470d2f6c44

--- additional note ---
I manually checked that the permissions in the /home/app directory were set correctly... There was a lot of files (not all 100% necessary), I can create an additional log if desired.

I also noticed that the tox test generated a completely new virtualenv with root permissions, I'm not sure if it is necessary or desired to keep these test files in the final image. I'll likely create a new issue ticket with some additional recommendations to trim down the container image size. 👍🏻

@alexellis
Copy link
Member

That sounds good.

@LucasRoesler do you want to go ahead and send a PR for this?

LucasRoesler added a commit to LucasRoesler/python-flask-template that referenced this issue Aug 20, 2022
Using the `--chown` flag during `COPY` is much faster than running
`chown -R`. It also removes a layer from the image, resulting in faster
and smaller builds.

Resolves openfaas#55

Signed-off-by: Lucas Roesler <[email protected]>
@LucasRoesler
Copy link
Member

@alexellis patched here #58

@LucasRoesler
Copy link
Member

LucasRoesler commented Aug 20, 2022

@alexellis also related is #59 which resolves #57

@rgschmitz1
Copy link
Contributor Author

@alexellis and @LucasRoesler , thanks for the support!

LucasRoesler added a commit to LucasRoesler/python-flask-template that referenced this issue Oct 4, 2022
Using the `--chown` flag during `COPY` is much faster than running
`chown -R`. It also removes a layer from the image, resulting in faster
and smaller builds.

Resolves openfaas#55

Signed-off-by: Lucas Roesler <[email protected]>
alexellis pushed a commit that referenced this issue Oct 4, 2022
Using the `--chown` flag during `COPY` is much faster than running
`chown -R`. It also removes a layer from the image, resulting in faster
and smaller builds.

Resolves #55

Signed-off-by: Lucas Roesler <[email protected]>
jpauwels pushed a commit to jpauwels/python-flask-template that referenced this issue Apr 15, 2023
Using the `--chown` flag during `COPY` is much faster than running
`chown -R`. It also removes a layer from the image, resulting in faster
and smaller builds.

Resolves openfaas#55

Signed-off-by: Lucas Roesler <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants