<?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[ScottFred]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://scottfred.org/</link><image><url>https://scottfred.org/favicon.png</url><title>ScottFred</title><link>https://scottfred.org/</link></image><generator>Ghost 4.3</generator><lastBuildDate>Tue, 14 Apr 2026 12:29:40 GMT</lastBuildDate><atom:link href="https://scottfred.org/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Flow and Meditation]]></title><description><![CDATA[<p>Being a software engineer is challenging. &#xA0;Many software professionals talk about getting into Flow as a great way to being able to increase their productivity and enjoyment while coding. &#xA0;Flow seems to enable developers to see the path they need to take rather than wandering around without direction</p>]]></description><link>https://scottfred.org/flow-and-meditation/</link><guid isPermaLink="false">60b3cd1b9f54f765a3ca983c</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Sun, 30 May 2021 18:01:54 GMT</pubDate><content:encoded><![CDATA[<p>Being a software engineer is challenging. &#xA0;Many software professionals talk about getting into Flow as a great way to being able to increase their productivity and enjoyment while coding. &#xA0;Flow seems to enable developers to see the path they need to take rather than wandering around without direction toward completing their work.</p><p>I often read ideas of how to achieve Flow which are more reactive than proactive. The reactive ideas are to close your office door (assuming you have a door), turn off all notifications on your computer (instant messaging notifications, text messages, email, etc), and wearing headphones while listening to ambient music. These are all great ideas, but they are reactive to the situation.</p><p>One idea I would like to propose more software engineers to do is to train your brain to focus by practicing meditation. &#xA0;I find that 10 to 30 minutes of meditation per day are an excellent way to teach my brain how to focus and get into flow. &#xA0;I&apos;ve practiced meditation for a little over 4 years now and find it to be a great way to focus.</p><p>For those that are not familiar with meditation, it can be as simple as finding a quiet place where you won&apos;t be interrupted, usually closing your eyes, focusing on inhaling and exhaling a few times to calm the mind and center it on a single task of focusing on your breath. &#xA0;At its most simple form, that&apos;s really it. </p><p>During each session, your monkey mind will likely go skipping off thinking of a hundred different things. &#xA0;Once you discover that your mind has wandered off (not focused on simply observing of your breathing), just gently bring your mind back to your breathing. &#xA0;You shouldn&apos;t judge yourself harshly as you try to complete this seemingly simple task of observing your breath for 10 to 30 minutes; your monkey mind has been encouraged to wander off seemingly randomly through all of our electronic interruptions.</p><p>There are several meditation apps that I have used for learning how to meditate. Each have their own flavor and style of training and doing meditation. &#xA0;There is no one right way to do it; I would encourage you to just experiment to find something that fits with your style. &#xA0;Also keep in mind that as you practice meditation, you may find something that works now, but months or years later you shift to something else as you grow and learn.</p><p>One app that I currently use daily is &quot;Insight Timer&quot;. &#xA0;There are thousands of guided meditations, meditation background music, and courses. &#xA0;You can find guided meditations or simply ambient background music to listen to for your meditation. Within Insight Timer, a favorite meditation guide for me is Andy Hobbson. &#xA0;His guided meditations are my style, but you&apos;ll need to find your own style.</p><p>Happy meditating...</p>]]></content:encoded></item><item><title><![CDATA[Software Development Is a Team Sport]]></title><description><![CDATA[<p>Developing software of any real significance requires a <a href="https://en.wikipedia.org/wiki/Team">team</a>. &#xA0;A team is more than a group. &#xA0;A group lacks a goal or a common purpose. &#xA0;Are you a software developer that works as a member of a team, or a group? &#xA0;Or, are you playing &quot;</p>]]></description><link>https://scottfred.org/software-development-is-a-team-sport/</link><guid isPermaLink="false">5fa4284476e58345ebf0d6af</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Tue, 24 Nov 2020 19:02:48 GMT</pubDate><content:encoded><![CDATA[<p>Developing software of any real significance requires a <a href="https://en.wikipedia.org/wiki/Team">team</a>. &#xA0;A team is more than a group. &#xA0;A group lacks a goal or a common purpose. &#xA0;Are you a software developer that works as a member of a team, or a group? &#xA0;Or, are you playing &quot;<a href="https://en.wikipedia.org/wiki/Individual_sport">individual sports</a>&quot;?</p><p>Software that requires a team is something of significance; not just a side project that many of us work on from time to time. &#xA0;The software I&apos;m talking about is designed, marketed, architected, built, tested, supported, and deployed for the world to use. &#xA0;And EVERYONE on this team is important. &#xA0;There is no single person that is more important than the other because a team is only as strong as its weakest link. &#xA0;This is also why I like to focus on the team&apos;s successes rather than individual contributors. &#xA0; </p><p>Marc Andreessen famously quipped that &quot;<a href="https://www.forbes.com/sites/cognitiveworld/2019/08/29/software-ate-the-world-now-ai-is-eating-software/?sh=1f30f2b95810">software is eating the world</a>&quot; and I believe it. However, I don&apos;t quite subscribe to Microsoft&apos;s CEO belief that &quot;<a href="https://www.satellitetoday.com/innovation/2019/02/26/microsoft-ceo-every-company-is-now-a-software-company/">every company is a software company</a>&quot;. &#xA0;Being a little geeky, that sentence fails the <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov Substitution Principle</a>; it&apos;s more accurate to say that every company <strong><em>has a</em></strong> (or should have a) software development element within it (if you&apos;re going to be competitive in the world economy). Software is everywhere and there really isn&apos;t an end in sight and building software of any real significance requires a team.</p><p>And, like team sports, software teams are comprised of individuals. &#xA0;The individuals all have their own skills, ambitions, goals, challenges, strengths, and weaknesses. &#xA0;As such, that team will be all the better when each of the individuals are the best at the skill that the team needs. &#xA0;It&apos;s also a lot more fun when everyone is firing on all cylinders, confident, supported, encouraged by the rest of the team members.</p><p>There is nothing wrong with individual sports. &#xA0;In fact, I have the utmost respect for people that play individual sports. &#xA0;Just like being on the tennis court, there&apos;s no one else to blame. Or, just like being a pilot flying solo. &#xA0;You have to be on top of your game to be able to do this.</p><p>I&apos;m not saying, however, that this team has to literally be in the trenches shoulder to shoulder like Soldiers or like a football team for every play. &#xA0;But, there has to be enough coordination and communication to ensure that the team is moving in the same direction with the same motivation. A software development team is very cross-functional with a lot of individual specialities. &#xA0;Those individuals don&apos;t need to be spending every working hour constantly communicating because they need time to focus on their task - their specialty - because the team is relying on them. </p><p>I love everything about software development and working in a team. And I continue to get the opportunity to work with a lot of great teams. The &quot;knowledge workers&quot;, as we are often referred to, appear to go into this abyss and emerge with something. &#xA0;It&apos;s a very creative process. &#xA0;Whether its a UI design, the front-end client code, the backend APIs, or database structures, they are all have fascinating things to consider; &#xA0;everything from usability to performance. &#xA0;</p><p>But, team&apos;s don&apos;t just happen. &#xA0;They are cultivated. &#xA0;They are built. &#xA0;They are led! &#xA0;</p><p>If you think software is hard to build, consider the challenges of building a team. People are the most complex systems I know. &#xA0;They all have their own operating systems, communication protocols, and networking infrastructure. &#xA0; They all come with their own &quot;bugs&quot;, aka biases. &#xA0;On top of this, many of these biases are subconscious, which make them even more difficult to identify.</p><p>Working with great teams is exhilarating, inspirational, and fun. &#xA0;I&apos;ve been part of a few great teams in my career and that feeling is alluring. &#xA0;The one thing I really appreciated from a strong team is - strangely enough - teamwork. &#xA0;Specifically, everyone supporting one another. &#xA0;Encouraging one another. &#xA0;Helping them get over roadblocks and freely giving them ideas. &#xA0;Sharing what they learn along the way, regardless of whether or not they think the topic may apply to them. &#xA0;In my experience, sharing things you learn along the way can result in surprising ways that it can be applied in other areas of the team or company.</p><p>Just like a sports team, a software team needs leadership. &#xA0;Leaders that coach, guide, mentor, encourage, and supports individual members -- as well as the team as a whole. Leadership happens on many different levels. &#xA0;Leadership is way more than management. &#xA0;</p><p>Everyone gets up in the morning wanting to feel like they are contributing to the team and the goal. &#xA0;&quot;I&apos;m going to go to work today and fail at my job and make everyone miserable&quot;, says no one, ever. </p><p>Moreover, people grow and change. &#xA0;Their goals change. &#xA0;Life happens. &#xA0;They mature (hopefully). &#xA0;It&apos;s a leader&apos;s job to communicate the direction of the team and the company and help people understand how they can contribute to that goal. It&apos;s also a leader&apos;s job to encourage individuals to learn new skills and get experience with a new technology to continue that growth so they can continue to be a valuable part of the team. &#xA0;It&apos;s a leader&apos;s job to inspire and paint a clear picture.</p><p>So, are you playing on a team? &#xA0;How are you doing in your role on the team to support, encourage, and lift everyone up?</p>]]></content:encoded></item><item><title><![CDATA[Software Engineering Notebook]]></title><description><![CDATA[<p>Do you keep a software engineering notebook or log book? &#xA0;If not, you may want to consider doing it. &#xA0;Below, I outline what I&apos;ve been doing for many years and how it has helped me. &#xA0;<em>(Notebook, Log Book, Field Notes, Lab Notebook, Journal?)</em></p><p>First, I</p>]]></description><link>https://scottfred.org/software-journals/</link><guid isPermaLink="false">5fb9436e76e58345ebf0db05</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Mon, 23 Nov 2020 06:11:36 GMT</pubDate><content:encoded><![CDATA[<p>Do you keep a software engineering notebook or log book? &#xA0;If not, you may want to consider doing it. &#xA0;Below, I outline what I&apos;ve been doing for many years and how it has helped me. &#xA0;<em>(Notebook, Log Book, Field Notes, Lab Notebook, Journal?)</em></p><p>First, I refer to my notebook as a software engineering notebook, rather than a programming or code journal because I try to encourage myself to be systematic, or scientific-lite about it. &#xA0;Meaning that I have a general collections of sections that I have developed which encourages me to have a structure to the information that I capture. &#xA0;It helps me remember to capture certain aspects of the things I&apos;m learning or experimenting with. &#xA0;For example, references for the information I&apos;m writing. </p><p>Second, my interests are broader than just &quot;programming&quot; or &quot;coding&quot;. &#xA0;I love all aspects of software engineering! &#xA0;I love the psychological UI/UX color, typography, animation aspects of applications as much as I do building out CI/CD deployment pipelines, as well as building the application itself. &#xA0;In my notebooks over the years, I find all of these topics covered in various and interesting ways. </p><p>Engineering has been defined in Merriam-Webster as: &quot;the design and manufacture of complex products&quot;. &#xA0;The Wikipedia universe currently defines &quot;software engineering&quot; as, &quot;the systematic application of engineering approaches to the development of software.&quot; It may also be my degree in aerospace engineering, that encourages me to approach this from a more scientific approach. But, there are no hard and fast rules for your own software engineering notebook. I&apos;m going to share what I&apos;ve done and you might adopt it for a while until you decide on how you want to change it up and make it personal for yourself. My format is not rigid and it is never &quot;done&quot;; it is forever changing in ways that I want to experiment.</p><p>In the past, however, I kept my software engineering notebook to myself, usually on my personal Atlassian Confluence Wiki. &#xA0;It&apos;s not pretty, but my notebook is just for me. &#xA0;But, I now realize that there might be times when my notes might be helpful to others. &#xA0;So, I&apos;m trying to migrate it to a more public format by using this Ghost blog. &#xA0;</p><p>My goal, however, remains the same - to &#xA0;capture notes for me. &#xA0;If they help you, great. &#xA0;If they confuse you, I&apos;m sorry, I may try to help you understand if you contact me, but then again, I&apos;m busy with a lot of my own projects and I may not have time. &#xA0;Again, these notes are for me.</p><p>Typical types of pages that I keep in my electronic notebook: Experiments, Course Notes, Future Blog Topics</p><p><strong>Experiments:</strong></p><p>While I am learning something new, or trying a new approach, I like to treat it loosely as an experiment. &#xA0;I like to capture the following as I&apos;m experimenting:</p><ul><li>The &quot;title&quot;: &#xA0;I often find that as I work through the problem, the title I originally assigned often morphs (becomes more specific) as I develop the solution. Naming the problem, like naming variables and functions in software, is often a challenging part of solving it.</li><li>The &quot;problem statement&quot;: &#xA0;More explanation of what I&apos;m trying to accomplish, what I want to learn, the question I&apos;m trying to answer, etc. &#xA0;</li><li>The <strong><em>initial conditions</em></strong> and <strong><em>assumptions</em></strong> that I&apos;m making. &#xA0;</li><li>The experiment itself: Documenting where the code (Git repo) and data lives, the commands I&apos;m issuing, and the results I get. &#xA0;I leave these in to show the chronological progression of my study. &#xA0;Rarely if ever do I delete them. &#xA0;I often include inline code blocks of command line commands, the results just get copied and pasted into the notebook. &#xA0;I&apos;ve found that many times as I progress through my experimentations, I misinterpreted the results and being able to review the chronological progress at how I arrived here, &#xA0;I&apos;m able to find the error. &#xA0;</li><li>Doing this also allows me to learn to diagnose these errors earlier. &#xA0;For example, how the operating system was trying to tell me one thing, but I misinterpreted it which lead me to an incorrect conclusion or a new hypothesis that I later proved wrong. &#xA0;I also include screenshots of the browser developer tools (e.g Console) output to show the results.</li><li>In addition, as I progress, I usually develop additional hypothesis, or experiments to try - while I&apos;m working on the current experiment. &#xA0;So, I capture all of these as I go. &#xA0;Some I may get to, others may live on until another day. Again, these notes are just for me.</li><li>Lessons learned: &#xA0;If the topic is sufficiently large or long, I will often summarize &quot;lessons learned&quot; at the top of the topic so that when I return to it, I have my own Cliff Notes (or abstract) for the topic. &#xA0;Tailored to what I didn&apos;t know and therefore were a gap.</li><li>References: I also include links to blogs, books, and conversations used to develop my understanding of the problem, possible approaches, and results that others have obtained.</li></ul><p><strong>Course Notes:</strong></p><p>When I take a course - Udemy, Pluralsight, Coursera, O&apos;Reilly, etc, I take a lot of notes. &#xA0;</p><ul><li>It helps me focus on the material rather. &#xA0;I also take screenshots of the lecture material or website information I find. </li><li>It helps me understand ideas and connect them with concepts from other instructors by making hyperlinks to other entries and discoveries I&apos;ve made.</li><li>It helps me retain what I learned, not only because the act of typing up the notes, helps make additional connections to other ideas, but it also allows me to return to it and scan it for the things that I didn&apos;t know.</li><li>It helps me clear that stuff out of my head knowing that I understand the concepts and I can get back to the details at any time reliably. </li></ul><p>The format I use is pretty simple (and although I&apos;m biased) quite logical:</p><ul><li>Course title</li><li>Author</li><li>Date the course was released (or last updated)</li><li>Date I started the course</li><li>Lessons learned (summary)</li><li>Chronological notes of each section; bulleted highlights</li></ul><p><strong>Blog Topics:</strong></p><ul><li>This lists the proposed idea, a couple sentences that could be compared to an &quot;abstract&quot;, and the date I entered it. </li></ul><p><strong>References:</strong></p><ul><li><a href="https://levelup.gitconnected.com/why-programmers-need-a-training-journal-edf2db5be44c">https://levelup.gitconnected.com/why-programmers-need-a-training-journal-edf2db5be44c</a></li><li><a href="https://www.sciencemag.org/careers/2019/09/how-keep-lab-notebook">https://www.sciencemag.org/careers/2019/09/how-keep-lab-notebook</a></li><li><a href="http://bryanpendleton.blogspot.com/2014/07/git-clone-vs-fork.html?m=1">http://bryanpendleton.blogspot.com/2014/07/git-clone-vs-fork.html?m=1</a></li><li><a href="https://benjaminhardy.com/how-to-write-in-your-journal-to-improve-yourself-and-achieve-your-goals/">https://benjaminhardy.com/how-to-write-in-your-journal-to-improve-yourself-and-achieve-your-goals/</a></li><li>akin to <strong><em>Bullet Journaling for Programmer</em></strong>s: <a href="http://www.jacqui.tk/prof-development/why-you-should-keep-a-code-journal-code-journaling-pt-1-of-4/">http://www.jacqui.tk/prof-development/why-you-should-keep-a-code-journal-code-journaling-pt-1-of-4/</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Udemy: Progressive Web Apps]]></title><description><![CDATA[<p>In the <a href="https://www.udemy.com/course/progressive-web-app-pwa-the-complete-guide/">Udemy: Progressive Web Apps (PWA)</a> course by Maximilian Schwarzmuller, Max outlines the following manual steps in Section 13: SPAs and PWAs, Lesson 203 to make a PWA out of any Angular application. &#xA0;However, they are a bit out of date (as he suggests that they may be)</p>]]></description><link>https://scottfred.org/udemy-progressive-web-apps/</link><guid isPermaLink="false">5fbafb4876e58345ebf0df2e</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Mon, 23 Nov 2020 00:06:26 GMT</pubDate><content:encoded><![CDATA[<p>In the <a href="https://www.udemy.com/course/progressive-web-app-pwa-the-complete-guide/">Udemy: Progressive Web Apps (PWA)</a> course by Maximilian Schwarzmuller, Max outlines the following manual steps in Section 13: SPAs and PWAs, Lesson 203 to make a PWA out of any Angular application. &#xA0;However, they are a bit out of date (as he suggests that they may be). &#xA0;For an updated (simplified) process of adding PWA to an Angular application, see <a href="https://scottfred.org/convert-angular-app-to-pwa/">my write-up</a>.</p><p><strong>Manual Steps:</strong></p><ul><li>Modify the angular-cli.json file: &#xA0;Add <code>serviceWorker&quot;: true,</code> in the apps[] portion of this file.</li><li>Add service worker package via npm</li><li>Max then highlights that in order to use Service Workers in Angular, we need to tell Angular to build this as a &quot;Production&quot; build.</li></ul><pre><code>npm install --save @angular/service-worker</code></pre><pre><code>ng build --prod</code></pre><p>Max goes on to explain that when we create a production build, the Angular CLI creates a couple of new files that suggest they are specific to the Service Workers. He also opens up the <code>ngsw-manifest.json</code><strong><em> </em></strong>file to see what is contained in it and explains that these files are all of this project&apos;s static assets (bundled, minified, etc). &#xA0;It&apos;s basically telling the Angular Service Worker that all of these files should be &quot;pre-cached&quot; (aka, &quot;pre-fetched&quot;?). &#xA0;There is a hash associated with each static asset filename which is used to identify when a new <strong><em>version</em></strong> of this static asset is available. </p><ul><li>Max also notes that the production build also creates a sw-register.xxx file that registers the Angular Service Worker with the application.</li><li>Max then points out the <code>worker-basic.min.js</code> file and says that this is the Service Worker package which is all setup and managed by the Service Worker.</li><li>Max then goes on to point out that the Assets (fonts, icons, etc) are missing at this point (if using his manual process of converting an Angular App to a PWA). To solve this, Max recommends creating an <code>ngsw-manifest.json</code> file at the Project Root directory (not to be confused with the <code>dist/ngsw-manifest.json</code> file that is automatically created by the Production build step). &#xA0;NOTE: When using the Angular CLI to add PWA functionality as described above, the CLI automatically creates a file called <code>ngsw-config.json</code> that appears to serve as the same functionality, but there are a lot of differences between these two files.</li><li>Next, Max talks about adding a <code>manifest.json</code> file to the <code>assets</code> folder and makes a copy of the content of a manifest file from somewhere into this file, but I don&apos;t know where he got it. &#xA0;Maybe he got it from the &quot;manifest.json&quot; file that he created in the &quot;Manifest&quot; Modules (A hint I see is that the &quot;Instagram as a Progressive Web App&quot; was the original application name) Yup, found it in <code>app-manifest-03--final.zip</code>? &#xA0;NOTE: In the Angular CLI automatic version (which presumably uses a Schematic to automate all of this), the equivalent file is the <code>src/manifest.webmanifest</code> file.</li><li>Finally, Max adds a <code>&lt;link \&gt;</code> line to add the manifest file to the <code>index.html</code> file.</li><li>Build the new Angular application (production) with the Service Worker information applied: <code>ng build --prod</code></li><li>Max suggests, however, that it&apos;s possible to use <code>ng serve --prod</code> but the Angular Documentation suggests that this is NOT possible. &#xA0;They say that we must use something like http-server instead. &quot;Because <code>ng serve</code> does not work with service workers, you must use a separate HTTP server to test your project locally.&quot; However, <code>ng serve --help</code> suggests that we should be able to use the <code>--prod</code> option because it is still available, but it doesn&apos;t say specifically that it supports service workers. &#xA0;Hmmm? </li></ul><p>Q?: Would the manual steps outlined by Max work for AngularJS applications too?</p>]]></content:encoded></item><item><title><![CDATA[Add PWA to an Angular App]]></title><description><![CDATA[<p>The <a href="https://angular.io/guide/service-worker-getting-started">Official Angular Docs</a> make it seem very easy to convert an existing Angular App to a PWA. &#xA0;To demonstrate this, I&apos;ll show how it&apos;s possible to take the generic Angular CLI application that is built with <code>ng new</code> and add PWA functionality to it</p>]]></description><link>https://scottfred.org/convert-angular-app-to-pwa/</link><guid isPermaLink="false">5fbad2bc76e58345ebf0dd8f</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Mon, 23 Nov 2020 00:05:48 GMT</pubDate><content:encoded><![CDATA[<p>The <a href="https://angular.io/guide/service-worker-getting-started">Official Angular Docs</a> make it seem very easy to convert an existing Angular App to a PWA. &#xA0;To demonstrate this, I&apos;ll show how it&apos;s possible to take the generic Angular CLI application that is built with <code>ng new</code> and add PWA functionality to it (based on <a href="https://angular.io/guide/service-worker-getting-started">notes</a> from the official Angular documentation).</p><p>First, start by creating a new Angular CLI project:</p><pre><code>$ ng new &lt;project-name&gt;
$ cd &lt;project-name&gt;</code></pre><p>Next, add the Angular PWA (Service Worker) functionality:</p><pre><code># long form docker command
docker run --rm -it -v $(pwd):/app angular-util:10.2.0 ng add @angular/pwa --project &lt;project-name&gt;

# or, with Angular CLI installed on your machine, 
# or, with alias ng=&apos;docker run --rm -it -v $(pwd):/app angular-util:10.2.0 ng&apos;
$ ng add @angular/pwa --project &lt;project-name&gt;</code></pre><p>NOTE: If you are interested in learning more about the Docker Container that I&apos;m using above (rather than installing the Angular CLI on your host machine), you can read my blog post about <a href="https://scottfred.org/building-and-using-utility-containers/">Docker Utility Containers</a>.</p><p>Q?: &#xA0;In the <code>ng add</code> command above, is <code>--project &lt;project-name&gt;</code> really required?</p><p>Performing this step to a newly created (default) Angular application results in the following files being modified and created.</p><pre><code>$ git s
On branch master
Changes not staged for commit:
  (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)
  (use &quot;git restore &lt;file&gt;...&quot; to discard changes in working directory)
	modified:   angular.json
	modified:   package-lock.json
	modified:   package.json
	modified:   src/app/app.module.ts
	modified:   src/index.html

Untracked files:
  (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)
	ngsw-config.json
	src/assets/icons/
	src/manifest.webmanifest</code></pre><p>Using a Dockerized Angular environment, this newly created PWA can then be built and served using the following commands:</p><pre><code># using long form
$ docker run --rm -it -v $(pwd):/app angular-util:10.2.0 ng build --prod

# or, with Angular CLI installed on your machine, 
# or, using angular-cli specific alias
# with alias ng=&apos;docker run --rm -it -v $(pwd):/app angular-util:10.2.0 ng&apos;
$ ng build --prod

# or, using generic angular-util image (NodeJS, Angular, npm, yarn, etc)
# with alias ngi=&apos;docker run --rm -it -v $(pwd):/app angular-util:10.2.0&apos;
$ ngi ng build --prod

chunk {} runtime.acf0dec4155e77772545.js (runtime) 1.45 kB [entry] [rendered]
chunk {1} main.a2f2f2ba868f42fbe918.js (main) 225 kB [initial] [rendered]
chunk {2} polyfills.35a5ca1855eb057f016a.js (polyfills) 36 kB [initial] [rendered]
chunk {3} styles.09e2c710755c8867a460.css (styles) 0 bytes [initial] [rendered]
Date: 2020-11-22T22:50:56.978Z - Hash: 73ad25d26b84753bcc89 - Time: 22633ms
</code></pre><p>Finally, the PWA can be served via:</p><pre><code>$ docker run --rm -it -v $(pwd)/dist/:/app -p 8080:8080 angular-util:10.2.0 npx http-server ./cli-spa/</code></pre><p>Another important note about hosting PWAs is that <a href="https://angular.io/guide/service-worker-getting-started#initial-load">they must be served over an HTTPS connection</a> when deployed anywhere other than <code>localhost</code>! </p>]]></content:encoded></item><item><title><![CDATA[Git and Remotes]]></title><description><![CDATA[<h3 id="lessons-learned-">Lessons learned :</h3><ul><li>When using SSH as the protocol to interact with the Git repository, make sure you include the &quot;.git&quot; suffix as part of the URL specification to the &quot;git remote add&quot; command. &#xA0;You can verify this by using <strong><em>git remote -v </em></strong>and look for</li></ul>]]></description><link>https://scottfred.org/git-and-remotes/</link><guid isPermaLink="false">5faf181676e58345ebf0d809</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Sat, 14 Nov 2020 00:06:28 GMT</pubDate><content:encoded><![CDATA[<h3 id="lessons-learned-">Lessons learned :</h3><ul><li>When using SSH as the protocol to interact with the Git repository, make sure you include the &quot;.git&quot; suffix as part of the URL specification to the &quot;git remote add&quot; command. &#xA0;You can verify this by using <strong><em>git remote -v </em></strong>and look for <strong><em>.git</em></strong> suffix. &#xA0;</li></ul><pre><code class="language-bash">$ git remote add origin git@gitlab.com:&lt;namespace&gt;/&lt;repo&gt;.git

$ git remote -v
origin	git@gitlab.com:&lt;namespace&gt;/testrepo.git (fetch)
origin	git@gitlab.com:&lt;namespace&gt;/testrepo.git (push)</code></pre><ul><li>For a visual, pattern-matching rule of thumb, if the git remote URL starts with <strong>git</strong>, it needs to end with .<strong>git</strong>. &#xA0;(Otherwise, it is an HTTP protocol and it should not end in .git)</li><li>When setting the upstream connection for a branch, use &quot;git push -u [--set-upstream]&quot;:</li></ul><pre><code class="language-bash">$ git push -u &lt;remote-URL.git&gt; &lt;branch&gt; # -- or 
$ git push --set-upstream &lt;remote-URL.git&gt; &lt;branch&gt;

# for example
$ git push -u git@gitlab.com:&lt;namespace&gt;/testrepo.git master

# or, rely on a remote alias (as &quot;origin&quot; set above)
$ git push -u origin master</code></pre><ul><li>When using the command line, it&apos;s better to be explicit about which remote and what branch rather than rely on Git defaults for things like push, pull, etc</li></ul><pre><code class="language-bash">$ git push origin master</code></pre><p><strong>It&apos;s possible to do the following to create a new GitLab project from the command line:</strong></p><pre><code class="language-bash">$ mkdir testrepo
$ cd !$
$ git init
$ git remote add origin git@gitlab.com:&lt;namespace&gt;/&lt;project&gt;.git

... work, git add, git commit
$ git push -u origin master

# verify upstream branch is configured
$ git branch -vv
* master 96d323a [origin/master] :tada: fixed

# more validation of the repo config
$ more .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote &quot;origin&quot;]
	url = git@gitlab.com:&lt;namespace&gt;/testrepo.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch &quot;master&quot;]
	remote = origin
	merge = refs/heads/master</code></pre><h3 id="notes-">Notes:</h3><ul><li>By default the repo will be created in GtiLab as a &quot;private&quot; project. &#xA0;This can be changed later.</li><li>When using the HTTP protocol to interact with the Git Repo, you do NOT include the &quot;.git&quot; suffix as part of the &lt;URL&gt;. &#xA0;But, when using SSH protocol you MUST include the &quot;.git&quot; suffix as part of the &lt;URL&gt;. &#xA0;</li><li>A lot of the <a href="https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes">git-scm documentation</a> mixes the use of https vs ssh. &#xA0;So, if you&apos;re not paying attention, you may miss this subtlety.</li></ul><h3 id="questions-">Questions:</h3><ul><li>Can we set upstream repos/branches for each branch? &#xA0;(I&apos;m pretty sure we can, but I need to verify.) &#xA0;</li></ul><h3 id="references-">References: </h3><ul><li><a href="https://docs.gitlab.com/ee/gitlab-basics/create-project.html#push-to-create-a-new-project">https://docs.gitlab.com/ee/gitlab-basics/create-project.html#push-to-create-a-new-project</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Building and Using Utility Containers]]></title><description><![CDATA[<p>I first heard the phrase, &quot;utility containers&quot; from Maximilian Schwarzmuller from <a href="https://academind.com/">Academind</a>, via his excellent course on Udemy, <a href="https://www.udemy.com/course/docker-kubernetes-the-practical-guide/"><em>Docker and Kubernetes: The Practical Guide</em></a>. &#xA0;But, the goal of building &quot;utility containers&quot; has been something I have worked to &#xA0;integrate into my software development workflow</p>]]></description><link>https://scottfred.org/building-and-using-utility-containers/</link><guid isPermaLink="false">5fa406f776e58345ebf0d509</guid><dc:creator><![CDATA[Scott Fredericksen]]></dc:creator><pubDate>Thu, 05 Nov 2020 15:27:20 GMT</pubDate><content:encoded><![CDATA[<p>I first heard the phrase, &quot;utility containers&quot; from Maximilian Schwarzmuller from <a href="https://academind.com/">Academind</a>, via his excellent course on Udemy, <a href="https://www.udemy.com/course/docker-kubernetes-the-practical-guide/"><em>Docker and Kubernetes: The Practical Guide</em></a>. &#xA0;But, the goal of building &quot;utility containers&quot; has been something I have worked to &#xA0;integrate into my software development workflow for a couple of years. &#xA0;The promise of the perfect containerized environment, to eliminate interactions between software installed on the bare metal hosts (e.g. past frustrations of python 2 and python 3) has been alluring.</p><p>What Max did for me was introduce the idea of a &quot;utility container&quot;. &#xA0;I then considered using them to be the primary tool to bootstrap a project such as &quot;npm init&quot; or &quot;ng new project&quot;.</p><p>I then realized that this is very similar to what the AWS CLI team had produced with their <a href="https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-docker.html">Dockerized AWS CLI tool</a>. &#xA0;Their simple idea of using an Alias with their dockerized AWS CLI tool solidified what I had wanted to achieve all along, which was to be able to simply type: &quot;npm init&quot; from the command line and have a dockerized Node to run.</p><p>Before the Dockerized version of AWS CLI tool was available, installing the AWS CLI was <a href="https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html">a lengthy process</a> of ensuring we met the pre-requisites, using &quot;curl&quot; to download the code, unzipping, running an install script which also installed Python because it is dependent on it. &#xA0;Similarly, in order to update to a newer version, we had to uninstall, unlink software, etc, etc. &#xA0;</p><p>Using Docker containers is so much cleaner to just about everything!</p><h3 id="prerequisites-">Prerequisites:</h3><ul><li>Docker 19.03.13 (or newer) installed</li></ul><h3 id="installing-the-software-">&quot;Installing&quot; The Software:</h3><ul><li>Consider, this new process to <strong><em>install</em></strong> an Angular development environment, e.g. Angular utility container.</li></ul><figure class="kg-card kg-code-card"><pre><code class="language-dockerfile">FROM node:14.15.0

RUN npm install -g @angular/cli@10.2.0

USER node
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH</code></pre><figcaption>Dockerfile</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language- bash">$ build docker -t angular-util:10.2.0 . # don&apos;t forget the dot (.)</code></pre><figcaption>Build the Docker image</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-bash">$ alias ng=&quot;docker run -it --rm -v ~/.gitconfig:/home/node/.gitconfig \
  -v $(pwd):/app angular-util:10.2.0 ng&quot;
$ alias ts-node=&quot;docker run -it --rm -v $(pwd):/app  \
  angular-util:10.2.0 ts-node&quot;
$ alias node=&quot;docker run -it --rm -v $(pwd):/app \
  angular-util:10.2.0 node&quot;</code></pre><figcaption>Create a couple of aliases (put these in your shell startup script)</figcaption></figure><h3 id="usage-">Usage:</h3><p>Create (&quot;initialize&quot;, &quot;bootstrap&quot;) a cool new Angular Project, without having Node and Angular installed on your bare metal system:</p><pre><code class="language-bash">$ ng new &lt;proejct name&gt;
...
$ cd &lt;project name&gt;</code></pre><p>Other examples:</p><pre><code class="language-bash">$ node --version
v14.15.0
$ npm --version
6.14.8
$ yarn --version
1.22.5</code></pre><p>Initialize a NodeJS backend:</p><pre><code class="language-bash">$ mkdir backend
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install &lt;pkg&gt;` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (app) backend
version: (1.0.0) 
description: Testing docker
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /app/package.json:

{
  &quot;name&quot;: &quot;backend&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;Testing docker&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;
  },
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;
}


Is this OK? (yes)

$ ll
total 12
drwxr-xr-x 2 scott scott 4096 Nov  5 08:18 ./
drwxr-xr-x 3 scott scott 4096 Nov  5 08:18 ../
-rw-r--r-- 1 scott scott  217 Nov  5 08:17 package.json
</code></pre><p>Keep in mind that the intent of the use of this &quot;Utility Container&quot; is merely to Bootstrap the application. &#xA0;It is not enough to containerize the application itself. &#xA0;That should be done in a Dockerfile or Docker Compose yml file that resides within the application itself. &#xA0;This separates the functions of the containers.</p><h3 id="benefits-">Benefits:</h3><p>Notice that from this &quot;installation&quot;, we get the following software (all containerized into a nice, neat little package that&apos;s not polluting our bare metal system):</p><ul><li>Node 14.15.0</li><li>NPM (packaged with Node)</li><li>Yarn (packaged with Node)</li><li>Angular CLI 10.2.0 development environment</li><li>TS-NODE (packaged with Angular CLI)</li><li>(many others...)</li></ul><p>Also note the other advantages:</p><ul><li>It&apos;s possible to quickly change to another Node or Angular version by simply changing out the :tag that&apos;s used</li><li>Changing the version does not mean that an entirely new Node or Angular image needs to be downloaded because of magic of Docker image layers which are provided via a <a href="https://medium.com/@jessgreb01/digging-into-docker-layers-c22f948ed612#:~:text=What%20are%20the%20layers%3F,during%20the%20Docker%20image%20build.">Union File System</a>. &#xA0;Only the differences between the versions of Node need to be downloaded, not an entirely new image.</li></ul><p>&quot;Using Union filesystems is <strong><strong>super cool</strong></strong> because they merge all the files for each image layer together and presents them as one single read-only directory at the union mount point. If there are duplicate files in different layers, the file on the higher level layer is what is displayed.&quot;</p><ul><li>As a best practice, it&apos;s best to take advantage of the Union File System capabilities (e.g. docker layers) if you can favor one base image for multiple environments. &#xA0;For example, using Node:14.15.0 for both the Node and Angular environments rather than mixing base images like Node:14.15.0 for <strong><em>node</em></strong> (backend api development) and Node:12.0.0 for <strong><em>Angular</em></strong><em>. &#xA0;</em>Docker will still union what it can together to be efficient, but we can help it if we try to stick to something consistent.</li></ul><h3 id="troubleshooting-">Troubleshooting:</h3><p>If you&apos;re on a Linux / Unix environment and you run into file ownership issues when you do things like &quot;npm init&quot; or &quot;ng new &lt;project&gt;&quot;, here are some steps you can use to overcome them:</p><p>The problem is most likely related to your Linux User not having User and Group Ids of 1000:1000. &#xA0;The Node team had to assume something when they built the image, so, that&apos;s what they went with. &#xA0;But, your user is likely not 1000:1000 if you are one of several people logged into a Linux server, rather than being the one and only user on a personal Linux system.</p><p>The fix is pretty simple; just a couple of modifications to the Dockerfile and the Docker build command - everything else stays the same.</p><figure class="kg-card kg-code-card"><pre><code class="language-dockerfile">FROM node:14.15.0

RUN userdel -r node

ARG USER_ID

ARG GROUP_ID

RUN addgroup --gid $GROUP_ID user

RUN adduser --disabled-password --gecos &apos;&apos; --uid $USER_ID --gid $GROUP_ID user

USER user

WORKDIR /app</code></pre><figcaption>Dockerfile modifications</figcaption></figure><pre><code class="language-bash">$ docker build -t node-util:cliuser --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) .</code></pre>]]></content:encoded></item></channel></rss>