Skip to content

Instantly share code, notes, and snippets.

@enspdf
Forked from zeagord/node-docker.md
Created September 13, 2019 16:22
Show Gist options
  • Save enspdf/0f86a7bc321a57cf47e1ec4cc06d28a2 to your computer and use it in GitHub Desktop.
Save enspdf/0f86a7bc321a57cf47e1ec4cc06d28a2 to your computer and use it in GitHub Desktop.

Revisions

  1. @zeagord zeagord revised this gist Apr 7, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion node-docker.md
    Original file line number Diff line number Diff line change
    @@ -97,4 +97,8 @@ CMD ["pm2 start"]


    * **Final image size: ~400MB (~1.2 GB earlier)**
    * **Build time: 10 seconds (15 minutes earlier)**
    * **Build time: 10 seconds (15 minutes earlier)**

    Note: All the image sizes mentioned are uncompressed version sizes. The actualy size uploaded to docker registries will be compressed and will smaller than the sizes mentioned.

    Next Steps: Need to explore options to reduce the size by exploring the official wheezy/alpine versions and install node by my self and test.
  2. @zeagord zeagord revised this gist Apr 7, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions node-docker.md
    Original file line number Diff line number Diff line change
    @@ -94,5 +94,7 @@ WORKDIR /usr/src/app
    CMD ["pm2 start"]
    ```



    * **Final image size: ~400MB (~1.2 GB earlier)**
    * **Build time: 10 seconds (15 minutes earlier)**
  3. @zeagord zeagord revised this gist Apr 7, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions node-docker.md
    Original file line number Diff line number Diff line change
    @@ -94,5 +94,5 @@ WORKDIR /usr/src/app
    CMD ["pm2 start"]
    ```

    Final image size: ~400MB (~1.2 GB earlier)
    Build time: 10 seconds (15 minutes earlier)
    * **Final image size: ~400MB (~1.2 GB earlier)**
    * **Build time: 10 seconds (15 minutes earlier)**
  4. @zeagord zeagord revised this gist Apr 7, 2017. No changes.
  5. @zeagord zeagord revised this gist Apr 7, 2017. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions node-docker.md
    Original file line number Diff line number Diff line change
    @@ -94,6 +94,5 @@ WORKDIR /usr/src/app
    CMD ["pm2 start"]
    ```




    Final image size: ~400MB (~1.2 GB earlier)
    Build time: 10 seconds (15 minutes earlier)
  6. @zeagord zeagord revised this gist Apr 7, 2017. 1 changed file with 68 additions and 0 deletions.
    68 changes: 68 additions & 0 deletions node-docker.md
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@ different CI/CD pipelines and environments.

    The initial docker file was looking something like this:

    ## Initial Docker File
    ```
    FROM node:6.10.1-alpine
    ENV APP_ENV $APP_ENV
    @@ -29,3 +30,70 @@ ADD start.sh /start.sh
    RUN chmod 755 /start.sh
    CMD ["/start.sh"]
    ```
    ## PROBLEMS
    1. Docker Image Size
    2. Image build Time
    3. Configure the image building process for different environment pipeline


    ## Solution

    I first decided to upgrade to Node:6 because of the LTS (Long Term Support), next I wanted to use a slim version of offcial node docker image. I didn't choose the alpine version for the reason there is no official support for node-sass. There are plethora of docker images available with sass-alpine-node version. But I strongly recommend not to use it for security reasons.

    ```
    FROM node:6-slim
    ```
    Secondly I want to build a base web image specific to my project with all the node_modules dependencies installed. Whenever we add a new module to npm package, we need to build the base image once which is not going to happen super frequently.

    The next thing, I did after updating to node 6 was to make use of in built node capabilities. You can read more about them in the official npmjs website more.

    Removes the duplicate refrences of node modules
    ```
    npm dedupe
    ```
    Removes the unreferenced node modules
    ```
    npm prune
    ```
    Create a shrinkwrap to lock down the node module versions
    ```
    npm shrinkwrap
    ```

    This has reduced the number of modules get installed and the size of the node_modules directory. The final base image docker file looked like below.

    ```
    FROM node:6-slim
    ENV APP_ENV $APP_ENV
    ENV BINPATH /usr/bin
    COPY wkhtmltox/bin/wkhtmltopdf /usr/local/bin/
    RUN mkdir -p /usr/src/app
    COPY package.json /usr/src/app/
    WORKDIR /usr/src/app/
    RUN npm install --production
    ```
    Then I built a base image like below:

    ```
    docker build -t base-web-image:<version-number> .
    ```

    After this I removed the executing the grunt task out the docker image build process and moved it to the build agent machine.

    ```
    grunt --env=prod
    ```

    As a final step, whenever a business logic or new code is pushed a new image needs to be built as a final application. I refered the image built earlier and started to refer it in the second image.

    ```
    FROM base-web-image
    RUN mkdir -p /usr/src/app
    COPY dist /usr/src/app
    WORKDIR /usr/src/app
    CMD ["pm2 start"]
    ```




  7. @zeagord zeagord revised this gist Apr 7, 2017. 1 changed file with 2 additions and 10 deletions.
    12 changes: 2 additions & 10 deletions node-docker.md
    Original file line number Diff line number Diff line change
    @@ -5,35 +5,27 @@ different CI/CD pipelines and environments.

    The initial docker file was looking something like this:

    `
    ```
    FROM node:6.10.1-alpine
    ENV APP_ENV $APP_ENV
    ENV BINPATH /usr/bin
    COPY wkhtmltox/bin/wkhtmltopdf /usr/local/bin/

    RUN mkdir -p /usr/src/app

    WORKDIR /usr/src/app/

    # Install app dependencies
    COPY package.json /usr/src/app/
    #COPY start.sh /usr/src/app/
    RUN npm install --production

    RUN npm install -g [email protected]

    # Bundle app source
    COPY . /usr/src/app

    # Install pm2 so we can run our app
    RUN npm i -g pm2

    # run grunt, cd to dist, node server.js
    RUN grunt --env=prod
    #COPY start.sh dist
    WORKDIR dist

    ADD start.sh /start.sh
    RUN chmod 755 /start.sh
    CMD ["/start.sh"]
    `
    ```
  8. @zeagord zeagord revised this gist Apr 7, 2017. 2 changed files with 39 additions and 7 deletions.
    7 changes: 0 additions & 7 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,7 +0,0 @@
    When we were trying to create a docker image for our Node JS based application, we chose to use the official Node docker image (~700MB).
    On top of that we need to add the node modules, business logic, etc and so on. The final image size was staggering (~1.2GB). It was not what we wanted.
    Secondly, the average build time to do NPM install and run a grunt task totally took 15 minutes for every build. I am not even talking about the pain of configuring this for
    different CI/CD pipelines and environments.

    The initial docker file was looking something like this:

    39 changes: 39 additions & 0 deletions node-docker.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    When we were trying to create a docker image for our Node JS based application, we chose to use the official Node docker image (~700MB).
    On top of that we need to add the node modules, business logic, etc and so on. The final image size was staggering (~1.2GB). It was not what we wanted.
    Secondly, the average build time to do NPM install and run a grunt task totally took 15 minutes for every build. I am not even talking about the pain of configuring this for
    different CI/CD pipelines and environments.

    The initial docker file was looking something like this:

    `
    FROM node:6.10.1-alpine
    ENV APP_ENV $APP_ENV
    ENV BINPATH /usr/bin
    COPY wkhtmltox/bin/wkhtmltopdf /usr/local/bin/

    RUN mkdir -p /usr/src/app

    WORKDIR /usr/src/app/

    # Install app dependencies
    COPY package.json /usr/src/app/
    #COPY start.sh /usr/src/app/
    RUN npm install --production

    RUN npm install -g [email protected]

    # Bundle app source
    COPY . /usr/src/app

    # Install pm2 so we can run our app
    RUN npm i -g pm2

    # run grunt, cd to dist, node server.js
    RUN grunt --env=prod
    #COPY start.sh dist
    WORKDIR dist

    ADD start.sh /start.sh
    RUN chmod 755 /start.sh
    CMD ["/start.sh"]
    `
  9. @zeagord zeagord created this gist Apr 7, 2017.
    7 changes: 7 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    When we were trying to create a docker image for our Node JS based application, we chose to use the official Node docker image (~700MB).
    On top of that we need to add the node modules, business logic, etc and so on. The final image size was staggering (~1.2GB). It was not what we wanted.
    Secondly, the average build time to do NPM install and run a grunt task totally took 15 minutes for every build. I am not even talking about the pain of configuring this for
    different CI/CD pipelines and environments.

    The initial docker file was looking something like this: