<?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>Forem: Teclado</title>
    <description>The latest articles on Forem by Teclado (@teclado).</description>
    <link>https://forem.com/teclado</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%2F415368%2F1013fc57-6931-4cdd-93fc-5b8daeb9c6b1.png</url>
      <title>Forem: Teclado</title>
      <link>https://forem.com/teclado</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/teclado"/>
    <language>en</language>
    <item>
      <title>Adding other services to a Docker container</title>
      <dc:creator>Teclado</dc:creator>
      <pubDate>Sun, 20 Nov 2022 13:32:21 +0000</pubDate>
      <link>https://forem.com/teclado/adding-other-services-to-a-docker-container-49fc</link>
      <guid>https://forem.com/teclado/adding-other-services-to-a-docker-container-49fc</guid>
      <description>&lt;p&gt;If you are about to dockerize a production-ready infrastructure in order to save server-related costs, you may find a problem with certain images that are enough complex to be a pain to override but does not fulfill your requeriments completly.&lt;/p&gt;

&lt;p&gt;In that case the common roadmap is to extend that image until you are comfortable with it. But, what if we want or need to add some other services? Simply overriding the &lt;code&gt;ENTRYPOINT&lt;/code&gt; layer is often both a risk and a pain too, and you would have to be aware of the changes in the original image. For that we can look after the existence of &lt;code&gt;supervisord&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Learning by example
&lt;/h1&gt;

&lt;p&gt;An example of this is the official &lt;em&gt;&lt;a href="https://github.com/docker-library/redmine/blob/cae991b96a33dbf0771dc73c5e145c9badc4c6c8/5.0/Dockerfile" rel="noopener noreferrer"&gt;Redmine&lt;/a&gt;&lt;/em&gt; image. This image serves by default the &lt;em&gt;Redmine&lt;/em&gt; app in the port &lt;code&gt;3000&lt;/code&gt; using &lt;code&gt;HTTP&lt;/code&gt;. But we want to use &lt;code&gt;HTTPS&lt;/code&gt; because we want to use it in a production environment! Then we need a &lt;code&gt;HTTP&lt;/code&gt; server acting as a proxy where we configure &lt;code&gt;HTTPS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Well, that's not an issue, we just extend the image in a &lt;code&gt;Dockerfile&lt;/code&gt; like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM redmine:5

RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y \
    nginx \
    apt-get clean &amp;amp;&amp;amp; \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY conf/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
EXPOSE 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Being &lt;code&gt;conf/default.conf&lt;/code&gt; the &lt;em&gt;Nginx&lt;/em&gt; config file, something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen       80;
    listen      [::]:80;
    server_name  redmine.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen      443 ssl;
    listen      [::]:443 ssl;
    server_name redmine.example.com;

    ssl_certificate     /path/to/certificate.crt;
    ssl_certificate_key /path/to/certificate.key;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, but that's not launching &lt;em&gt;Nginx&lt;/em&gt; at all yet. That's why we need &lt;code&gt;supervisord&lt;/code&gt;. If we inspect the &lt;em&gt;Redmine&lt;/em&gt; &lt;a href="https://github.com/docker-library/redmine/blob/cae991b96a33dbf0771dc73c5e145c9badc4c6c8/5.0/Dockerfile" rel="noopener noreferrer"&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/a&gt;, we can see the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WORKDIR /usr/src/redmine
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["rails", "server", "-b", "0.0.0.0"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thats all the information we need to configure &lt;code&gt;supervisord&lt;/code&gt; to launch &lt;em&gt;Redmine&lt;/em&gt;. But first, we need to install it. For that we edit our &lt;code&gt;Dockerfile&lt;/code&gt; so it finally remains like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM redmine:5

RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y \
    supervisor \
    nginx \
    apt-get clean &amp;amp;&amp;amp; \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY conf/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY conf/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
EXPOSE 443

ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have added the &lt;code&gt;supervisor&lt;/code&gt; package to the &lt;code&gt;apt-get install&lt;/code&gt; command, and the copy of the configuration file of it. As we want &lt;code&gt;supervisord&lt;/code&gt; to be our new entrypoint we added the last line too, passing the configuration file to the command.&lt;/p&gt;

&lt;p&gt;Then the &lt;code&gt;conf/supervisor.conf&lt;/code&gt; file will have to be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[supervisord]
nodaemon=true
user=root

[program:nginx]
user=root
command=nginx

[program:redmine]
user=redmine
directory=/usr/src/redmine
command=/docker-entrypoint.sh rails server -b 127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first section is the configuration of the supervisor daemon itself. We simply set the user to be root and indicate that it have to run in foreground with &lt;code&gt;nodaemon=true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the second section we just start &lt;em&gt;Nginx&lt;/em&gt; using the default configuration file (the one we copied in the &lt;code&gt;Dockerfile&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;With the last section we demand &lt;code&gt;supervisord&lt;/code&gt; to start &lt;em&gt;Redmine&lt;/em&gt;. First we change to the dir &lt;code&gt;/usr/src/redmine&lt;/code&gt;, as the &lt;em&gt;Redmine&lt;/em&gt; &lt;a href="https://github.com/docker-library/redmine/blob/cae991b96a33dbf0771dc73c5e145c9badc4c6c8/5.0/Dockerfile" rel="noopener noreferrer"&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/a&gt; states with the &lt;code&gt;WORKDIR&lt;/code&gt; layer. And we start the application linking the &lt;code&gt;ENTRYPOINT&lt;/code&gt; and the &lt;code&gt;CMD&lt;/code&gt; layers of the original &lt;a href="https://github.com/docker-library/redmine/blob/cae991b96a33dbf0771dc73c5e145c9badc4c6c8/5.0/Dockerfile" rel="noopener noreferrer"&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/a&gt;. We also change the &lt;code&gt;IP&lt;/code&gt; &lt;em&gt;Redmine&lt;/em&gt; will listen on to &lt;code&gt;127.0.0.1&lt;/code&gt; in order to avoid direct connections from outside the container.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We have tweaked a Docker image to fit the need of other services inside the same container without changing a word of the original image.&lt;/p&gt;

&lt;p&gt;You can see more about &lt;code&gt;supervisor&lt;/code&gt; in the &lt;a href="https://manpages.debian.org/testing/supervisor/supervisor.1.en.html" rel="noopener noreferrer"&gt;Debian man page&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Getting the precision for a float</title>
      <dc:creator>Teclado</dc:creator>
      <pubDate>Fri, 10 Jul 2020 19:46:28 +0000</pubDate>
      <link>https://forem.com/teclado/getting-the-precision-for-a-float-48fp</link>
      <guid>https://forem.com/teclado/getting-the-precision-for-a-float-48fp</guid>
      <description>&lt;p&gt;When using floating-point numbers, we're not used to think about the precision of theirs value. We only want a variable that can change in a continuous form, but we &lt;em&gt;never&lt;/em&gt; take into account that this variables don't take a continuous range of values due to their binary (and finite) representation.&lt;/p&gt;

&lt;p&gt;If we attend to the &lt;a href="https://en.wikipedia.org/wiki/IEEE_754"&gt;IEEE754&lt;/a&gt; specification, we can see the consensual meaning of each bit of this representation for each of the types we handle.&lt;/p&gt;

&lt;p&gt;There we see a space reserved to the sign and other for the exponent. That's ok, since they should be defined as integers. Is the mantissa which should be continuous, but due to its limited size, it's not. It behaves (with a fixed sign and exponent) just as an integer.&lt;/p&gt;

&lt;p&gt;Any scientist will agree with that if the floating-point number was matched up with other one (may be one with less precision) that would indicate a range containing the actual (and infinite precision) value of the number we're representing.&lt;/p&gt;

&lt;p&gt;However, this has been never implemented in the core logic of any computer, so we need to build it by ourselves.&lt;/p&gt;

&lt;p&gt;If we have after some calculations a final result, its least significant digit is never precise. This is because we had to round a real number to fit in a fixed length binary representation, so the error we get in the result is never less than the value of this bit (which changes as the exponent changes) divided by two.&lt;/p&gt;

&lt;p&gt;Here is an example of a little C code that get this error for a floating point number in a big-endian machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nf"&gt;errf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;nearest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vnp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cnp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;vnp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;cnp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fabsf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the rounding has been taken correctly, we might divide this by 2 and get a sensible result, but I'm in the doubt right now about this. In addition, if we're in a little-endian machine, we should flip the last byte, and not the first.&lt;/p&gt;

&lt;p&gt;This piece of code flips the least significant bit, getting the next faithfully representable number if this bit is a 0, and the previous one if it's a 1, in order to substract it from the provided value.&lt;/p&gt;

&lt;p&gt;We could get the manner of get both in each case, and subtract the previuos to the next, but the only difference appears when all bits in the mantissa are 0, so the previous representable number is nearer the value &lt;code&gt;x&lt;/code&gt; we're asking for. This means that we can always be sure the actual real (infinite precision again) value is somewhere between &lt;code&gt;x-errf(x)&lt;/code&gt; and &lt;code&gt;x+errf(x)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to comment other methods of getting this error, may be in other languages ;-D.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doing operations
&lt;/h3&gt;

&lt;p&gt;The trick with this topic is that if we want to operate with float values, we have to take this error into account. If we add up three times &lt;code&gt;0.5&lt;/code&gt;, which have an intrinsic error of &lt;code&gt;0.000000060&lt;/code&gt;, the errors add too, so we get a result of &lt;code&gt;1.50000000±0.00000018&lt;/code&gt;. All having a intrinsic one of &lt;code&gt;errf(1.5)=0.00000012&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Multiplication, division and subtraction have their own rules too. It was wonderful if we take this in account in each operation we do. When we do many of them as often happens, the accumulated error can grow pretty fast, and we should be prepared to discard a result when this one gets greater than some sensible limit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;p&gt;Cover image: &lt;a href="https://es.wikipedia.org/wiki/Archivo:Accuracy_(trueness_and_precision).svg"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>discuss</category>
      <category>healthydebate</category>
    </item>
  </channel>
</rss>
