<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sjuul Janssen</title>
    <description>The latest articles on DEV Community by Sjuul Janssen (@obeleh).</description>
    <link>https://dev.to/obeleh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F190922%2F6b63c77f-f242-49fd-aadb-a0f16bd775a3.jpeg</url>
      <title>DEV Community: Sjuul Janssen</title>
      <link>https://dev.to/obeleh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/obeleh"/>
    <language>en</language>
    <item>
      <title>Node version management in Docker containers</title>
      <dc:creator>Sjuul Janssen</dc:creator>
      <pubDate>Fri, 05 Jul 2019 15:04:10 +0000</pubDate>
      <link>https://dev.to/kabisasoftware/node-version-management-in-docker-containers-42c7</link>
      <guid>https://dev.to/kabisasoftware/node-version-management-in-docker-containers-42c7</guid>
      <description>&lt;p&gt;Recently I came across a solution to a Docker specific problem that I didn't know about and that I think is not used very often. Mainly because you shouldn't use it without knowing the implications. It can be a useful thing to know nonetheless.&lt;/p&gt;

&lt;p&gt;I was building containers for a client where the codebase for historical reasons uses a few different node versions. Being more of a backend / devops developer myself I hadn't really used &lt;code&gt;nvm&lt;/code&gt; before.&lt;/p&gt;

&lt;p&gt;Usually I would opt for using a Docker image &lt;code&gt;FROM node:&amp;lt;version_here&amp;gt;&lt;/code&gt; but the version in use (perhaps for good reason) isn't on Docker hub. And perhaps it's actually more maintainable if the Dockerfile uses the &lt;code&gt;.nvmrc&lt;/code&gt; file for determining which node version to use.&lt;/p&gt;

&lt;p&gt;Building this container appeared to be harder than I expected. This is because nvm uses environment variables that are declared in the profile. Which is quite logical because its a developer tool and you wouldn't want switching environments to have system-wide effects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current solutions
&lt;/h2&gt;

&lt;p&gt;The reason why I'm writing this post is because most of the answers out there are giving advise that feels just wrong. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# replace shell with bash so we can source files&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; /bin/sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash /bin/sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or hardcoding the node version in the Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_VERSION 4.4.7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you're using nvm instead of a Docker hub image it's better to use the &lt;code&gt;.nvmrc&lt;/code&gt; file in your folder as a single point where you document the used node version.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better solution?
&lt;/h2&gt;

&lt;p&gt;It was only after building a &lt;code&gt;rvm&lt;/code&gt; container that I came across this &lt;a href="https://stackoverflow.com/a/51803492"&gt;Stack Overflow Answer&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't use &lt;code&gt;RUN bash -l -c rvm install 2.3.3.&lt;/code&gt; It's very scruffy. You can set shell command by SHELL [ "/bin/bash", "-l", "-c" ] and simply call &lt;code&gt;RUN rvm install 2.3.3.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After this your Dockerfile gets a lot cleaner. But please note that you're doing something unusual here. With &lt;code&gt;-l&lt;/code&gt; you're asking for a "login shell". Which is not normally the case in a Docker container and it might have side-effects you didn't intend to. But that mostly depends on what you're doing. In most cases you're safe. And in my case I don't really mind because I was using multi stage builds in docker so the end result wasn't affected by this. And in case you were using this in a development container I think you're fine as well.&lt;/p&gt;

&lt;p&gt;So this is the Dockerfile I came up with. Note that I don't cleanup my apt file because it's an intermediate build step&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; debian&lt;/span&gt;

&lt;span class="k"&gt;SHELL&lt;/span&gt;&lt;span class="s"&gt; [ "/bin/bash", "-l", "-c" ]&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; curl
&lt;span class="k"&gt;RUN &lt;/span&gt;curl &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;-o-&lt;/span&gt; https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
&lt;span class="c"&gt;# this now works&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;nvm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; nvm use
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Please do note that this doesn't directly work in an Ubuntu container because the &lt;code&gt;/root/.bashrc&lt;/code&gt; file in Ubuntu contains this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# If not running interactively, don't do anything&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PS1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And it would then skip setting up the environment variables needed for nvm because in a non login shell &lt;code&gt;$PS1&lt;/code&gt; is not set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I do think that this solution is cleaner on more than one front. But of course I'm open for suggestions ;) &lt;br&gt;
I hope this saves others time and helps clean up those otherwise bloated Dockerfiles.&lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
