egze
Hi,
I’m having trouble building a multi-stage Docker image for my app.
Here is my Dockerfile.base
FROM elixir:1.8-otp-22-alpine
ENV MIX_HOME=/opt/mix \
HEX_HOME=/opt/hex
WORKDIR /elixir
COPY mix.* ./
RUN mix local.hex --force && \
mix local.rebar --force && \
mix deps.get && \
mix deps.compile && \
mix compile
I built and pushed it to the registry.
Then here is Dockerfile
FROM registry.gitlab.com/username/project_name/base:latest as base
FROM elixir:1.8-otp-22-alpine
ENV MIX_HOME=/opt/mix \
HEX_HOME=/opt/hex
RUN apk --update --upgrade add inotify-tools bash postgresql-client \
&& update-ca-certificates --fresh \
&& rm -rf /var/cache/apk/*
WORKDIR /app
COPY . .
COPY --from=base /opt/mix /opt/mix
COPY --from=base /opt/hex /opt/hex
COPY --from=base /elixir/deps ./deps
COPY --from=base /elixir/_build ./_build
RUN mix deps.get \
&& mix deps.compile \
&& mix compile
It doesn’t fetch dependencies twice, this is good. But it tries to compile them again, and also fails at that.
Step 12/12 : RUN mix deps.get && mix deps.compile && mix compile
---> Running in 62fe07600112
Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
certifi 2.5.1
...
unicode_util_compat 0.4.1
All dependencies are up to date
===> Compiling parse_trans
===> Failed to restore /app/deps/parse_trans/.rebar3/erlcinfo file. Discarding it.
===> Compiling mimerl
===> Failed to restore /app/deps/mimerl/.rebar3/erlcinfo file. Discarding it.
...
What am I doing wrong? I thought it was enough to copy over the compiled deps from the base image.
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
Anyone here using Honeybadger?
My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of
Bandit.HTTPError...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #elixirconf-us
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
benwilson512
Usually if you are doing a multi stage build it works best to just go ahead and build a release in the base image and then you just copy that into the runtime image. Then the runtime image can be way smaller.
egze
This is for development. I’m not trying to build a release. The goal is that every team member can start the server or console as fast as possible.
akoutmos
I would suggest not going the multi-stage build route for local development. For releases it is definitely a good route to go down (and I also recently published a post on this recently here if you are interested: Multi-stage Docker Builds and Elixir 1.9 Releases-Alex Koutmos | Engineering Blog)
Given that your dependencies can/will change over time, maintaining a separate base image in my opinion will just lead to headaches across the team (people having out of date images, images needing to be updated every time there is a new dep/version, etc).
My current workflow (both for work and personal) is to have a docker-compose stack with my elixir service based on elixir:1.8.2 (or whatever version you are on), along with postgres and any other services i require. I then leverage named volumes (Compose file reference | Docker Docs) so that every time I spin the container up, all the deps/build stuff is persisted from the last time the container ran.
This way everyone on the team has the same container versions, no need to introduce any additional CI/CD steps for deploying new images to the registry and what not. It is also fast and productive. I can usually have my whole stack up and running locally in under a minute.
egze
Thanks, I will explore volumes for deps. Although my idea with multi stages was supposed to take care about deps and libs. It would compile them in base, but then still run mix deps.get and compile in the next stage when you start it. So if mix.exs hasn’t changed - nothing would be done. But if you added anything new, it would add and compile only that.
But regardless, now I’m just curious why copying deps from base image didn’t work.
akoutmos
Why even have a multistage build I guess is the question I have? Why not just base your container off of
FROM registry.gitlab.com/username/project_name/base:latest? Seems like an extra step of indirection which doesn’t net you anything.egze
That‘s a good point. Honestly, I don‘t remember now, tried a couple of strategies today. I‘ll try it a bit later tonight and report back.
cnck1387
Personally I use them in Phoenix (for development at least) for Webpack. I have a stage in my Dockerfile that does nothing but install Node and build assets. Then in a 2nd stage that sets up Elixir / Phoenix / mix, etc. I copy in the compiled assets into a folder.
Then I run a dedicated
webpackservice in Docker Compose but only in development (using an override file).Haven’t deployed anything yet but I imagine once I tackle that, I’ll end up moving the webpack stage to nginx and also set up a 2nd stage for Elixir releases to base as my final prod image.
akoutmos
That comment was aimed more at the OPs code sample where they used the registry image as a base, and then immediatly started the next stage:
For your case that sounds like a good solution as installing node+elixir in the same container can be annoying to do. When doing frontend work, I usually have 2 containers running, 1 for Elixir app and 1 for the JS app. Each container will then have read only access to the host filesystem (to the files that are relevant for each) and then kick off rebuilds as files change. At that point it is only a matter of setting up CORS correctly on the Phoenix app and my Vue SPA can communicate with my Phoenix API.
NobbZ
And because of that you make them install docker? Instead of just to teach them how to use
mix? Perhapsasdfas well?egze
That’s just how we like to develop, everything in docker containers. Nothing wrong with that.