kriasoft / react-starter-kit

The web's most popular Jamstack front-end template (boilerplate) for building web applications with React
https://reactstarter.com
MIT License
22.78k stars 4.16k forks source link

Docker: How to setup production container to be smaller? #1224

Closed epozsh closed 3 years ago

epozsh commented 7 years ago

Hello, i am using old version of react-starter kit intl with old tools(build,run etc) before update of webpack, my webpack is (1.13.3) i am new with this, is there any way to build all node_modules that needed in single file while doing

npm run build -- --release and then just build docker container without

RUN npm install yarn --global --no-progress --silent --depth 0 && \
yarn install --production --no-progress

? My build folder is 5ΜΒ. But Docker Container become 500mb Sorry for the inconvenience

koistya commented 7 years ago

First thing to do is to update node image to v7.8.0 and remove npm install yarn ... part as it's already included into the official node image.

epozsh commented 7 years ago

By doing this the docker image is reduced by 30ΜΒ. Dockerfile:

FROM node:7.9.0-alpine

# Copy application files
COPY ./build /usr/src/app
WORKDIR /usr/src/app

# Install Node.js dependencies
RUN yarn install --production --no-progress
ENV NODE_ENV production
CMD [ "node", "server.js" ]

Is there something more to do?

langpavel commented 7 years ago

You can switch order, set ENV above yarn

epozsh commented 7 years ago

Still same this is my dependencies

"dependencies": {
    "babel-core": "^6.22.1",
    "babel-polyfill": "6.16.0",
    "babel-runtime": "6.18.0",
    "bluebird": "3.4.6",
    "body-parser": "1.15.2",
    "bootstrap": "^3.3.7",
    "classnames": "2.2.5",
    "compression": "^1.6.2",
    "cookie-parser": "1.4.3",
    "core-js": "2.4.1",
    "d3": "^4.7.3",
    "d3fc-label-layout": "^5.0.1",
    "express": "4.14.0",
    "express-graphql": "0.6.1",
    "express-jwt": "5.1.0",
    "express-request-language": "1.1.8",
    "fastclick": "1.0.6",
    "fbjs": "0.8.6",
    "feathers": "^2.0.3",
    "feathers-hooks": "^1.7.1",
    "feathers-rest": "^1.6.0",
    "feathers-sequelize": "^1.4.5",
    "front-matter": "2.1.1",
    "graphql": "^0.8.2",
    "graphql-server-express": "^0.7.1",
    "graphql-tools": "^0.9.0",
    "history": "4.4.0",
    "html-to-react": "^1.2.3",
    "interactjs": "^1.2.8",
    "intl": "1.2.5",
    "intl-locales-supported": "1.0.0",
    "isomorphic-style-loader": "1.1.0",
    "jsonwebtoken": "7.1.9",
    "leaflet": "^1.0.3",
    "leaflet-curve": "^1.0.0",
    "markdown-it": "8.1.0",
    "marked": "^0.3.6",
    "node-fetch": "1.6.3",
    "normalize.css": "5.0.0",
    "npm": "^4.0.5",
    "pretty-error": "2.0.2",
    "query-string": "4.2.3",
    "react": "15.4.1",
    "react-bootstrap": "^0.30.7",
    "react-burger-menu": "^1.10.14",
    "react-calendar-timeline": "^0.11.1",
    "react-dom": "15.4.1",
    "react-dropzone": "^3.12.2",
    "react-google-recaptcha": "^0.5.4",
    "react-html-parser": "^1.0.3",
    "react-image-gallery": "^0.7.15",
    "react-images": "^0.5.2",
    "react-intl": "2.1.5",
    "react-js-pagination": "^2.0.2",
    "react-leaflet": "^1.1.1",
    "react-leaflet-curve": "^1.0.0",
    "react-leaflet-fullscreen": "0.0.5",
    "react-markdown": "^2.4.6",
    "react-portal": "^3.0.0",
    "react-pure-render": "^1.0.2",
    "react-redux": "4.4.5",
    "react-redux-loading-bar": "^2.8.1",
    "react-render-html": "^0.1.6",
    "react-responsive": "^1.2.6",
    "react-router": "^3.0.1",
    "react-scroll": "^1.4.8",
    "react-select": "^1.0.0-rc.3",
    "react-string-replace": "^0.4.0",
    "react-swipe": "^5.0.6",
    "react-swipeable-views": "^0.10.7",
    "redux": "3.6.0",
    "redux-connect": "^5.0.0",
    "redux-form": "^6.2.1",
    "redux-logger": "2.7.4",
    "redux-thunk": "2.1.0",
    "request-promise": "^4.1.1",
    "sanitize-html": "^1.14.1",
    "sequelize": "3.27.0",
    "serialize-javascript": "1.3.0",
    "snapjs": "^1.2.1",
    "source-map-support": "^0.4.3",
    "sqlite3": "3.1.8",
    "string-replace-to-array": "^1.0.1",
    "tedious": "^1.14.0",
    "to-markdown": "^3.0.4",
    "tween.js": "^16.6.0",
    "universal-router": "2.0.0",
    "whatwg-fetch": "2.0.1",
    "winston": "^2.3.0"
  }

maybe size cannot be reduced?

fhillipgcastillo commented 4 years ago

Hello,

I hope to bring a solution as is been too long time and this is open. I found this as I looking for best practices and improvements in my learning curve about Docker.

Intro to the solution

Docker has the ability to use the multi-stage build for the containerization process and we can also name them to be reutilized certain things from the other stages.

What is Multi-Stage Builds

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image. To show how this works, let’s adapt the Dockerfile from the previous section to use multi-stage builds. [Taken from docker documentation]

An example:

FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]  
...

Also found at Docker multi-stage builds documentation

I hope this all gives you the solution you where looking for, @Shadowman4205 and the others.

Read the full documentation for Multi-stage Builds

I found this from dockerfile best practices

ulani commented 3 years ago

@Shadowman4205 thank you very much for crating this issue! Unfortunately, we have close it due to inactivity. Feel free to re-open it or join our Discord channel for discussion.

NOTE: The main branch has been updated with React Starter Kit v2, using JAM-style architecture.