1
votes

I have a Dockerfile which builds an elixir project. Here, I compile both erlang and elixir from source. Afterwards I just run docker build --build-arg ... new-image . and it works without any errors. Please see below

FROM centos:8.2.2004

ARG APP_NAME
ARG APP_VSN
ARG MIX_ENV=prod

ENV APP_NAME=${APP_NAME} \
    APP_VSN=${APP_VSN} \
    MIX_ENV=${MIX_ENV}

RUN yum -y update
RUN yum -y upgrade
RUN yum -y install \
          nodejs \ 
          git \
          gcc gcc-c++ make \
          ncurses-devel \
          cmake \
          openssl-devel \
          autoconf \
          zip \
          bzip2 \
          readline-devel \
          jq \
          npm \
          && yum clean all

ENV ERLANG_VERSION=21.1.1
ENV ELIXIR_VERSION=1.8.2
ENV RUBY_VERSION=2.4.3
ENV ERL_AFLAGS="-kernel shell_history enabled"

ARG DISABLED_APPS='megaco wx debugger jinterface orber reltool observer et'
ARG ERLANG_TAG=OTP-${ERLANG_VERSION}
ARG ELIXIR_TAG=v${ELIXIR_VERSION}

LABEL erlang_version=$ERLANG_VERSION erlang_disabled_apps=$DISABLED_APPS elixir_version=$ELIXIR_VERSION ruby_version=$RUBY_VERSION

RUN yum update -y && yum clean all
RUN yum reinstall -y glibc-common && yum clean all

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en

RUN yum -y install glibc-locale-source glibc-langpack-en
RUN localedef -i en_US -f UTF-8 en_US.UTF-8

RUN locale

# Install Erlang
RUN set -xe \
    cd /tmp \
    && git clone --branch $ERLANG_TAG --depth=1 --single-branch https://github.com/erlang/otp.git \
    && cd otp \
    && echo "ERLANG_BUILD=$(git rev-parse HEAD)" >> /info.txt \
    && echo "ERLANG_VERSION=$(cat OTP_VERSION)" >> /info.txt  \
    && for lib in ${DISABLED_APPS} ; do touch lib/${lib}/SKIP ; done \
    && ./otp_build autoconf \
    && ./configure \
        --enable-smp-support \
        --enable-m64-build \
        --disable-native-libs \
        --enable-sctp \
        --enable-threads \
        --enable-kernel-poll \
        --disable-hipe \
    && make -j$(nproc) \
    && make install \
    && find /usr/local -name examples | xargs rm -rf \
    && ls -d /usr/local/lib/erlang/lib/*/src | xargs rm -rf \
    && rm -rf \
       /otp/* \
      /tmp/*

# Install Elixir
RUN cd /tmp \
    && git clone https://github.com/elixir-lang/elixir.git \
    && cd elixir

RUN git clone --branch $ELIXIR_TAG --depth=1 --single-branch https://github.com/elixir-lang/elixir.git \
    && cd elixir \
    && echo "ELIXIR_BUILD=$(git rev-parse HEAD)" >> /info.txt \
    && echo "ELIXIR_VERSION=$(cat VERSION)" >> /info.txt  \
    && make -j$(nproc) compile \
    && rm -rf .git \
    && make install \
    && cd / \
    && rm -rf \
      /tmp/*

RUN  mix local.rebar --force
RUN  mix local.hex --force

# This copies our app source code into the build container
COPY . .

RUN mix do deps.get, deps.compile, compile, phx.digest

RUN echo $MIX_ENV
RUN echo $APP_NAME
RUN echo $APP_VSN

RUN \
  mix release --verbose && \
  cp _build/${MIX_ENV}/rel/${APP_NAME}/releases/${APP_VSN}/${APP_NAME}.tar.gz ${APP_DIR} && \
  tar -xzf ${APP_NAME}.tar.gz && \
  rm ${APP_NAME}.tar.gz

The build completed successfully and a new image named new-image was created. Naturally, I want to re-use the new-image for other projects. So, I created a new Dockerfile, imported from new-image and removed the commands to build elixir and erlang. Figured it's alright since I've already compiled the binaries during the earlier build, so elixir and erlang binaries should already be present in the build right?. And the Dockerfile ends up like shown below

FROM new-image # created above

ARG APP_NAME
ARG APP_VSN
ARG MIX_ENV=prod

ENV APP_NAME=${APP_NAME} \
    APP_VSN=${APP_VSN} \
    MIX_ENV=${MIX_ENV}

RUN yum -y update
RUN yum -y upgrade
RUN yum -y install \
          nodejs \ 
          git \
          gcc gcc-c++ make \
          ncurses-devel \
          cmake \
          openssl-devel \
          autoconf \
          zip \
          bzip2 \
          readline-devel \
          jq \
          npm \
          && yum clean all

ENV ERLANG_VERSION=21.1.1
ENV ELIXIR_VERSION=1.8.2
ENV RUBY_VERSION=2.4.3
ENV ERL_AFLAGS="-kernel shell_history enabled"

ARG DISABLED_APPS='megaco wx debugger jinterface orber reltool observer et'
ARG ERLANG_TAG=OTP-${ERLANG_VERSION}
ARG ELIXIR_TAG=v${ELIXIR_VERSION}

LABEL erlang_version=$ERLANG_VERSION erlang_disabled_apps=$DISABLED_APPS elixir_version=$ELIXIR_VERSION ruby_version=$RUBY_VERSION

RUN yum update -y && yum clean all
RUN yum reinstall -y glibc-common && yum clean all

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en

RUN yum -y install glibc-locale-source glibc-langpack-en
RUN localedef -i en_US -f UTF-8 en_US.UTF-8

RUN locale

RUN  mix local.rebar --force
RUN  mix local.hex --force

# This copies our app source code into the build container
COPY . .

RUN mix do deps.get, deps.compile, compile, phx.digest

RUN echo $MIX_ENV
RUN echo $APP_NAME
RUN echo $APP_VSN

RUN \
  mix release --verbose && \
  cp _build/${MIX_ENV}/rel/${APP_NAME}/releases/${APP_VSN}/${APP_NAME}.tar.gz ${APP_DIR} && \
  tar -xzf ${APP_NAME}.tar.gz && \
  rm ${APP_NAME}.tar.gz

And when I build from it now, I get the following syntax error when cowboy is being compiled.

All dependencies are up to date
===> Compiling ranch
===> Compiling telemetry
===> Compiling cowlib
===> Compiling cowboy
Compiling 28 files (.ex)

== Compilation error in file lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex ==
** (SyntaxError) lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex:1: syntax error before: '='
    (elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
The command '/bin/sh -c mix do deps.get, deps.compile, compile, phx.digest' returned a non-zero code: 1

P.S. I don't have ruby 2.4.3 installed, don't understand why ruby is needed here. Also this is the first time I'm seeing an erlang project. So please go easy on me.

Edit: Adding the template file (lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex)

defmodule <%= module %>Channel do
  use <%= web_module %>, :channel

  def join("<%= singular %>:lobby", payload, socket) do
    if authorized?(payload) do
      {:ok, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end

  # Channels can be used in a request/response fashion
  # by sending replies to requests from the client
  
1
Can you post the first couple of lines of the file: lib/phoenix-1.4.1/priv/templates/phx.gen.channel/channel.ex7stud
@7stud Edited question as per your requestviprasant

1 Answers

1
votes

You are trying to compile a template file. A template file contains syntax that is not elixir. A template file has to be run through a preprocessor to remove the <%= ... %> tags and replace them with legal elixir syntax. See EEx in elixir. Basically, a file is a string, which can be run through the EEx engine to replace those tags with the return value of the elixir code contained inside those tags.