FrankBeautiful
FrankBeautiful

Reputation: 41

How to handle differences in Dockerfile for dev/prod

Recently started with Docker and I'm setting up a new project. I have a Dockerfile for a Node web app set up to run an npm script for development which runs webpack with live reloading and a few other processes like linting, etc.

I'm setting up for my production deployment which will look a bit different.

What's the recommended approach to handle the differences? Two Dockerfiles?

Upvotes: 4

Views: 2764

Answers (2)

pinage404
pinage404

Reputation: 33

I think you should "play" with ARG and ENV

https://docs.docker.com/engine/reference/builder/#/arg

https://docs.docker.com/engine/reference/builder/#env

Example:

Dockerfile:

FROM node:7.1

ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV:-production}

COPY package.json .
RUN npm install

COPY . .

CMD npm start # the start script can handle the NODE_ENV variable to run a special command

bash for development:

docker build --tag myimage:development --build-arg "NODE_ENV=development" .
docker run myimage:development

bash for production:

docker build --tag myimage:production --build-arg "NODE_ENV=production" .
# or
docker build --tag myimage:production .
docker run myimage:production

Upvotes: 1

Bukharov Sergey
Bukharov Sergey

Reputation: 10185

You may be surprised but three Dockerfiles looks better!

  • First Dockerfile contains common things for dev and production environment, This may named a "my-app-base";
  • Second - dev Dockerfile based on "First" image and contains only specific things for dev env;
  • Third - production Dockerfile based on "First" image and contains only specific things for production env.

Let me show you on the example of php project :

Base dockerfile

We create base image for our project. Dockerfile.base will look like

# Set the base image
FROM php:5.6-apache

# install php dependencies
RUN apt-get update && apt-get install -y \
        php5-pgsql \
        postgresql-client \
        php5-mongo \
        libxml2-dev \
        php-soap \
        libpq-dev \
        libmcrypt-dev \
        php-pear \
    && docker-php-ext-install pdo \
    && docker-php-ext-install pgsql \
    && docker-php-ext-install pdo_pgsql \
    && docker-php-ext-install soap \
    && docker-php-ext-install pcntl \
    && docker-php-ext-install mcrypt

# preconfiguring apache
RUN a2enmod rewrite && a2enmod headers && a2enmod proxy && a2enmod proxy_http
RUN echo "export DISPLAY=':0'" >> /etc/apache2/envvars
VOLUME /var/log/apache2
EXPOSE 80

# configure envarionments
RUN echo "date.timezone=Europe/Moscow" > $PHP_INI_DIR/conf.d/date_timezone.ini

...settings env, configuring apache, etc...

and image will named my_company/php5.6:base

Production Dockerfile

In production i want to have container with source code inside, then my Dockerfile.prod will look like:

# Set the base image
FROM my_company/php5.6:base

# begin instalation
# copy src
ADD . /src

Dev Dockerfile

In dev env i want to have ability to edit source code outside of container, then my Dockerfile.dev will look like:

# Set the base image
FROM my_company/php5.6:base

RUN docker-php-ext-install xdebug

VOLUME /src

Upvotes: 1

Related Questions