README.md

# Build Release builds a release tar through a docker container

A mix task to build a release in a linux container and then copy it out to the
project's path on the host machine.

If you, like me, work on a mac then the release created on the mac isn't useful
for production: I want to run my apps on linux. This library will build the
release inside a linux docker container and then copy the tar.gz out.  This
also means builds are very repeatable and always created in the same
environment.

## Usage

First, make sure you can build a release:

```sh
$ MIX_ENV=prod mix release
```

Then, place a `Dockerfile` in the project’s root directory. You can find
examples for [ubuntu](#ubuntu) and [debian](#debian) below.

Then, you should be able to:

```sh
$ mix build.release
```

You will now have a `.tar` in your current directory of the release built from inside the container. If you `tar -xf` then the can by started with: `:app_name/bin/:app_name start`

## Installation

Make sure you have docker running. If you can `docker ps` then you are good.
Docker for Mac/Windows is a good app if you are starting from zero.

The package can be installed by adding `build_release` to your list of
dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:build_release, "~> 0.3.0", only: [:dev]}
  ]
end
```

## Example `Dockerfile`s:

### Debian

```Dockerfile
FROM elixir:1.10.3

MAINTAINER Nathan Herald and Anthony Drendel

CMD /bin/bash

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

ENV MIX_ENV=prod

RUN mix local.hex --force && \
    mix local.rebar --force && \
    mix hex.info

WORKDIR /app
RUN mkdir config

COPY mix.exs mix.lock /app/
COPY config/config.exs config/prod.exs config/releases.exs /app/config/

# Must get deps before npm install becuase some javascript is inside some of
# the elixir packages
RUN mix do deps.get --only prod, deps.compile

WORKDIR /app/assets

COPY assets/package.json assets/package-lock.json /app/assets/

RUN npm install

COPY assets /app/assets/
RUN npm run deploy

WORKDIR /app

RUN mix phx.digest

COPY priv /app/priv/
COPY lib /app/lib/

RUN mix compile
RUN mix release

RUN tar -zcf /release.tar.gz -C /app/_build/prod/rel/ .
```

### Ubuntu

```Dockerfile
FROM ubuntu:bionic

MAINTAINER Nathan Herald & Anthony Drendel

ENV OTP_VERSION="22.3.3" \
    REBAR3_VERSION="3.13.1" \
    DEBIAN_FRONTEND="noninteractive"

# We'll install the build dependencies for erlang-odbc along with the erlang
# build process:
RUN set -xe \
	&& OTP_DOWNLOAD_URL="https://github.com/erlang/otp/archive/OTP-${OTP_VERSION}.tar.gz" \
	&& OTP_DOWNLOAD_SHA256="58ef3623cad5f490fdc0719514fe1a9626c8b177a4fb8fa25b5bec0216693eb9" \
	&& runtimeDeps='libodbc1 \
			libsctp1 \
			libwxgtk3.0' \
	&& buildDeps='unixodbc-dev \
			libsctp-dev \
			libwxgtk3.0-dev \
      ca-certificates \
      autoconf \
      git \
      build-essential \
      libncurses-dev \
      openssl \
      libssl-dev \
      curl' \
	&& apt-get update \
	&& apt-get install -y --no-install-recommends $runtimeDeps \
	&& apt-get install -y --no-install-recommends $buildDeps \
	&& curl -fSL -o otp-src.tar.gz "$OTP_DOWNLOAD_URL" \
	&& echo "$OTP_DOWNLOAD_SHA256  otp-src.tar.gz" | sha256sum -c - \
	&& export ERL_TOP="/usr/src/otp_src_${OTP_VERSION%%@*}" \
	&& mkdir -vp $ERL_TOP \
	&& tar -xzf otp-src.tar.gz -C $ERL_TOP --strip-components=1 \
	&& rm otp-src.tar.gz \
	&& ( cd $ERL_TOP \
	  && ./otp_build autoconf \
	  && ./configure --disable-hipe --without-javac \
	  && make -j$(nproc) \
	  && make install ) \
	&& rm -rf $ERL_TOP /var/lib/apt/lists/*

# elixir expects utf8.
ENV ELIXIR_VERSION="v1.10.3" \
	LANG=C.UTF-8

RUN set -xe \
	&& ELIXIR_DOWNLOAD_URL="https://github.com/elixir-lang/elixir/archive/${ELIXIR_VERSION}.tar.gz" \
	&& ELIXIR_DOWNLOAD_SHA256="f3035fc5fdade35c3592a5fa7c8ee1aadb736f565c46b74b68ed7828b3ee1897" \
	&& curl -fSL -o elixir-src.tar.gz $ELIXIR_DOWNLOAD_URL \
	&& echo "$ELIXIR_DOWNLOAD_SHA256  elixir-src.tar.gz" | sha256sum -c - \
	&& mkdir -p /usr/local/src/elixir \
	&& tar -xzC /usr/local/src/elixir --strip-components=1 -f elixir-src.tar.gz \
	&& rm elixir-src.tar.gz \
	&& cd /usr/local/src/elixir \
	&& make install clean

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

ENV MIX_ENV=prod

RUN mix local.hex --force && \
    mix local.rebar --force && \
    mix hex.info

WORKDIR /app
RUN mkdir config

COPY mix.exs mix.lock /app/
COPY config/config.exs config/prod.exs config/releases.exs /app/config/

# Must get deps before npm install becuase some javascript is inside some of
# the elixir packages
RUN mix do deps.get --only prod, deps.compile

WORKDIR /app/assets

COPY assets/package.json assets/package-lock.json /app/assets/

RUN npm install

COPY assets /app/assets/
RUN npm run deploy

WORKDIR /app

RUN mix phx.digest

COPY priv /app/priv/
COPY lib /app/lib/

RUN mix compile
RUN mix release

RUN tar -zcf /release.tar.gz -C /app/_build/prod/rel/ .

CMD /bin/bash
```