Adding Solid Docker Compose Recipes

The shadowing issue is only an issue if you run mix deps.get and mix compile in both the host and the container, otherwise is a non issue. If you run in both than you just need to map each folder in your root project and leave out the deps, _build and I think the assets/node_modules folders.

This is a completely different issue, and is nothing related with shadowing, instead it means you are missing the OS dependencies to build bccrypt in the container or if you are running mix commands in both the host and in the container, then it may cause issues, because bcrypt was compiled for a different target, but without seeing the exact error is hard to say.

To resume if you don’t run mix commands in both the container and host, shadowing is a non issue.

Docker Stack

Dockerfile

The Dockerfile now as non root user with the id 1000. Please read the comments in the Dockerfile to see if you need to customize this id for your computer.

ARG TAG=latest

FROM elixir:${TAG}

ARG PHOENIX_VERSION=1.4.16

RUN apt-get update && \

  ## install inotify-tool for phoenix hot reload
  apt-get install -y inotify-tools && \
  # DO THE SAME IN YOUR HOST MACHINE
  printf "fs.inotify.max_user_watches=524288\n" > /etc/sysctl.d/01-inotify.conf && \

  # install nodejs and npm on globaly
  curl -sL https://deb.nodesource.com/setup_14.x | bash - && \
  apt-get install -y -q nodejs && \

  # Add the user `developer` with id `1000`. Adjust `1000` to match the user in
  #  your host in order to avoid permissions issues between container and host.
  # To check user id in host, just run: `id -u`
  useradd -m -u 1000 -s /bin/bash developer && \
  su developer -c 'mkdir -p /home/developer/phoenix' && \

  # Install postgres client
  apt-get install -y postgresql-client && \
  # Clear apt cache
  rm -rf /var/lib/apt/lists/*

USER developer

RUN mix local.hex --force &&\
    mix local.rebar --force &&\
    mix archive.install hex phx_new ${PHOENIX_VERSION} --force

WORKDIR /home/developer/phoenix

CMD ["bash"]

You can now build any combination of Elixir and Phoenix version:

docker build --build-arg "TAG=1.10" --build-arg "PHOENIX_VERSION=1.5.1" -t phoenix:1.10_1.5.1 .

Docker Compose

I don’t have Elixir installed in my host, therefore I cannot test this docker compose file, but if I have not missed anything it will allow you to run mix commands from the host and container without causing issues:

# DONT USER VERSION £ UNLESS YOUR ARE USING DOCKER SWARM TO RUN THE CONTIANERS
version: '2.3'

services:
  db:
    image: postgres:9.6
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      PGDATA: /var/lib/postgresql/data/pgdata
    restart: always
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    ports:
      # IF POSTGRES IS ONLY USED BY THE PHOENIX SERVICE THEN YOU CAN REMOVE THIS PORT MAP
      # This is listening to requests coming from outside your computer:
      #- "5432:5432"
      # Localhost only
      - "127.0.0.1:5432:5432"
  phoenix:
    build: .
    volumes:
      - $PWD/assets/css:/home/developer/phoenix/assets/css
      - $PWD/assets/js:/home/developer/phoenix/assets/js
      - $PWD/assets/static:/home/developer/phoenix/assets/static
      - $PWD/assets/package.json:/home/developer/phoenix/assets/package.json
      - $PWD/assets/package-lock.json:/home/developer/phoenix/assets/package-lock.json
      - $PWD/assets/webpack.config.js:/home/developer/phoenix/assets/webpack.config.js
      - $PWD:/home/developer/phoenix/config
      - $PWD:/home/developer/phoenix/lib
      - $PWD:/home/developer/phoenix/priv
      - $PWD/mix.exs:/home/developer/phoenix/mix.exs
      - $PWD/mix.lock:/home/developer/phoenix/mix.lock
      - $PWD/.formatter.exs:/home/developer/phoenix/.formatter.exs
    
    # DONT KNOW WHAT IS DOING BUT PROBABLY YOU WANT TO ADJUST IT FOR THE NEW STACK.
    #command: ../phoenix-setup.sh
    command: mix phx.server
    environment:
      PGUSER: postgres
      PGPASSWORD: postgres
      PGDATABASE: portfolio
      PGPORT: 5432
      PGHOST: db
    ports:
      # Only visible to localhost, otherwise will be 0.0.0.0, meaning it will listen to requests coming from outsiide.
      - "127.0.0.1:4000:4000"
    depends_on:
      - db
volumes:
  pgdata: