<?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: Samuel O'Daniels</title>
    <description>The latest articles on DEV Community by Samuel O'Daniels (@samuelodan).</description>
    <link>https://dev.to/samuelodan</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%2F820060%2F7209a65e-ab7b-41e2-b5b9-d995a2124049.jpeg</url>
      <title>DEV Community: Samuel O'Daniels</title>
      <link>https://dev.to/samuelodan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samuelodan"/>
    <language>en</language>
    <item>
      <title>Interesting JavaScript Features from a Ruby Perspective</title>
      <dc:creator>Samuel O'Daniels</dc:creator>
      <pubDate>Sat, 10 Jun 2023 22:05:06 +0000</pubDate>
      <link>https://dev.to/samuelodan/interesting-javascript-features-from-a-ruby-perspective-k2e</link>
      <guid>https://dev.to/samuelodan/interesting-javascript-features-from-a-ruby-perspective-k2e</guid>
      <description>&lt;p&gt;Hi there. I recently began relearning JavaScript, as it had been a year since I last did anything meaningful with it. So, I thought to share some of the differences that stood out to me as a Ruby developer. There should be a part 2, so you might want to watch out for that if you find this one entertaining.&lt;br&gt;
Enough said. Let's jump right to the first difference.&lt;/p&gt;
&lt;h2&gt;
  
  
  No Error for Calling an Undefined Property
&lt;/h2&gt;

&lt;p&gt;This tripped me up at first, but what's really happening is that classes in JavaScript are basically templates for creating Objects (hashes in Ruby). So, what looks like a "method" call (if you're coming from Ruby) is actually just accessing the property, including accessor properties like getters and setters, using dot notation. JS methods still need the &lt;code&gt;()&lt;/code&gt; to be invoked.&lt;br&gt;
Whereas in Ruby, any information you want from an object must be gotten through a method call. I'll attempt an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JavaScript Class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;codeName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You know who&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;regularName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unknown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DemoClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;codeName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; You know who&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;codeName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// using brackets&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; You know who&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we can see that &lt;code&gt;target&lt;/code&gt; is just a regular object (hash), and as a result, its properties can also be accessed using bracket notation, just like a hash in Ruby.&lt;/p&gt;

&lt;p&gt;To access the same property in Ruby, we'll have to define a getter method that returns that property when called. &lt;code&gt;target&lt;/code&gt; will be an instance of a real class, not a hash, so bracket notation won't work here. Also, I think referring to hashes as "objects" in JavaScript is just confusing, lol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional Chaining
&lt;/h2&gt;

&lt;p&gt;This dot notation for properties in JavaScript objects also affects the use of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining" rel="noopener noreferrer"&gt;optional chaining&lt;/a&gt; (&lt;a href="https://ruby-doc.org/core-2.6/doc/syntax/calling_methods_rdoc.html#label-Safe+navigation+operator" rel="noopener noreferrer"&gt;safe navigation&lt;/a&gt; in Ruby) because, depending on the usage, you will need less of the operator compared to Ruby.&lt;br&gt;
Let's look at an example.&lt;br&gt;
Say we have a user who, unbeknownst to us, doesn't have a &lt;code&gt;currentAccount&lt;/code&gt; property, and we want to safely check their current account balance; this is how we can do that in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ?. is the optional chaining operator in JS&lt;/span&gt;
&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentAccount&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# &amp;amp;. is the safe navigation operator in Ruby&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current_account&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balance&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we had to use the operator twice in Ruby to avoid an error in case &lt;code&gt;current_account&lt;/code&gt; was not a valid/defined method for the &lt;code&gt;user&lt;/code&gt; object. &lt;/p&gt;

&lt;p&gt;There's another difference when it comes to safely calling functions or methods. With JavaScript, &lt;code&gt;?.&lt;/code&gt; is placed between the function name and the parenthesis like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// supposing 'name' is undefined or null&lt;/span&gt;
&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;?.();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Ruby, the use appears more straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;
&lt;span class="c1"&gt;# even if you use parenthesis&lt;/span&gt;
&lt;span class="c1"&gt;# which you shouldn't use without arguments&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: While testing the code examples for this section and the one before it, I made the mistake of "calling" JS functions as if they were properties. This created a hole in my understanding, causing me to make an inaccurate claim. Thankfully, u/jrochkind pointed it out on Reddit, so I made modifications to clarify the affected sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing the Last Array Element
&lt;/h2&gt;

&lt;p&gt;If you're coming from Ruby, you may instinctively try &lt;code&gt;array[-1]&lt;/code&gt;, but it'll return &lt;code&gt;undefined&lt;/code&gt;. So, to actually get the last element in a JS array, you have to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="c1"&gt;// or less preferably&lt;/span&gt;
&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;slice&lt;/code&gt; this way looks hacky, and you wouldn't be able to modify the element in place since it returns a new array.&lt;/p&gt;

&lt;p&gt;With Ruby, however, you simply do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# or to modify the element:&lt;/span&gt;
&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'new last element'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Incrementing Numbers
&lt;/h2&gt;

&lt;p&gt;Javascript has an increment (&lt;code&gt;++&lt;/code&gt;)  operator that you can use instead of doing something like &lt;code&gt;num += 1&lt;/code&gt; or &lt;code&gt;num = num + 1&lt;/code&gt;.&lt;br&gt;
However, Ruby does not have such an operator, so you have to use &lt;code&gt;num += 1&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Function Parameters are Optional by Default
&lt;/h2&gt;

&lt;p&gt;In JavaScript, missing arguments become &lt;code&gt;undefined&lt;/code&gt; instead of raising an exception. Ruby, however, will raise an &lt;code&gt;ArgumentError&lt;/code&gt;. Let's look at an example.&lt;br&gt;
In JavaScript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// passing only one argument instead of two&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Good &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;morning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Good morning, undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time_of_day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s2"&gt;"Good &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;time_of_day&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'morning'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; wrong number of arguments (given 1, expected 2) (ArgumentError)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  No &lt;code&gt;none()&lt;/code&gt; Even Though There's &lt;code&gt;every()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;JavaScript Arrays have &lt;code&gt;every()&lt;/code&gt; and &lt;code&gt;some()&lt;/code&gt; predicate methods, just like &lt;code&gt;Array#all?&lt;/code&gt; and &lt;code&gt;Array#any?&lt;/code&gt; in Ruby, but unlike JavaScript, Ruby Arrays have a &lt;code&gt;#none?&lt;/code&gt; method, which is the opposite of &lt;code&gt;#any?&lt;/code&gt;.&lt;br&gt;
You might achieve a similar effect in JavaScript by either defining a &lt;code&gt;none()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;none&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// and use it like so&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;none&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or simply negating the call like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Ruby though, you write the same logic this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;none?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Array.forEach() returns undefined
&lt;/h2&gt;

&lt;p&gt;This might seem intuitive, and it probably is, but in Ruby, &lt;code&gt;Array#each&lt;/code&gt; returns &lt;code&gt;self&lt;/code&gt;, which is the object the method was called on. Here's an example.&lt;br&gt;
In JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// result =&amp;gt; undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# result =&amp;gt; ['a', 'b', 'c']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright. That's the last one. I hope you found these rather interesting or insightful. Thanks for reading.&lt;br&gt;
Until next time.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ruby</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Upgrading Old Versions of Dokku</title>
      <dc:creator>Samuel O'Daniels</dc:creator>
      <pubDate>Tue, 30 May 2023 15:02:33 +0000</pubDate>
      <link>https://dev.to/samuelodan/upgrading-old-version-of-dokku-1hda</link>
      <guid>https://dev.to/samuelodan/upgrading-old-version-of-dokku-1hda</guid>
      <description>&lt;p&gt;Hi there. I originally planned to include this set of instructions as part of another article, but it was getting long. So I decided to make it into its own post. That said, let's jump right in.&lt;/p&gt;

&lt;p&gt;If Dokku was automatically included for you through the Digital Ocean (DO) 1-Click Droplet, chances are you're running an inexcusably old version of the tool; version &lt;code&gt;0.21.4&lt;/code&gt; specifically. It works fine for the most part, but there have since been dozens of releases with numerous improvements. The one improvement I'm particularly interested in is &lt;a href="https://www.pair.com/support/kb/configuring-cron/" rel="noopener noreferrer"&gt;Cron&lt;/a&gt; support, because Dokku's Let's Encrypt plugin needs it to schedule cronjobs (tasks) for automatically renewing SSL certificates.&lt;/p&gt;

&lt;p&gt;I spoke with the project's maintainer, and he &lt;a href="https://github.com/digitalocean/droplet-1-clicks/pull/118" rel="noopener noreferrer"&gt;submitted a PR&lt;/a&gt; to update DO's Droplet to use the latest version (&lt;code&gt;0.30.6&lt;/code&gt;). He's also interested in automating the releases, so this shouldn't be an issue in the future. But in the meantime, we'll have to upgrade our versions ourselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confirm The Version You've Got Installed
&lt;/h3&gt;

&lt;p&gt;The upgrade path is dependent on the current version. Check it by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it's below &lt;code&gt;0.25.x&lt;/code&gt;, you'll have to first upgrade to &lt;code&gt;0.29.x&lt;/code&gt; before &lt;code&gt;0.30.x&lt;/code&gt; to avoid a breaking change. Conversely, you can go straight to the latest if you have a higher version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upgrade to Version 0.29.4
&lt;/h3&gt;

&lt;p&gt;Stop all your running apps first using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# for 0.22.0 and newer versions, use&lt;/span&gt;
dokku ps:stop &lt;span class="nt"&gt;--all&lt;/span&gt;

&lt;span class="c"&gt;# for versions between 0.11.4 and 0.21.4, use&lt;/span&gt;
dokku ps:stopall

&lt;span class="c"&gt;# for versions between 0.8.1 and 0.11.3, use&lt;/span&gt;
dokku &lt;span class="nt"&gt;--quiet&lt;/span&gt; apps:list | xargs &lt;span class="nt"&gt;-L1&lt;/span&gt; dokku ps:stop

&lt;span class="c"&gt;# for versions versions older than 0.8.1, use&lt;/span&gt;
dokku &lt;span class="nt"&gt;--quiet&lt;/span&gt; apps | xargs &lt;span class="nt"&gt;-L1&lt;/span&gt; dokku ps:stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run these two commands to upgrade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# run the three commands one after the other&lt;/span&gt;
&lt;span class="nb"&gt;rm &lt;/span&gt;bootstrap.sh
wget https://raw.githubusercontent.com/dokku/dokku/v0.29.4/bootstrap.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;&lt;span class="nv"&gt;DOKKU_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v0.29.4 bash bootstrap.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Upgrade to Version 0.30.6
&lt;/h3&gt;

&lt;p&gt;Next, we'll upgrade to the latest version at the time of writing this article.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# run the three commands one after the other&lt;/span&gt;
&lt;span class="nb"&gt;rm &lt;/span&gt;bootstrap.sh
wget &lt;span class="nt"&gt;-NP&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; https://dokku.com/install/v0.30.6/bootstrap.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;&lt;span class="nv"&gt;DOKKU_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v0.30.6 bash bootstrap.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the new version by running &lt;code&gt;dokku version&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Restart Apps
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku ps:start &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. You're now on the latest version. If you visit this page in the future, you can find all the latest releases and their respective upgrade commands &lt;a href="https://github.com/dokku/dokku/releases" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;br&gt;
Till next time!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>paas</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Adding a Domain and SSL Certificate to Your Dokku App</title>
      <dc:creator>Samuel O'Daniels</dc:creator>
      <pubDate>Tue, 30 May 2023 14:56:35 +0000</pubDate>
      <link>https://dev.to/samuelodan/adding-a-domain-and-ssl-certificate-to-your-dokku-app-20oc</link>
      <guid>https://dev.to/samuelodan/adding-a-domain-and-ssl-certificate-to-your-dokku-app-20oc</guid>
      <description>&lt;p&gt;In a previous article, we looked at how to host Rails apps on DigitalOcean with Dokku. But we used an IP address as the domain, and while that works all right, you'll need a domain you've bought if you want your app URLs to look professional. A domain name is also required for SSL, as certificate authorities like &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt; will not issue certs to IP addresses. &lt;/p&gt;

&lt;p&gt;So, just as the title suggests, we'll add a domain and SSL cert to your app in the following steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Yet Deployed Your App?
&lt;/h2&gt;

&lt;p&gt;No problem. Open &lt;a href="https://dev.to/samuelodan/how-to-deploy-your-rails-app-to-a-digitalocean-droplet-using-dokku-eh7"&gt;the deployment article&lt;/a&gt; in a separate tab and return when you're done deploying to DigitalOcean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Already Deployed Your App?
&lt;/h2&gt;

&lt;p&gt;If you're using an IP address as the hostname, you'll have to add domains for Dokku.&lt;/p&gt;

&lt;p&gt;Confirm by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# assuming app-name is 'ruby-getting-started'&lt;/span&gt;
&lt;span class="c"&gt;# look at the value for 'Domains app vhosts:' in the output&lt;/span&gt;
dokku domains:report ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it's blank and &lt;code&gt;Domain app enabled&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, run the following domain commands. Otherwise, skip to the DNS Section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Global Domain
&lt;/h3&gt;

&lt;p&gt;Run the following command to add your domain as the global domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku domains:add-global &amp;lt;example.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add App Domain
&lt;/h3&gt;

&lt;p&gt;Run the following to add the domain to the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# assuming 'ruby-getting-started' is your app's name&lt;/span&gt;
dokku domains:add &amp;lt;ruby-getting-started&amp;gt; &amp;lt;ruby-getting-started.example.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will also configure the server to use the vhost to access the app.&lt;/p&gt;

&lt;p&gt;You can confirm the domain of your app by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# assuming app-name is 'ruby-getting-started'&lt;/span&gt;
&lt;span class="c"&gt;# look at the value for 'domains app vhosts:' in the output&lt;/span&gt;
dokku domains:report ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All right! Let's proceed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a DNS Record
&lt;/h2&gt;

&lt;p&gt;Now that your app has been properly configured, you have to map your domain (or subdomain, in this case) to the IP address of your Dokku Droplet server.&lt;br&gt;
I use NameCheap, but you can search for "how to add DNS record in &amp;lt;insert-your-domain-name-registrar" on Google.&lt;br&gt;
It generally goes like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to the dashboard of your domain name registrar and go to the advanced DNS settings for the domain you used earlier.&lt;/li&gt;
&lt;li&gt;Add an &lt;code&gt;A&lt;/code&gt; record with &lt;code&gt;*&lt;/code&gt; as &lt;code&gt;Host&lt;/code&gt; to catch all subdomains (&lt;code&gt;*.example.com&lt;/code&gt;), and give it a &lt;code&gt;value&lt;/code&gt; of your Droplet IP address. Set the TTL to &lt;code&gt;automatic&lt;/code&gt; or 30 minutes and save the record.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the table below for reference.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;'A' Record&lt;/td&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;123.111.22.3&lt;/td&gt;
&lt;td&gt;Automatic or 30 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Your &lt;code&gt;ruby-getting-started.example.com&lt;/code&gt; domain should be functional after a minute or so.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding SSL
&lt;/h2&gt;

&lt;p&gt;We'll be using &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt; because they provide free certificates, and there's an official Dokku plugin.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install the dokku-letsencrypt plugin
&lt;/h3&gt;

&lt;p&gt;run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set Global Let'sEncrypt Email
&lt;/h3&gt;

&lt;p&gt;The plugin needs it to send you email reminders when certificates are about to expire. They expire in 90 days, but we'll address that soon.&lt;br&gt;
Run this command to set the email globally so you don't have to do it on a per-app basis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku letsencrypt:set &lt;span class="nt"&gt;--global&lt;/span&gt; email &amp;lt;your@email.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enable Let's Encrypt for Your App
&lt;/h3&gt;

&lt;p&gt;The command below will generate a certificate for your app's domain and configure the webserver to work with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku letsencrypt:enable ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload your app's URL, and you should see a new security status symbol in the browser. Nice!&lt;/p&gt;

&lt;h2&gt;
  
  
  One More Thing
&lt;/h2&gt;

&lt;p&gt;This certificate expires every 90 days, but thankfully, we don't have to always remember to update it. The dokku-letsencrypt plugin provides an option automatically update certicates that are due across all apps. &lt;/p&gt;

&lt;h3&gt;
  
  
  We May Have To Upgrade Dokku For This Part
&lt;/h3&gt;

&lt;p&gt;The version of Dokku (&lt;code&gt;0.21.4&lt;/code&gt;) currently installed on the 1-Click Droplet is very old and doesn't support Cron. I spoke with the project's maintainer, and he has &lt;a href="https://github.com/digitalocean/droplet-1-clicks/pull/118" rel="noopener noreferrer"&gt;submitted a PR&lt;/a&gt; to update it to the latest version (&lt;code&gt;0.30.6&lt;/code&gt;). &lt;br&gt;
To keep this section from getting too long, I've moved the upgrade guide to a separate article.&lt;/p&gt;

&lt;p&gt;So, check your version by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it's below &lt;code&gt;0.3.x&lt;/code&gt;, upgrade your dokku install using &lt;a href="https://dev.to/samuelodan/upgrading-old-version-of-dokku-1hda#confirm-the-version-youve-got-installed"&gt;the upgrade guide&lt;/a&gt;; otherwise, proceed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Automatic Certificate Renewal
&lt;/h3&gt;

&lt;p&gt;Run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku letsencrypt:cron-job &lt;span class="nt"&gt;--add&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see an output 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;root@dokku-demo-dp:~# dokku letsencrypt:cron-job --add
-----&amp;gt; Updated schedule file
-----&amp;gt; Added cron job to dokku's crontab.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well done! Your site is now safe to use, and users will no longer get a warning from their browsers when they visit.&lt;br&gt;
Thanks for reading. Until next time!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>paas</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to Take Advantage of the GitHub Student Developer Pack</title>
      <dc:creator>Samuel O'Daniels</dc:creator>
      <pubDate>Fri, 12 May 2023 17:44:38 +0000</pubDate>
      <link>https://dev.to/samuelodan/how-to-take-advantage-of-the-github-student-developer-pack-1d2f</link>
      <guid>https://dev.to/samuelodan/how-to-take-advantage-of-the-github-student-developer-pack-1d2f</guid>
      <description>&lt;p&gt;Nearly a decade ago, GitHub launched their Student Developer Pack. A valuable initiative to provide students with access to essential tools and high-quality paid resources to enhance their learning experience. If you're a student, this article aims to help you maximize the benefits offered through the program, ensuring you make the most of the available opportunities.&lt;/p&gt;

&lt;p&gt;To access the offers available, start by visiting &lt;a href="https://education.github.com/pack" rel="noopener noreferrer"&gt;this page&lt;/a&gt;. Click on the register button and then click "get student benefits" to sign up for the pack. Verification requires your student email to confirm the message sent by GitHub. Once verified, you'll be able to access over 80 offers on the site.&lt;/p&gt;

&lt;p&gt;While this article may mention Ruby or JavaScript, the resources cover many mainstream languages and stacks. So, without further ado, here's a curated list of standout offers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Educative.io
&lt;/h3&gt;

&lt;p&gt;With their offer, you get access to 60+ written programming courses on &lt;a href="https://www.educative.io/" rel="noopener noreferrer"&gt;Educative.io&lt;/a&gt; for free. It used to be their entire library a few years ago, but you still get good courses despite the limited amount.&lt;/p&gt;

&lt;p&gt;One piece of advice, though, especially if you're brand new to coding, is that it is beneficial to learn to set up your dev environment, and you won't learn that with Educative.io, as they have you code in their embedded IDE right there in the browser.&lt;br&gt;
But you'll find great value in the courses once you account for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  GoRails
&lt;/h3&gt;

&lt;p&gt;A good way to learn to code is by reading and writing a lot of code. And &lt;a href="https://gorails.com/" rel="noopener noreferrer"&gt;GoRails&lt;/a&gt; helps you on the reading front, as you're essentially watching somebody build software. You'll notice certain interesting decisions and patterns, which can become options for you when building your own software. &lt;br&gt;
GoRails has a lot of videos covering various aspects of &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Rails&lt;/a&gt;, and you get 12 months free plus an invite to their private Discord server.&lt;/p&gt;

&lt;h3&gt;
  
  
  DigitalOcean
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;Digital Ocean&lt;/a&gt; is a simple cloud hosting platform built for developers. I recently &lt;a href="https://dev.to/samuelodan/how-to-deploy-your-rails-app-to-a-digitalocean-droplet-using-dokku-eh7"&gt;wrote a guide&lt;/a&gt; on how to host your Rails apps on there. &lt;br&gt;
Once you claim your offer, you get $200 of free credit for a year, which should be enough to cover your hosting needs throughout its validity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Namecheap and Name.com
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.namecheap.com/" rel="noopener noreferrer"&gt;Namecheap&lt;/a&gt; and &lt;a href="https://www.name.com/" rel="noopener noreferrer"&gt;Name.com&lt;/a&gt; are big-name domain registrars, and in partnership with GitHub, they each offer one free domain name registration and a free SSL certificate.&lt;/p&gt;

&lt;h3&gt;
  
  
  JetBrains
&lt;/h3&gt;

&lt;p&gt;You've probably heard of IntelliJ. It's one of the most popular IDEs (not just among Java devs), and it was made by &lt;a href="https://www.jetbrains.com/" rel="noopener noreferrer"&gt;JetBrains&lt;/a&gt;. They have Development tools for whatever technology or platform you use, and their offer grants you access to all their IDEs (Including RubyMine and Webstorm) while you're a student.&lt;br&gt;
Fun fact: they are the creators of the Kotlin programming language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend Masters
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://frontendmasters.com/" rel="noopener noreferrer"&gt;Frontend Masters&lt;/a&gt; has over 150 high-quality video courses from renowned Devs, including &lt;a href="https://twitter.com/sarah_edo" rel="noopener noreferrer"&gt;Sarah Drasner&lt;/a&gt;, &lt;a href="https://www.google.com/search?q=kyle+simpson&amp;amp;oq=kyle+sim&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;Kyle Simpson &lt;/a&gt; (author of You Don’t Know JS), &lt;a href="https://twitter.com/holtbt" rel="noopener noreferrer"&gt;Brian Holt&lt;/a&gt;, and &lt;a href="https://twitter.com/ThePrimeagen" rel="noopener noreferrer"&gt;ThePrimeagen&lt;/a&gt; (the Vim evangelist, haha!).&lt;br&gt;
You get all their courses for 6 months. Glad they haven’t nerfed their offer. &lt;/p&gt;

&lt;p&gt;Despite what the name suggests, Frontend Masters also covers backend web development, DevOps, Linux &amp;amp; the command line, Machine Learning, Computer Science, Vim, and mobile app development. &lt;/p&gt;

&lt;h3&gt;
  
  
  Icons8
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://icons8.com/" rel="noopener noreferrer"&gt;Icons8&lt;/a&gt; provides photo, illustration, icon, and music assets for designers, and their offer nets you a 3-month, all-access subscription.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://replit.com/" rel="noopener noreferrer"&gt;Replit&lt;/a&gt; is an online integrated development environment (IDE) that allows users to write, compile, and run code in various programming languages directly from their web browser. It provides a collaborative coding platform where multiple users can simultaneously work on the same project.&lt;/p&gt;

&lt;p&gt;Their offer grants you private repls for 6 months.&lt;br&gt;
If you want to see what your programs can look like on there, &lt;a href="https://replit.com/@Samuelodan/chesscli" rel="noopener noreferrer"&gt;here&lt;/a&gt; is a chess game I wrote and hosted there last year. Although it's a CLI app, you can also run simple web apps there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interview Cake
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.interviewcake.com/" rel="noopener noreferrer"&gt;Interview Cake&lt;/a&gt; is an online platform that offers resources and guidance for coding interviews, particularly for software engineering and technical roles. It provides a structured curriculum and practice materials to help individuals prepare for technical interviews at top tech companies.&lt;/p&gt;

&lt;p&gt;It's pricey, but I've heard good things about it. You can get 3 weeks of access for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dashlane
&lt;/h3&gt;

&lt;p&gt;&lt;a href=""&gt;Dashlane&lt;/a&gt; is a top-rated password manager with loads of features. Here's an &lt;a href="https://www.pcmag.com/reviews/dashlane" rel="noopener noreferrer"&gt;excellent review&lt;/a&gt; from PCMag&lt;br&gt;
You can get 6 months of premium. Okay, that's not entirely true. You get all the premium features except the VPN, but it's good value nonetheless.&lt;/p&gt;

&lt;h3&gt;
  
  
  1Password
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://1password.com/" rel="noopener noreferrer"&gt;1Password&lt;/a&gt; is another popular password manager. I haven't used this one, but many people swear by it, so I'll include it. &lt;br&gt;
You get 1 whole year of free access. Here's &lt;a href="https://www.pcmag.com/reviews/agilebits-1password" rel="noopener noreferrer"&gt;a review&lt;/a&gt; for good measure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mailgun
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.mailgun.com/" rel="noopener noreferrer"&gt;Mailgun&lt;/a&gt; is a cloud-based email service provider that offers email delivery and management solutions for businesses and developers. It provides a set of APIs that allow users to send, receive, and track email messages effortlessly.&lt;br&gt;
You get 20,000 free emails and 100 free email validations each month for up to 12 months.&lt;/p&gt;

&lt;p&gt;Phew! That's the last one.&lt;/p&gt;

&lt;p&gt;Most of these services are worth the money, even if you're not a student. So, consider checking them out.&lt;/p&gt;

&lt;p&gt;Alright! That's been it from me. If you think an offer should've made the list, let me know in the comments below.&lt;br&gt;
Thanks for reading.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>github</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How To Deploy Your Rails App to a DigitalOcean Droplet Using Dokku</title>
      <dc:creator>Samuel O'Daniels</dc:creator>
      <pubDate>Mon, 01 May 2023 01:26:32 +0000</pubDate>
      <link>https://dev.to/samuelodan/how-to-deploy-your-rails-app-to-a-digitalocean-droplet-using-dokku-eh7</link>
      <guid>https://dev.to/samuelodan/how-to-deploy-your-rails-app-to-a-digitalocean-droplet-using-dokku-eh7</guid>
      <description>&lt;p&gt;Hi there, you're probably searching for a simple and cost-effective way to deploy your Rails app, especially now that Heroku no longer offers its free plan. Well, look no further. Dokku is an open-source Heroku alternative that simplifies deploying and managing our apps on a server. Combine that with DigitalOcean's affordable Droplets, and you've got an attractive solution. &lt;/p&gt;

&lt;p&gt;For reference, you can deploy and run about three simple apps on one $6 droplet, but that's only about half the cost of hosting one app on Heroku with a database and caching. Moreover, unlike a Droplet, the Heroku server will sleep when it's not been accessed for a while. This is not to say that Heroku is overpriced. They do a lot of the work for you and charge more for the convenience.&lt;/p&gt;

&lt;p&gt;Alright, before we proceed, what are "Droplets"? They are DigitalOcean's Linux-based virtual machines. When you create one, it becomes a server for your app(s).&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Droplet
&lt;/h2&gt;

&lt;p&gt;First, you need to &lt;a href="https://cloud.digitalocean.com/registrations/new" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; on DigitalOcean.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next, head to the &lt;a href="https://marketplace.digitalocean.com/apps/dokku" rel="noopener noreferrer"&gt;Dokku Droplet page&lt;/a&gt; and click the "Create Dokku Droplet" button to create a droplet with Dokku preinstalled. Note that if you create a regular droplet, you'll have to install Dokku manually, and more configuration will be required.&lt;/li&gt;
&lt;li&gt;Select a region closest to you or your userbase on the create page for best performance. Select the "Basic" option and choose the $6/month plan under the "Regular" CPU option.&lt;/li&gt;
&lt;li&gt;For authentication, choose SSH and click the button to add a "New SSH Key." You should see a pop-up like this&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6443g8d6m992cte4frz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6443g8d6m992cte4frz.png" alt="Add New SSH Key Interface" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;with instructions on how to get your SSH key from your device. Give your key a descriptive name. I like to use the name of my device (e.g., "M1 MacBook Air")&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scroll to the bottom and replace your droplet's hostname. A shorter name is ideal. You can use a name like "bootcamp-projects" or the app's name if the droplet is used exclusively for a single app.
Create the droplet, which should take you to the project page, where you'll see your droplet with a loading progress bar. This indicates that your Droplet is being initialized. Once it's ready, you should see more details like this:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1hwl4rqhwtxi4w670ml.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1hwl4rqhwtxi4w670ml.jpg" alt="Image of droplet" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The series of numbers the arrow points to is your droplet's IP address. Please take note of the IP address, as you'll be using it later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Next, enter the IP address in your browser's address bar (preferably in a different tab), and you'll see a setup page. &lt;br&gt;
On the setup page, you'll see three fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public Key&lt;/strong&gt;: By default, this field will contain the SSH key you supplied earlier, so you don't need to do anything. However, if you didn't already upload a key, you can do so here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hostname&lt;/strong&gt;: If you want to use a domain name, enter it here. Otherwise, enter your Droplet IP address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use virtual host naming for your apps&lt;/strong&gt;: Only tick this if you're using a domain name since the option isn't available for IP address hostnames.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click 'Finish Setup' to complete the setup. If successful, it may redirect you to an error page but don't mind it.&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: You should complete this setup immediately because anybody that visits that IP address before you can insert their pubic key and complete the setup, granting them access to your server as the &lt;code&gt;dokku&lt;/code&gt; user. &lt;br&gt;
Once you complete the setup, though, nobody can access the page again.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Prepare for Deployment
&lt;/h2&gt;

&lt;p&gt;The rest of this guide assumes that you're comfortable running commands in the terminal, but here are some things to note if you aren't.&lt;/p&gt;

&lt;p&gt;When you see a command with angle brackets like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# enter your app directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;your app directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the content of the brackets (including the brackets) with the appropriate information. So, in this case, assuming the directory is &lt;code&gt;my-shiny-new-app&lt;/code&gt;, the command you type into your terminal window will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-shiny-new-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line that starts with a &lt;code&gt;#&lt;/code&gt; will be omitted because it's a comment. Comments are only there to describe the code or command.&lt;/p&gt;

&lt;p&gt;So, with that out of the way, let's proceed.&lt;/p&gt;

&lt;p&gt;SSH into your droplet using &lt;code&gt;ssh root@&amp;lt;your droplet IP or domain name&amp;gt;&lt;/code&gt; . Replace the &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; with your IP like so, &lt;code&gt;ssh root@127.0.0.1&lt;/code&gt; &lt;br&gt;
If you get a message in the terminal saying "the authenticity of host &amp;lt;your IP&amp;gt; can't be established," proceed to connect by entering &lt;code&gt;yes&lt;/code&gt;.&lt;br&gt;
You should see  &lt;code&gt;Warning: Permanently added '&amp;lt;your IP&amp;gt;' (ED25519) to the list of known hosts.&lt;/code&gt; and that's fine. If the connection is closed afterwards, rerun the ssh command, and you should now see an output like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgi6t86v0hp3628p26dye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgi6t86v0hp3628p26dye.png" alt="Dokku CLI output" width="800" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll be deploying a sample Rails app provided by Heroku.&lt;br&gt;
Clone the app on your local machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# from the root folder or a folder containing your other repos&lt;/span&gt;
git clone git@github.com:heroku/ruby-getting-started.git
&lt;span class="c"&gt;# enter into the directory of the sample app&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In another terminal window, connect to your dokku host (SSH into it like before) and create the app there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku apps:create ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"ruby-getting-started" is the app name I chose because it matches the repo, but you can give it any name you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create The Database Service
&lt;/h3&gt;

&lt;p&gt;This app uses PostgreSQL, so you'll need to install the progress plugin for Dokku:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
&lt;span class="c"&gt;# we're using sudo because the install requires root&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dokku plugin:install https://github.com/dokku/dokku-postgres.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create the database service and link it to your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your dokku host&lt;/span&gt;
dokku postgres:create rails-sample-database

dokku postgres:link rails-sample-database ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, I'm using the name "rails-sample-database," but you can name it something else.&lt;br&gt;
The &lt;code&gt;link&lt;/code&gt; method is used like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dokku postgres:link &amp;lt;service&amp;gt; &amp;lt;app&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--link-flags&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="c"&gt;# service   service to run the command against&lt;/span&gt;
&lt;span class="c"&gt;# app       app to run the command against&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can learn more about it by running the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dokku postgres:help &lt;span class="nb"&gt;link&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# for a list of all the available commands&lt;/span&gt;
dokku postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy The App
&lt;/h3&gt;

&lt;p&gt;You first need to add a git remote to your app's repo on your local machine (not on the Dokku host)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on your local machine&lt;/span&gt;
&lt;span class="c"&gt;# remote name must be dokku for it to work&lt;/span&gt;
git remote add dokku dokku@&amp;lt;our-Dokku-IP&amp;gt;:ruby-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push dokku main:master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! You've successfully deployed your app.&lt;/p&gt;

&lt;p&gt;You'll find the URL to your app in the output of the push like so;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=====&amp;gt; Application deployed:
       http://67.207.95.153:20104
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This link will only work after manually updating the Droplet firewall to allow your app's port. You'll do so with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# the port in the URL above is 20104, so insert your app's port&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow &amp;lt;port&amp;gt;/tcp comment &lt;span class="s1"&gt;'ruby-getting-started app'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your app should load up just fine now. Congrats!&lt;/p&gt;

&lt;p&gt;If you forget the port for any particular app, you can always check it by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# it'll be under 'host port'&lt;/span&gt;
dokku proxy:ports &amp;lt;app-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like Heroku, you don't need to configure &lt;a href="https://devcenter.heroku.com/articles/buildpacks" rel="noopener noreferrer"&gt;buildpacks&lt;/a&gt;. If you checked the deployment output, you may have noticed that the buildpack identified your application as a Ruby app. This is because the root directory of your app contains both the &lt;code&gt;Gemfile&lt;/code&gt; and &lt;code&gt;Gemfile.lock&lt;/code&gt; files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling Database Migrations
&lt;/h3&gt;

&lt;p&gt;Instead of remembering to run migrations after every deployment, you can use a &lt;a href="https://devcenter.heroku.com/articles/procfile" rel="noopener noreferrer"&gt;Procfile&lt;/a&gt;. We didn't create one earlier, and that was fine because Dokku creates a default Procfile for the app if none is found. But we will create one now to add the &lt;code&gt;db:migrate&lt;/code&gt; command under the &lt;code&gt;release&lt;/code&gt; process type. Here's how:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the root directory of your app in your local machine and create a file named &lt;code&gt;Procfile&lt;/code&gt; . Don't add an extension.&lt;/li&gt;
&lt;li&gt;Next, paste this into the file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rake: bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake  
console: bin/rails console  
web: bin/rails server &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;5000&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;$RAILS_ENV&lt;/span&gt;  
release: bin/rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Now, every time you push to your dokku repo, the &lt;code&gt;release&lt;/code&gt; command will run, and the database migration files will run automatically. Click &lt;a href="https://devcenter.heroku.com/articles/procfile" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you want a general understanding of what a Procfile is.&lt;/p&gt;

&lt;p&gt;Some concluding remarks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Because you only have 1GB of RAM, learn how to create Swap memory using this &lt;a href="https://dokku.com/docs~v0.5.8/advanced-installation/?h=swap#vms-with-less-than-1gb-of-memory" rel="noopener noreferrer"&gt;link.&lt;/a&gt;
I recommend 4GBs of SWAP. So, change the value of &lt;code&gt;count=1000&lt;/code&gt; to &lt;code&gt;4000&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Check out the &lt;a href="https://dokku.com/docs~v0.5.8/installation/" rel="noopener noreferrer"&gt;official Dokku docs&lt;/a&gt; to learn about all the other things you can do in Dokku. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article has been updated to make the part about running db migrations into its own section. This change was done to provide a more efficient way of handling the task. I'll continue to make small changes as I learn new stuff. &lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read this. If you have any questions or if you found this helpful, please feel free to leave a comment below.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ruby</category>
      <category>rails</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
