Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mix deps compiled in Docker image need to be re-compiled when starting container #5130

Closed
hisapy opened this issue Aug 11, 2016 · 11 comments
Closed

Comments

@hisapy
Copy link

hisapy commented Aug 11, 2016

This might be a possible minor bug.

Environment

  • Elixir version (elixir -v): Elixir 1.3.1
  • Operating system: Ubuntu 16.04 (on a Docker container)

Current behavior

I have a Dockerfile with an instruction to compile Mix deps. Everything works fine when you build the Docker image. However the first time you start a container with the image and run mix phoenix.server or iex -S mix.phoenix.server everything compiles again. This process can take approximately 3 minutes. After this first compilation on the container, whenever you restart the container everything is compiled and working as expected.

Although the _build directory contains all the builds you would expect to be in there, the first time you start the container mix deps output is like the following:

* connection (Hex package) (mix)
  locked at 1.0.4 (connection) a1cae722
  the dependency build is outdated, please run "mix deps.compile"
* fs (Hex package) (rebar)
  locked at 0.9.2 (fs) ed17036c
  the dependency build is outdated, please run "mix deps.compile"
* gettext (Hex package) (mix)
  locked at 0.11.0 (gettext) 80c1dd42
  the dependency build is outdated, please run "mix deps.compile"
* absinthe (Hex package) (mix)
  locked at 1.1.8 (absinthe) b5563ca1
  the dependency build is outdated, please run "mix deps.compile"
* ranch (Hex package) (rebar)
  locked at 1.2.1 (ranch) a6fb992c
  the dependency build is outdated, please run "mix deps.compile"
* poolboy (Hex package) (rebar)
  locked at 1.5.1 (poolboy) 6b461639
  the dependency build is outdated, please run "mix deps.compile"
* decimal (Hex package) (mix)
  locked at 1.1.2 (decimal) 79a769d4
  the dependency build is outdated, please run "mix deps.compile"
* poison (Hex package) (mix)
  locked at 2.2.0 (poison) 4763b69a
  the dependency build is outdated, please run "mix deps.compile"
* db_connection (Hex package) (mix)
  locked at 1.0.0-rc.4 (db_connection) fad1f772
  the dependency build is outdated, please run "mix deps.compile"
* phoenix_pubsub (Hex package) (mix)
  locked at 1.0.0 (phoenix_pubsub) c31af4be
  the dependency build is outdated, please run "mix deps.compile"
* cowlib (Hex package) (rebar)
  locked at 1.0.2 (cowlib) 9d769a1d
  the dependency build is outdated, please run "mix deps.compile"
* cowboy (Hex package) (rebar)
  locked at 1.0.4 (cowboy) a324a8df
  the dependency build is outdated, please run "mix deps.compile"
* plug (Hex package) (mix)
  locked at 1.1.6 (plug) 8927e402
  the dependency build is outdated, please run "mix deps.compile"
* absinthe_plug (Hex package) (mix)
  locked at 1.1.3 (absinthe_plug) 6abd17e9
  the dependency build is outdated, please run "mix deps.compile"
* phoenix_html (Hex package) (mix)
  locked at 2.6.2 (phoenix_html) 944a5e58
  the dependency build is outdated, please run "mix deps.compile"
* phoenix (Hex package) (mix)
  locked at 1.2.0 (phoenix) 1bdeb99c
  the dependency build is outdated, please run "mix deps.compile"
* phoenix_live_reload (Hex package) (mix)
  locked at 1.0.5 (phoenix_live_reload) 829218c4
  the dependency build is outdated, please run "mix deps.compile"
* postgrex (Hex package) (mix)
  locked at 0.11.2 (postgrex) 139755c1
  the dependency build is outdated, please run "mix deps.compile"
* ecto (Hex package) (mix)
  locked at 2.0.2 (ecto) b02331c1
  the dependency build is outdated, please run "mix deps.compile"
* absinthe_relay (Hex package) (mix)
  locked at 0.9.4 (absinthe_relay) 72a59b7a
  the dependency build is outdated, please run "mix deps.compile"
* phoenix_ecto (Hex package) (mix)
  locked at 3.0.0 (phoenix_ecto) b947aaf0
  the dependency build is outdated, please run "mix deps.compile

Expected behavior

Based on the Dockerfile instructions, I expect deps to be properly compiled from the first time the container is started, thus mix deps output from the first time I get in the container should be:

* connection 1.0.4 (Hex package) (mix)
  locked at 1.0.4 (connection) a1cae722
  ok
* fs 0.9.1 (Hex package) (rebar)
  locked at 0.9.2 (fs) ed17036c
  ok
* gettext 0.11.0 (Hex package) (mix)
  locked at 0.11.0 (gettext) 80c1dd42
  ok
* absinthe 1.1.8 (Hex package) (mix)
  locked at 1.1.8 (absinthe) b5563ca1
  ok
* ranch 1.2.1 (Hex package) (rebar)
  locked at 1.2.1 (ranch) a6fb992c
  ok
* poolboy 1.5.1 (Hex package) (rebar)
  locked at 1.5.1 (poolboy) 6b461639
  ok
* decimal 1.1.2 (Hex package) (mix)
  locked at 1.1.2 (decimal) 79a769d4
  ok
* poison 2.2.0 (Hex package) (mix)
  locked at 2.2.0 (poison) 4763b69a
  ok
* db_connection 1.0.0-rc.4 (Hex package) (mix)
  locked at 1.0.0-rc.4 (db_connection) fad1f772
  ok
* phoenix_pubsub 1.0.0 (Hex package) (mix)
  locked at 1.0.0 (phoenix_pubsub) c31af4be
  ok
* cowlib 1.0.2 (Hex package) (rebar)
  locked at 1.0.2 (cowlib) 9d769a1d
  ok
* cowboy 1.0.4 (Hex package) (rebar)
  locked at 1.0.4 (cowboy) a324a8df
  ok
* plug 1.1.6 (Hex package) (mix)
  locked at 1.1.6 (plug) 8927e402
  ok
* absinthe_plug 1.1.3 (Hex package) (mix)
  locked at 1.1.3 (absinthe_plug) 6abd17e9
  ok
* phoenix_html 2.6.2 (Hex package) (mix)
  locked at 2.6.2 (phoenix_html) 944a5e58
  ok
* phoenix 1.2.0 (Hex package) (mix)
  locked at 1.2.0 (phoenix) 1bdeb99c
  ok
* phoenix_live_reload 1.0.5 (Hex package) (mix)
  locked at 1.0.5 (phoenix_live_reload) 829218c4
  ok
* postgrex 0.11.2 (Hex package) (mix)
  locked at 0.11.2 (postgrex) 139755c1
  ok
* ecto 2.0.2 (Hex package) (mix)
  locked at 2.0.2 (ecto) b02331c1
  ok
* absinthe_relay 0.9.4 (Hex package) (mix)
  locked at 0.9.4 (absinthe_relay) 72a59b7a
  ok
* phoenix_ecto 3.0.0 (Hex package) (mix)
  locked at 3.0.0 (phoenix_ecto) b947aaf0
  ok
@josevalim
Copy link
Member

I need more information to understand what is really happening. For example, does the machine where you built the software contains the same Elixir version that is inside Docker? Another option is that the Elixir compiler works on timestamps and maybe when creating the instance it sets all file timestamps to be the same?

@josevalim
Copy link
Member

Btw, it seems your docker instruction is using elixir v1.3.2 (the latest) and if elixir -v on your machine reported v1.3.1, that would explain the issue.

@hisapy
Copy link
Author

hisapy commented Aug 11, 2016

Hi Jose,

Obrigado for the quick response.

does the machine where you built the software contains the same Elixir version that is inside Docker?

I'm using Elixir entirely inside the container. When you build the image Elixir is installed from apt-get. Think of the container as a virtual machine image that you can boot and starts the same machine as it was when you created the image. So yes, the Elixir when compiling in the Dockerfile is the same as used when working with it inside a running container.

Another option is that the Elixir compiler works on timestamps and maybe when creating the instance it sets all file timestamps to be the same?

I also suspected it could be something related to compile time but I don't know where to start looking. The farthest I got was noticing all packages with the dependency build is outdated, please run "mix deps.compile" actually have their _build .

To be honest I started Elixir/Phoenix and letting go Ruby on Rails a couple of month ago. In Rails we have a base Docker image we use for our Rails projects with all the base gems we need already installed, built in the Dockerfile with:

COPY Gemfile Gemfile.lock $APP_HOME/
ENV BUNDLE_PATH=/home/app/bundle \
  BUNDLE_GEMFILE=$APP_HOME/Gemfile \
  BUNDLE_JOBS=2
RUN bundle install

When you start that Rails container you don't need to run bundle install again. That's the same effect we want to achieve with this Elixir based Docker image so we can help spreading Elixir to the world from Encarnación Paraguay :)

Is not critical but I'd just like to improve the UX when starting the app the first time. I'll appreciate any suggestions or ideas.

@josevalim
Copy link
Member

Ok, thank you for explaining. I have a very minimum Docker knowledge. :) Just to make sure I got it correctly: the project is compiled inside Docker but, when starting the container, it still asks for compiling. Is this correct?

Can you try running rm -rf deps/*/.fetch before starting the project and let me know if it fixes the issue?

@hisapy
Copy link
Author

hisapy commented Aug 11, 2016

Thanks again ... I'll try it right now

@hisapy
Copy link
Author

hisapy commented Aug 11, 2016

Thank you very much @josevalim ! ... It works ... I'll add rm -rf deps/*/.fetch to the Dockerfile right now. What a great community experience

@hisapy hisapy closed this as completed Aug 11, 2016
@josevalim
Copy link
Member

Glad to have helped @hisapy!

I have one last question though: can you print the mtime of the deps/*/.fetch files? It seems the bug is that those timestamps are being rewritten when building the container. Is there an option for this not to happen? This would be the ideal fix IMO.

@hisapy
Copy link
Author

hisapy commented Aug 11, 2016

Sorry for the delay @josevalim

I just came back and played a little with Iex tried a nice one liner but ended-up with:

IO.puts "--- list of deps ---"; {:ok, deps} = File.ls("deps"); Enum.each(deps, &(IO.puts &1)); IO.puts "--- deps stats ---"; Path.wildcard("deps/*/.fetch", match_dot: true) |> Enum.each(&(IO.puts List.first(Tuple.to_list System.cmd("stat", [&1]))))

# is there any shortcut to get the first element of a tuple ?

As you can see in the long output below, Change timestamp are set to the time the container was created. Apparently Access and Modify timestamp are still set to the creation time of the Docker image layer for the instruction mix deps.compile.

I don't know if that could be a problem and I'm not sure how to avoid the change in Change when starting the container.

For the moment I think we'll live with rm -rf deps/*/.fetch.

The long output is:

--- list of deps ---
absinthe_plug
phoenix_live_reload
fs
phoenix_ecto
phoenix_html
postgrex
db_connection
phoenix_pubsub
phoenix
ecto
absinthe
cowboy
absinthe_relay
ranch
poolboy
connection
gettext
cowlib
poison
decimal
plug
--- deps stats ---
  File: 'deps/absinthe/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 927738      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.029109810 +0000
 Birth: -

  File: 'deps/absinthe_plug/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 927991      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.119004047 +0000
 Birth: -

  File: 'deps/absinthe_relay/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928002      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.128992296 +0000
 Birth: -

  File: 'deps/connection/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928025      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.138980545 +0000
 Birth: -

  File: 'deps/cowboy/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928033      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.138980545 +0000
 Birth: -

  File: 'deps/cowlib/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928086      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.218886534 +0000
 Birth: -

  File: 'deps/db_connection/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928121      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.248851279 +0000
 Birth: -

  File: 'deps/decimal/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928154      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.268827777 +0000
 Birth: -

  File: 'deps/ecto/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 928161      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.278816025 +0000
 Birth: -

  File: 'deps/fs/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179161      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.358722014 +0000
 Birth: -

  File: 'deps/gettext/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179213      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.378698512 +0000
 Birth: -

  File: 'deps/phoenix/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179246      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.398675009 +0000
 Birth: -

  File: 'deps/phoenix_ecto/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179370      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.448616252 +0000
 Birth: -

  File: 'deps/phoenix_html/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179384      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.458604500 +0000
 Birth: -

  File: 'deps/phoenix_live_reload/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179410      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.468592749 +0000
 Birth: -

  File: 'deps/phoenix_pubsub/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179424      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.468592749 +0000
 Birth: -

  File: 'deps/plug/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179452      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.478580998 +0000
 Birth: -

  File: 'deps/poison/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179517      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.508545744 +0000
 Birth: -

  File: 'deps/poolboy/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179531      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.508545744 +0000
 Birth: -

  File: 'deps/postgrex/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179551      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.518533992 +0000
 Birth: -

  File: 'deps/ranch/.fetch'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fe01h/65025d    Inode: 179603      Links: 1
Access: (2644/-rw-r-Sr--)  Uid: ( 1000/     app)   Gid: (   50/   staff)
Access: 2016-07-29 20:53:30.000000000 +0000
Modify: 2016-07-29 20:53:30.000000000 +0000
Change: 2016-08-11 21:55:52.538510489 +0000
 Birth: -

:ok

My :calendar.local_time is 2016-08-11 21:58:36 but I started this container more than an hour ago.

@josevalim
Copy link
Member

Alright, thank you!

@rootkc
Copy link

rootkc commented Jan 8, 2020

I am having a similar issue. I am using CircleCI to run my tests. I have a BDD and a unit test suite. To not build the image twice i build it and then save the docker image to the workspace. Then in the unit and BDD test flow i do docker load to load the docker image from the workspace.
But even though i did compile the deps with MIX_ENV=test they still recompiles. I have tried rm -rf deps/*/.fetch as the last step in the Dockerfile with no luck.
I am using excoveralls for the unit tests and white-bread for the BDD tests.
Any ideas?

@rootkc
Copy link

rootkc commented Jan 8, 2020

My problem was the same as https://elixirforum.com/t/using-docker-to-container-phoenix-does-not-persist-the-dependencies/11652/2.
I was using my docker file in a docker-compose file where i had the following volumes:

      - .:/opt/app
      - /opt/app/apps/trackbit_web/assets/node_modules
      - /opt/app/deps

Adding the _build folder:

      - .:/opt/app
      - /opt/app/apps/trackbit_web/assets/node_modules
      - /opt/app/deps
      - /opt/app/_build

Solved the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants