<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Darkthemecoder]]></title><description><![CDATA[Tutorials on the whole stack. Spring, Angular, Amazon AWS and more technologies!]]></description><link>https://darkthemecoder.com/</link><image><url>https://darkthemecoder.com/favicon.png</url><title>Darkthemecoder</title><link>https://darkthemecoder.com/</link></image><generator>Ghost 4.48</generator><lastBuildDate>Sun, 29 Mar 2026 13:54:12 GMT</lastBuildDate><atom:link href="https://darkthemecoder.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[From Pages to Progress: Turning Self-Help Books into Real Results]]></title><description><![CDATA[I have gotten stuck with consuming self-help books for a long time. I found out how to break out of this comfort zone and get results to work towards my dreams.]]></description><link>https://darkthemecoder.com/from-pages-to-progress-turning-self-help-books-into-real-results/</link><guid isPermaLink="false">66774967ed83c10895d1e274</guid><category><![CDATA[productivity]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Darkthemecoder]]></dc:creator><pubDate>Sat, 22 Jun 2024 22:04:26 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1447966374608-a6f7e7a12974?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIxfHxkaXZlfGVufDB8fHx8MTcxOTA5MzY3MHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1447966374608-a6f7e7a12974?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIxfHxkaXZlfGVufDB8fHx8MTcxOTA5MzY3MHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="From Pages to Progress: Turning Self-Help Books into Real Results"><p>I have wanted to start a business for a long time now. But I&#x2019;ve never done it before, so into the YouTube rabbit hole I went. Got some book recommendations and started reading them. From there, I found more books that I felt I needed to read before I deemed myself qualified to start a business. Sound familiar?</p><p>You may already know this, but deep down you probably don&#x2019;t think you are unqualified. Consuming content is just so much easier than taking the steps to learn something new and inherently failing at things.</p><blockquote>Reading self-help books gives you the illusion that you are learning and making progress in what you want to achieve.</blockquote><hr><p>Don&#x2019;t get me wrong, I am not saying that the books are bad. What I am saying is to put the things you read into action. If you don&#x2019;t do this, you will stay in your comfort zone of just reading and not truly learning.</p><p>If you wanted to learn to swim, would you pick up a book? Probably not. You would go to a local swimming pool and get lessons. What do those lessons do? They don&#x2019;t put you in a school bench to tell you how to float; they give you instructions, and you immediately get in the water to practice.</p><p>See what I&#x2019;m getting at here? <strong>You need to put every lesson you learn into action immediately, or you&#x2019;ll learn nothing from it</strong>.</p><p>When you read a self-help book, I want you to do what you would in a swimming school, or any other learning environment. Take notes on the things that stand out to you. As we know, taking notes while learning helps you remember the material. So, take notes, highlight interesting quotes, and write yourself a summary. But we&#x2019;re not stopping there.</p><p>The last important step is to get you out of that comfort zone. Since you won&#x2019;t be tested or thrown into the pool by your teacher, you have to do this yourself. With every chapter or lesson you learn, create an action point for yourself. And now put it to practice. When you finish a chapter and have a few points, start putting those into action before the next time you pick up the book. You could see it as homework you need to do before the next lesson. This way, you&#x2019;ll get yourself out of that warm and cozy comfort zone and start moving towards your goal.</p><p>When you follow these steps, you won&#x2019;t feel the need to read another book before you can get started because you already did! Of course, at some point, you might want to learn a new skill related to your goal, and it&#x2019;s perfectly fine to get another book to learn that skill, as long as you follow these steps again. Remember, Rome wasn&#x2019;t built in a day, and neither will your dreams be. But by taking action, you&#x2019;re already building the foundation.</p><p>So, let&#x2019;s put this post into practice right now, shall we? Highlight the points in this post that bring value to you, and create some specific action points based on what you&#x2019;ve learned. Since there won&#x2019;t be a next lesson for this class, how about setting a deadline? Execute the action points you made before next week and start building that base! Remember, the goal is progress, not perfection &#x2014; every small step counts.</p><p>Thank you for reading this, and good luck!</p>]]></content:encoded></item><item><title><![CDATA[Linux quicktip: Ssh names]]></title><description><![CDATA[<p>Got a lot of machines to connect to? It gets really annoying to memorize the ip&apos;s. Use this tip to give names to the connections and easily connect to the names instead of the ip&apos;s.</p><p>In your users home folder create or go to the /.ssh</p>]]></description><link>https://darkthemecoder.com/linux-quicktip-easier-ssh/</link><guid isPermaLink="false">6176d25d4136990abb0cbc7b</guid><category><![CDATA[linux]]></category><category><![CDATA[Knowledge]]></category><category><![CDATA[devops]]></category><dc:creator><![CDATA[Darkthemecoder]]></dc:creator><pubDate>Mon, 25 Oct 2021 16:16:58 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1569235186275-626cb53b83ce?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fGZpbGluZ3xlbnwwfHx8fDE2MzUxNzgzOTQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1569235186275-626cb53b83ce?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fGZpbGluZ3xlbnwwfHx8fDE2MzUxNzgzOTQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Linux quicktip: Ssh names"><p>Got a lot of machines to connect to? It gets really annoying to memorize the ip&apos;s. Use this tip to give names to the connections and easily connect to the names instead of the ip&apos;s.</p><p>In your users home folder create or go to the /.ssh folder and create a file named config. In this file add the following lines for each connection you have.</p><!--kg-card-begin: markdown--><pre><code>Host my-local-address
    HostName 127.0.0.1
    User username
</code></pre>
<!--kg-card-end: markdown--><p>Cool! After you save the file you can, with this specific example, connect to the ip 127.0.0.1 by using the command `ssh my-local-address`.</p><p>As you can maybe imagine the are plenty more options to be entered here. But this being a quicktip, I am not going to explore these with you. If you want to know more, check out this article which shows a lot more: <a href="https://linuxize.com/post/using-the-ssh-config-file/#ssh-config-file-location">https://linuxize.com/post/using-the-ssh-config-file/#ssh-config-file-location</a></p>]]></content:encoded></item><item><title><![CDATA[Deploy your Angular app automatically in the cloud for free!]]></title><description><![CDATA[The days of manual deployments are long gone, and so are the days of managing a VM or server with Apache to host your Angular app. Deploy your Angular app in to AWS S3 in less than 30 minutes today!]]></description><link>https://darkthemecoder.com/angular-to-s3-with-gitlab-ci/</link><guid isPermaLink="false">5eb2656feef3334ad61a3cf2</guid><category><![CDATA[Angular]]></category><category><![CDATA[Knowledge]]></category><category><![CDATA[tutorial]]></category><category><![CDATA[devops]]></category><category><![CDATA[Frontend]]></category><dc:creator><![CDATA[Darkthemecoder]]></dc:creator><pubDate>Sun, 13 Sep 2020 14:15:25 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1569428034239-f9565e32e224?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://images.unsplash.com/photo-1569428034239-f9565e32e224?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Deploy your Angular app automatically in the cloud for free!"><p>As developers we want our stuff running as quick and easy and cheap as possible. Why else would you keep working on that side project, am I right? So for this the best option I have found is to publish my frontend projects to Amazon&apos;s AWS S3. The first year is completely free and after that time it is still <a href="https://aws.amazon.com/s3/pricing/">dirt cheap</a>. So in this tutorial I will show you how you can deploy your Angular app to AWS S3 automatically with Gitlab CI!</p>
<!--kg-card-end: markdown--><h2 id="step-1-the-build">Step 1: The build</h2><!--kg-card-begin: markdown--><p>First of all we want Gitlab CI to build the project so that it can be deployed in a later stage. For this we need to make a file called <code>.gitlab-ci.yml</code> in your repository. In this file we are going to make a stage to build the project:</p>
<!--kg-card-end: markdown--><pre><code class="language-yml">build:
  stage: build
  image: node:lts-alpine3.11
 
  cache:
    key: build-cache
    paths:
      - node_modules/

  script: 
    - &quot;npm install -g @angular/cli&quot;
    - &quot;npm ci&quot;
    - &quot;npm run build-prod&quot;

  artifacts:
    paths:
      - dist/</code></pre><!--kg-card-begin: markdown--><p>As you can see we are using a node image to build the project. In the script section the real building magic kicks of: First we install the Angular CLI, next we run the CI-friendly <code>npm install</code> just like you would when you get a new project on your machine. And last but not least we run <code>build-prod</code>. If you&apos;ve worked a lot with Angular CLI before you can tell this does not exist. Normally you would run <code>ng build --prod</code>. So the next thing to do is put that configuration in the <code>package.json</code> file under the scripts section: <code>&quot;build-prod&quot;: &quot;ng build --prod&quot;,</code><br>
When you commit the code with these adjustments you should see your code being build by Gitlab CI automatically!</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>To make the builds a bit more efficient we added a cache with a key. This means all the node modules don&apos;t have to be downloaded every time a build runs.</p>
</blockquote>
<!--kg-card-end: markdown--><h2 id="step-2-deployment-stage">Step 2: Deployment stage</h2><!--kg-card-begin: markdown--><p>The next step is to add another stage to the <code>.gitlab-ci.yml</code> file that handles the deployment of the Angular app to AWS S3. For this we will be using the AWS CLI. Luckily, the lads and ladina&apos;s at Gitlab have provided us with a docker image on which said CLI is installed. So for the image of this stage use <code>registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest</code>. From there only one action is really required, which is copying your files to the bucket. This is done with the cli command <code>aws s3 cp ./dist/my-app/ s3://$BUCKET_NAME/ --recursive</code>. That is it, really! To be fancy I added the bucket as a Gitlab environment, but this is optional.</p>
<!--kg-card-end: markdown--><pre><code class="language-yaml">deploy:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  dependencies:
    - build
  script:
    - echo &quot;copying files to s3://$BUCKET_NAME/&quot;
    - aws s3 cp ./dist/my-app/ s3://$BUCKET_NAME/ --recursive
    - echo &quot;Copying files complete&quot;</code></pre><!--kg-card-begin: markdown--><p>Notice the <code>$BUCKET_NAME</code> usage in the scripts. That is an environment variable that can be set in Gitlab&apos;s variables tab, but we&apos;ll get to that later. One other final step is to make the two stages not run simultaneously by adding the stages at the top of the file:</p>
<!--kg-card-end: markdown--><pre><code>stages:
 - build
 - deploy</code></pre><!--kg-card-begin: markdown--><p>Okay, we&apos;re almost done with Gitlab. The last thing we need to do is to add the BUCKET_NAME variable, and two others for AWS authentication. You can find this in your project under Settings -&gt; CI/CD -&gt; Variables. Here you can add the following variables:</p>
<ol>
<li>BUCKET_NAME</li>
<li>AWS_ACCESS_KEY_ID</li>
<li>AWS_SECRET_ACCESS_KEY</li>
</ol>
<p>These values will be filled in the following steps so don&apos;t worry about them for now.</p>
<!--kg-card-end: markdown--><h2 id="step-3-setting-up-an-iam-user-with-permissions">Step 3: Setting up an IAM user with permissions</h2><p>To make it possible for your Gitlab pipeline to deploy your Angular app to AWS S3 we are going to create a new user that has the permission to put new files in a bucket. If you are familiar with this already feel free to skip this step.</p><p>If you haven&apos;t already, create an account on AWS. Heads up: I said it was free and it truly is. AWS will ask you for your credit card, and will reserve a small amount (can&apos;t remember or find if it was a dollar or a cent), <strong>only to verify you</strong>. This money will not be actually be written off your card.</p><p>AWS can be managed with the online console, a CLI or even an SDK. For now we will use the online console for its ease of use. So login to your account and navigate to IAM. From here you first need to head to <strong>Policies </strong>and click on <strong>Create policy. </strong>Click on the tab<strong> JSON</strong> and add the following:</p><pre><code>{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Sid&quot;: &quot;darkthemecoder-s3-ci-policy&quot;,
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: &quot;s3:PutObject&quot;,
            &quot;Resource&quot;: &quot;*&quot;
        }
    ]
}</code></pre><p>Click on Review policy and add a describing name, I went for the name <strong>ci-s3</strong>. </p><p>Now for the adding a user:</p><ul><li>Go to <strong>Users</strong> and click on <strong>Add user. </strong></li><li>Once again, give it a nice name. I chose ci-user.</li><li>Select <strong>Programmatic access </strong>and go to the next step. </li><li>Click on <strong>Attach existing policies directly </strong>and find your policy (You can use the Filter policies function and set it to <strong>customer managed</strong>). Select it and finish the wizard. </li><li>After creating a user you will get a screen with the <strong>Access key ID</strong> and the <strong>Secret access key</strong>. Copy those and add them to the corresponding variables in Gitlab. (If you closed this screen on accident: Don&apos;t worry, you can generate a new key in the options)</li></ul><h2 id="step-4-getting-s3-set-up">Step 4: Getting S3 set up</h2><p>Okay you&apos;re almost there. Just two more little steps before you can git push your code and see it being built and deployed automatically. These steps are to create a new S3 bucket, and get it configured to host the website. In other words, make the files in your bucket public.</p><p>First, let&apos;s create this bucket, shall we? </p><!--kg-card-begin: markdown--><ul>
<li>Log in to your AWS account and go to <a href="https://s3.console.aws.amazon.com/s3">https://s3.console.aws.amazon.com/s3</a>.</li>
<li>From here you can press the button <strong>Create bucket</strong> which will open a wizard.</li>
<li>Select a region and enter a &quot;DNS compliant&quot; name, which simply excludes some characters that can mess up the domain name. When you got several words just use a <code>-</code> and you&apos;re golden.</li>
<li>In the next step, Configure options, you can leave everything unchecked as they are optional features that can cost extra.</li>
<li>In the <strong>Permissions</strong> step uncheck the <strong>Block all public access</strong> toggle, and acknowledge the warning message.</li>
<li>Review your settings in the next step and click <strong>Create bucket</strong> to do exactly what the button says.</li>
</ul>
<!--kg-card-end: markdown--><blockquote>Hooray, you&apos;ve got a bucket! Now, <strong>very important: </strong>Set the BUCKET_NAME variable in your gitlab settings to the bucketname that you have just created. </blockquote><!--kg-card-begin: markdown--><p>To make the bucket a website host follow these steps:</p>
<ul>
<li>Navigate into your bucket and click on the tab <strong>Properties</strong>.</li>
<li>Click on the card <strong>Static website hosting</strong> to open it.</li>
<li>Click on Use this bucket to host a website and make sure that <strong>Index document</strong> is set to <code>index.html</code> and hit Save.</li>
</ul>
<!--kg-card-end: markdown--><p>Okay this is truly the last step: Navigate to <strong>Permissions </strong>and add the following json to the <strong>Bucket Policy </strong>button:</p><pre><code class="language-yml">{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Id&quot;: &quot;PublicSitePolicy&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Sid&quot;: &quot;WebsiteRead&quot;,
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: &quot;*&quot;,
            &quot;Action&quot;: &quot;s3:GetObject&quot;,
            &quot;Resource&quot;: &quot;arn:aws:s3:::YOUR-BUCKETNAME/*&quot;
        }
    ]
}</code></pre><p>You might have noticed the subtle <strong>YOUR-BUCKETNAME </strong>in there. Change that to your bucketname to make the policy work. Hit that <strong>Save </strong>button in the top right corner and it is all set! You can now start your pipeline by pushing your code and see your files appearing in the bucket. </p><p>To see your actual site, and not just the files; In your bucket go to <strong>Properties </strong> again and click on <strong>Static website hosting </strong>to see what the webaddress is of your now public bucket.</p><p>Oh oh oh.. also. You can now proudly say that your hobby projects run in <em>the cloud</em>. You&apos;re welcome ;)</p><h2 id="conclusion">Conclusion</h2><p>I hope this tutorial helped you! If you got any feedback and/or questions or feel free to reach out to me on <a href="https://twitter.com/darkthemecoder">Twitter</a> and of course, don&apos;t forget to follow me if you enjoyed this and want to be notified of coming tutorials.</p><p><em>Love, Darkthemecoder</em></p><p></p>]]></content:encoded></item><item><title><![CDATA[Migrating a Spring app to a Quarkus app]]></title><description><![CDATA[In this blogpost you will find the actions that you have to take to convert a Spring Boot application to a Quarkus application, and some noteable thing that I have learned in the process. ]]></description><link>https://darkthemecoder.com/spring-to-quarkus/</link><guid isPermaLink="false">5e5268e240654a2c83039fc7</guid><category><![CDATA[Serverless]]></category><category><![CDATA[Quarkus]]></category><category><![CDATA[spring boot]]></category><category><![CDATA[Knowledge]]></category><category><![CDATA[Java]]></category><dc:creator><![CDATA[Darkthemecoder]]></dc:creator><pubDate>Fri, 21 Feb 2020 15:33:33 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1558981023-1d4b7dd8dfb9?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://images.unsplash.com/photo-1558981023-1d4b7dd8dfb9?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Migrating a Spring app to a Quarkus app"><p>Recently I&apos;ve been looking at the potential of the serverless frameworks Quarkus and Micronaut. They look really promising, and therefore I tried to convert a Spring Boot service to a Quarkus service. In this blogpost you will find the actions that you have to take to do it yourself, and some noteable thing that I have learned in the process.</p>
<h3 id="build">Build</h3>
<p>First of all, Quarkus only supports Maven at this point. For Gradle a preview has been brought out, but if you&apos;re going for a production app, that&apos;s not the stable option you want to take. So if your Spring Boot app is currently built with Gradle, I&apos;d suggest converting it to make use of Maven.</p>
<h3 id="databaseconnection">Database connection</h3>
<p>Quarkus has hibernate to connect to a database with the needed database drivers like MySql, Postgress, H2 in-memory and so forth. The Quarkus team have provided an simplified implementation called &quot;Panache&quot;. It works quite similar to the Spring JpaRepository works and it provides an extra way of accessing the data, called the Active Record Pattern. In a Spring to Quarkus migration you probably don&apos;t want to move to that solution.</p>
<p>For migrating a Spring repository to a Quarkus Panache repository you have to change a couple of things:</p>
<ul>
<li>Your Spring repository is an interface, in Quarkus it is a class</li>
<li>Quarkus&apos; Panache repository method names are different from Spring&apos;s repo</li>
<li>All persisting methods need <code>@Transaction</code> to work when called</li>
</ul>
<p>Spring repo:<br>
<code>public interface PersonRepository extends CrudRepository&lt;Person, Long&gt;</code></p>
<p>Quarkus repo:<br>
<code>public class PersonRepository implements PanacheRepository&lt;Person&gt;</code></p>
<!--kg-card-end: markdown--><blockquote>Little extra note for those with an import.sql script in their SB application: The naming convention that Spring Boot has differs a bit from Quarkus&apos; implementation when it comes to camelcase. Where the field <code>paymentDate</code> is converted to the sql field <code>payment_date</code> in Spring, it is converted to the sql field <code>paymentDate</code> in Quarkus. So keep in mind that you either change the fieldnames in your import.sql or add an hibernate property to change this behaviour.</blockquote><h3 id="swagger">Swagger</h3><p>For the swagger documentation side of things, not much is needed. In Spring you&apos;ve got yourself two dependencies generally: swagger and swagger UI. In Quarkus these two are combined in the package <code>quarkus-smallrye-openapi</code>. Besides that, no additional config is needed for basic usage. Include the dependency and access it at <code>/swagger-ui</code>. Note that this only works in dev mode. To use it on production you just add <code>quarkus.swagger-ui.always-include=true</code> in the property file.</p><h2 id="property-files">Property files</h2><p>Another notable thing is that your yaml configurations from Spring don&apos;t work out of the box; you are going to need an extra yaml-config dependency. Another big change are the property profile files. That does not exist at the moment in quarkus. If you want to have several profiles it is going to look like this:</p><pre><code>quarkus.http.port=9090
%staging.quarkus.http.port=9999
%prod.quarkus.http.port=8080</code></pre><h2 id="missing">Missing</h2><!--kg-card-begin: markdown--><p>Last but not least, Quarkus&apos; age. The framework looks really promising and already has a good collection of extensions to make some cool stuff. However it looks like the developers aimed at quantity of extensions instead of the quality. I&apos;m not saying they are bad, they are just far from complete or completely missing. A lot of features that you take for granted when using Spring are either in &quot;preview&quot;, incomplete or simply missing. Therefore going to production with more complexity than simple REST endpoints is to me not a good idea yet. But I will surely be frequently playing with it and tracking its process and hoping that it will improve soon.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>