Using Docker with Phoenix Umbrella App
Tags: docker, phoenix
Published: 2023-04-30 22:25:51

---
title: Using Docker with Phoenix Umbrella App
published: true
description: 
tags: docker, phoenix
---

First, config the distillery with:

```elixir
# rel/config.exs
...

release :void do
  set version: "0.1.0"
  set applications: [
    :runtime_tools,
    void: :permanent,
  ]
  set commands: [
    "migrate": "rel/commands/migrate.sh",
    "seed": "rel/commands/seed.sh"
  ]
end

release :void_web do
  set version: "0.1.0"
  set applications: [
    :runtime_tools,
    void: :permanent,
    void_web: :permanent
  ]
end

...
```

Then use the following `Dockerfile` which take an arg `app_name`, then build the specific umbrella app for you.

```dockerfile
# Dockerfile

FROM elixir:1.4

# fixes bad trap when running release in foreground, built with distillery
# https://github.com/bitwalker/distillery/issues/18
RUN echo 'dash dash/sh boolean false' | debconf-set-selections
RUN dpkg-reconfigure -phigh dash

RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - && apt-get install -y nodejs
RUN apt-get install -y build-essential

# ENVs
ENV MIX_ENV=prod

# Define path ENVs
ENV BUILD_DIR /build
RUN mkdir $BUILD_DIR
ENV APP_HOME /app
RUN mkdir $APP_HOME

## Build
WORKDIR $BUILD_DIR

# Install Elixir Deps
RUN mix local.hex --force \
  && mix local.rebar --force

# Copying mix.exs
COPY mix.exs mix.lock ./
COPY apps/void/mix.exs apps/void/
COPY apps/void_web/mix.exs apps/void_web/

# Fetch deps
COPY deps deps
RUN mix deps.get

# Copying Config files
COPY config ./config
RUN mkdir -p apps/void/config
COPY apps/void/config/* apps/void/config/
RUN mkdir -p apps/void_web/config
COPY apps/void_web/config/* apps/void_web/config/

# Compile everything
RUN mix compile

# Web Assets
COPY apps/void_web/assets apps/void_web/assets
RUN cd apps/void_web/assets/ \
  && npm install \
  && ./node_modules/brunch/bin/brunch build --production
RUN cd apps/void_web && mix phx.digest

ADD . .

## - Release tasks, build the $app_name application.
ARG app_name

RUN mix release --name=$app_name --env=prod --executable

# Copy releases
RUN cp ./_build/prod/rel/$app_name/bin/$app_name.run $APP_HOME/ \
  && rm -rf $BUILD_DIR

WORKDIR $APP_HOME

# Set entry point
RUN echo "./$app_name.run \$1" > entrypoint.sh
ENTRYPOINT ["sh", "entrypoint.sh"]

CMD foreground
```

Using with docker-compose

```yml
version: "3"
volumes:
  db-volume:
    driver: local

services:
  db:
    image: "postgres:9.4"
    expose:
      - "5432"
    environment:
      POSTGRES_USER: civic
      POSTGRES_PASSWORD: civic
      POSTGRES_DB: civic_prod
    volumes:
      - db-volume:/var/lib/postgresql

  migrator:
    build:
      context: "."
      dockerfile: Dockerfile
      args:
        app_name: void
    environment:
      MIX_ENV: "prod"
      DATABASE_URL: postgres://civic:civic@db/civic_prod
    depends_on:
      - db
    command: migrate

  web:
    build:
      context: "."
      dockerfile: Dockerfile
      args:
        app_name: void_web
    environment:
      MIX_ENV: "prod"
      PORT: 4000
      DATABASE_URL: postgres://civic:civic@db/civic_prod
    depends_on:
      - db
      - migrator
    command: foreground
    ports:
      - "4000:4000"
```