Skip to content
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

Enhancement: Improve Dockerfile for cached layer handling #2158

Open
1 task done
virtuman opened this issue Mar 21, 2024 · 3 comments
Open
1 task done

Enhancement: Improve Dockerfile for cached layer handling #2158

virtuman opened this issue Mar 21, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@virtuman
Copy link
Contributor

virtuman commented Mar 21, 2024

What features would you like to see added?

Docker takes too long, couple simple manipulations will drastically improve build times and utilize cached layers, to avoid entire image rebuild on each run. You can see screenshots below, to notice build time differences

More details

something like this would result in a quicker build, given that you use runner that has docker cache, or pull :latest and use as cache. And minimize number of RUN commands, so that it doesn't persist layer after each command

here're the differences:

  • [*] first complete steps that are more permanent and don't need to be redone every time (like apk and npm -g)
  • [*] switch to user before copying files, this will automatically move files under that user
  • [*] WORKDIR will actually auto-create a folder with the set user already
  • [*] unfortunately requires tiny hardcode with paths, so we copy only changed code that requires re-compile before npm install
  • [*] then run NPM install (otherwise, it runs npm install and download tens of mbs on every codebase change)
  • copy all changed code
  • compile app

all steps that i marked, will re-use cached layers, and only app build will re-run on every rebuild of the app

this way, image build will go to seconds, if you use runners that have perstitent docker or use --pull in docker build command, to re-use cached layers (that will add few extra seconds to pull last built image as cache from docker registry)

Below is a working version of Dockerfile that I use it myself

# Base node image
FROM node:18-alpine AS node

RUN apk add --no-cache g++ make py3-pip curl && \
        npm config set fetch-retry-maxtimeout 300000 && \
        npm install -g node-gyp npm

USER node

WORKDIR /app

# Copy package.json and package-lock.json (if available)
COPY --chown=node:node package.json package-lock.json* ./
COPY --chown=node:node config config/
COPY --chown=node:node api/package.json api/
COPY --chown=node:node client/package.json client/
COPY --chown=node:node packages/data-provider/package.json packages/data-provider/

# Install dependencies
RUN npm install --no-audit
# Allow mounting of these files, which have no default
# values.
RUN touch .env

# Copy the rest of the application code
COPY --chown=node:node . .

# React client build
ENV NODE_OPTIONS="--max-old-space-size=2048"
RUN npm run frontend

# Node API setup
EXPOSE 3080
ENV HOST=0.0.0.0
CMD ["npm", "run", "backend"]

# Optional: for client with nginx routing
# FROM nginx:stable-alpine AS nginx-client
# WORKDIR /usr/share/nginx/html
# COPY --from=node /app/client/dist /usr/share/nginx/html
# COPY client/nginx.conf /etc/nginx/conf.d/default.conf
# EXPOSE 80
# ENTRYPOINT ["nginx", "-g", "daemon off;"]


Which components are impacted by your request?

No response

Pictures

Initial Build - before caching or if package-json files not changed
Initial Build - before caching or if package-json files not changed

Consequent rebuild without code changes
Consequent rebuild without code changes

Code changed in client only
Code changed in client only

Code of Conduct

  • I agree to follow this project's Code of Conduct
@virtuman virtuman added the enhancement New feature or request label Mar 21, 2024
@danny-avila
Copy link
Owner

danny-avila commented Mar 21, 2024

Feel free to submit a PR. I made some Dockerfile changes today, by the way, in case that affected your build time.

@ochen1
Copy link
Contributor

ochen1 commented Apr 4, 2024

Just saw this, I think my PR #2275 aims to address this issue to some extent.

@danny-avila
Copy link
Owner

danny-avila commented Apr 4, 2024

Just saw this, I think my PR #2275 aims to address this issue to some extent.

yes your PR addresses it for Dockerfile.multi but could use help to optimize the default Dockerfile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants