I am learning how to use Docker. I’m creating a container that contains Python and React. This code works, but it seems so heavy when I install it. I only want React, but to get React, I install Node so I can use npm later on. Do you see ways to optimize this? Or are there any red flags?
FROM python:3.6-slim # first two are for python, last five are for node RUN apt-get update && apt-get install -qq -y build-essential libpq-dev --no-install-recommends && apt-get install -y curl && apt-get -y autoclean && curl -sL https://deb.nodesource.com/setup_5.x | bash && apt-get install -y nodejs && apt-get autoremove -y # install python components ENV INSTALL_PATH /brainlint RUN mkdir -p $INSTALL_PATH WORKDIR $INSTALL_PATH COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt COPY . . RUN pip3 install --editable . CMD gunicorn -b 0.0.0.0:8000 --access-logfile - "brainlint.app:create_app()"
Your dockerfile is generally correct. Every RUN instruction in the Dockerfile writes a new layer in the image. Every layer requires extra space on disk. In order to keep the number layers to a minimum, any file manipulation like moving, extracting, removing, etc, should ideally be made under a single RUN instruction. So, you should try to minimize number of RUN command in your file (eg. try to merge installing requirements into one command) You can check size of you layers using cmd:
But there is question – Why do you want to have react and python in one container?
From this dockerfile I don’t understand why you are adding node/react to your container. If you need python, because you have to prepare some data for react or run some script before start your node app, then you could think about use Multi-Stage Builds. Example:
FROM python:3.6-slim # here build/do what you want to do WORKDIR /myapp COPY myscript.py . RUN python myscript.py > data FROM bayesimpact/react-base # run your react application WORKDIR /myapp COPY react_app . CMD ["./react_app/app", "data"]
So, when you are using Muli-Stage Builds you can:
You can selectively copy artifacts from one stage to another, leaving
behind everything you don’t want in the final image.
Also, there is possibility to use prepared earlier image with node and python, it should be smaller, but you have to also check this. (e.g beevelop/docker-nodejs-python)