<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="79764" data-post-id="79764">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="madasebrof" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/madasebrof/120/8974_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  madasebrof
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Re: deployment.</p>
<p>+1 for <a href="https://nanobox.io" rel="noopener nofollow ugc">https://nanobox.io</a> (deploying to Digital Ocean)</p>
<p>We are using for it staging &amp; production deployment, works AMAZINGLY well. (Large Elixir/Phoenix/Elm app/site). Highly recommend.</p>
<p>And yes, switch to Elixir/Phoenix (and Elm!). You’ll be super-psyched.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="79764" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/does-my-frustration-with-node-merit-switching-to-elixir/13865/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-79764" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="79764"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="80039" data-post-id="80039">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ranyefet" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ranyefet/120/3281_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ranyefet
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I also came to Elixir from Node.js and I shared the same issues that you mentioned with Node.<br>
Fragile deps, manual wiring all the different libs.</p>
<p>In Node.js its really easy to get started, but is harder to maintain the system in the long run.<br>
There’s is a learning curve, but once you it “clicks” you will never want to go back <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<p>If you’re just getting started, I suggest you make your Elixir app stateless (just like in Node.js), don’t use ETS or try to hot-code reload, keep all your state in external DB (Postgres, redis) it will make your life easier when trying to deploy your app.</p>
<p>Once you feel comfortable, you can try the cool features of Elixir <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="80039" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/does-my-frustration-with-node-merit-switching-to-elixir/13865/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-80039" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="80039"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="80070" data-post-id="80070">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="aaron-price" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/aaron-price/120/7745_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  aaron-price
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>TLDR: My biggest regret was not switching to elixir sooner. I suggest following the <a href="https://forum.elixirforum.com/t/the-complete-elixir-and-phoenix-bootcamp-udemy-self-published/2271" rel="nofollow">udemy course by Stephen Grider</a>. It’s a bit old, but it should give you enough to decide whether you want to make the leap or not.</p>
<p>I also came from node (nextjs + redux + mongodb + heroku) for many of the same reasons.<br>
My current project is Elixir + phoenix + react + redux + postgres (for users) + arangodb (for graph data) + graphql inside arangodb. I don’t bother with absinthe, just send a POST request with a string.</p>
<p>For my own project I wanted something really performant, and the js crowd seems to think that js is performant because it’s async. But dealing with async was a huge pain my rear. Especially when you start using things like mongoose, where it uses it’s own promise library, but parts of it you can do with async/await (promises), but there’s the occasional undocumented thing in mongoose that ONLY works with old school callbacks… That lead to a great deal of frustration.</p>
<p>Elixir is more performant. WAY more. And its async system (processes) is WAY easier to reason about. Processes are also <strong>truly</strong> asyncronous, while the js event loop is technically just a highly optimized, yet synchronous system.</p>
<p>Then you have immutability. I remember the time I spent days trying to figure out why my array was changing by itself. Oh, you used an Array.prototype method on a <em>different</em> array? Too bad!</p>
<p>That is not an issue in elixir.</p>
<p>Or how about setting things up. Expressjs is awesome because it’s so lightweight and lets you roll your own stack… but eventually I found that to be its greatest weakness. There’s several different ways to do anything in node. When you look for help, you often have to explain your whole setup, and pray that someone had the same setup with the same problem.</p>
<p>Elixir comes with testing. I find it better than jest, jasmine, or mocha.<br>
Elixir has a rails-like framework (phoenix). Built in CSRF validation and sessions, ORM, and an intuitive organization of code. Of course if you really want to roll your own, that’s still easy enough.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="80070" data-batch-url="/posts/batch_likers">
                        8
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/does-my-frustration-with-node-merit-switching-to-elixir/13865/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-80070" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="80070"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="105043" data-post-id="105043">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="aamerabbas" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/aamerabbas/120/12841_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  aamerabbas
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi, I switched from Node to Elixir. I am generally happy with the switch, but it really just depends on what your needs and expectations are. I personally really like the coherence of the community and the batteries-included approach of Phoenix. The community has basically taken the opinionated stance of Rails, but fixed most of the shortcomings.</p>
<p>Anyway, I’m sorry people are not answering your questions seriously. We all have to start somewhere and it’s very frustrating when people trivialize these challenges. I went through some of these struggles myself. Let me tell you my setup, and I hope it helps you out.</p>
<p>I am essentially doing the following for my Phoenix application:</p>
<ul>
<li>I build my Elixir code using the “mix release” task</li>
<li>I get all the dependencies and package them up in a container</li>
<li>I deploy using Kubernetes (in my case, on Google Cloud)</li>
<li>I use BitBucket pipelines to automate the testing and deployment process.</li>
</ul>
<p>My Dockerfile looks something like this:</p>
<pre data-code-wrap="Dockerfile"><code class="lang-Dockerfile">FROM elixir:1.7.1-alpine
ARG APP_NAME=my_app
ARG PHOENIX_SUBDIR=.
ENV MIX_ENV=prod REPLACE_OS_VARS=true TERM=xterm
WORKDIR /opt/app
RUN apk update \
    &amp;&amp; apk --no-cache --update add nodejs nodejs-npm make g++ python git imagemagick \
    &amp;&amp; mix local.rebar --force \
    &amp;&amp; mix local.hex --force
COPY . .
RUN mix do deps.get, deps.compile, compile
RUN cd ${PHOENIX_SUBDIR}/assets \
    &amp;&amp; npm install \
    &amp;&amp; ./node_modules/brunch/bin/brunch build -p \
    &amp;&amp; cd .. \
    &amp;&amp; mix phx.digest
RUN mix release --env=prod --verbose \
    &amp;&amp; mv _build/prod/rel/${APP_NAME} /opt/release
FROM alpine:latest
RUN apk update &amp;&amp; apk --no-cache --update add bash openssl-dev imagemagick
ENV PORT=8080 MIX_ENV=prod REPLACE_OS_VARS=true
WORKDIR /opt/app
EXPOSE ${PORT}
COPY --from=0 /opt/release .
CMD ["/opt/app/bin/my_app", "migrate_seed_and_start"]
</code></pre>
<p>My bitbucket pipeline config looks something like this</p>
<pre data-code-wrap="yml"><code class="lang-yml">image: elixir:1.7.1-alpine

pipelines:
  default:
    - step:
        name: Test
        script:
          - apk update
          - apk --no-cache --update add coreutils nodejs nodejs-npm make g++ python git imagemagick bash curl tar
          - MIX_ENV=test mix local.rebar --force
          - MIX_ENV=test mix local.hex --force
          - MIX_ENV=test mix deps.get
          - MIX_ENV=test mix deps.compile
          - MIX_ENV=test mix ecto.create
          - MIX_ENV=test mix ecto.migrate
          - mix test
        services:
          - database
    - step:
        name: Build and Deploy
        trigger: manual
        script:
          - apk update
          - apk --no-cache --update add coreutils nodejs nodejs-npm make g++ python git imagemagick bash curl tar
          # Installing gcloud
          - curl -o $HOME/google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-207.0.0-linux-x86_64.tar.gz
          - tar -xvf $HOME/google-cloud-sdk.tar.gz -C $HOME/
          - $HOME/google-cloud-sdk/install.sh
          - source $HOME/google-cloud-sdk/path.bash.inc
          - export PATH="$HOME/google-cloud-sdk/bin:$PATH"
          - gcloud -v -q
          # Installing kubectl
          - gcloud components install kubectl -q
          # Authentication
          - echo $GCLOUD_API_KEYFILE | base64 --decode --ignore-garbage &gt; ./gcloud-api-key.json
          - gcloud auth activate-service-account --key-file gcloud-api-key.json
          - gcloud config set project my_app
          - gcloud container clusters get-credentials my_app --zone=europe-west1-d
          - kubectl version
          # Deploy
          - source $BITBUCKET_CLONE_DIR/build.sh $BITBUCKET_BUILD_NUMBER
          - source $BITBUCKET_CLONE_DIR/deploy.sh $BITBUCKET_BUILD_NUMBER
        services:
          - docker
              
definitions:
  services:
    database:
      image: postgres:9.6
      environment:
        POSTGRES_PASSWORD: secret
    docker:
      memory: 2048
</code></pre>
<p>Also, you will notice a build.sh and deploy.sh file referenced here. These are small simple scripts I made. They look like this:</p>
<p>Build.sh</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">VERSION="$1";

if [ -z "$VERSION" ]
then
  echo "Must specify a version to tag the docker container";
  exit;
fi

docker build --no-cache -t "eu.gcr.io/my_app/my_app:$VERSION" . &amp;&amp; \
gcloud docker -- push "eu.gcr.io/my_app/my_app:$VERSION"
</code></pre>
<p>Deploy.sh</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">#!/bin/bash

VERSION="$1";

if [ -z "$VERSION" ]
then
  echo "Must specify a version to tag the docker container";
  exit;
fi

kubectl set image deployment/my_app my_app=eu.gcr.io/my_app/my_app:$VERSION
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="105043" data-batch-url="/posts/batch_likers">
                        11
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/does-my-frustration-with-node-merit-switching-to-elixir/13865/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-105043" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="105043"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="119243" data-post-id="119243">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="alamba78" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/alamba78/120/1229_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  alamba78
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Has anyone ever gone from Elixir to Node? That’s the interesting question. LOL.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="119243" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/does-my-frustration-with-node-merit-switching-to-elixir/13865/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-119243" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="119243"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="123369" data-post-id="123369">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="akoutmos" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/akoutmos/120/20230_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  akoutmos
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Build a Weather Station with Elixir and Nerves</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Haha. I had to make the switch for my day job as the tech stack does not include Elixir :'(.</p>
<p>The things you take for granted in Elixir are serious concerns in the Node world. The obvious example being hogging the event loop. Also, while not limited to Node, immutability is something I greatly miss especially in a team environment. You never really know if an object will change out from under you if you pass it around to other functions. If I had to choose between “developer diligence” and “baked in”, I would chose baked in.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="123369" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/does-my-frustration-with-node-merit-switching-to-elixir/13865/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-123369" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="123369"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>