<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-03-02T21:41:19+00:00</updated><id>/feed.xml</id><entry><title type="html">Switch your monitor inputs like a pro</title><link href="/posts/using-a-streamdeck-to-switch-multiple-monitor-inputs-at-the-touch-of-a-button/" rel="alternate" type="text/html" title="Switch your monitor inputs like a pro" /><published>2023-02-23T00:00:00+00:00</published><updated>2023-02-23T00:00:00+00:00</updated><id>/posts/using-a-streamdeck-to-switch-multiple-monitor-inputs-at-the-touch-of-a-button</id><content type="html" xml:base="/posts/using-a-streamdeck-to-switch-multiple-monitor-inputs-at-the-touch-of-a-button/">&lt;h1 id=&quot;productivity-enhancement---switch-your-monitor-inputs-like-a-pro-with-a-streamdeck&quot;&gt;Productivity enhancement - Switch your monitor inputs like a pro with a Streamdeck&lt;/h1&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;/h2&gt;

&lt;p&gt;I, like many people over the last 2 and a bit years, have been predominantly working from home. I run a triple monitor setup day to day, and have a company issued laptop for my work. I don’t have the option to work from any personal devices.&lt;/p&gt;

&lt;p&gt;Typically on a daily bases I use a &lt;a href=&quot;https://amzn.to/3Kzm4zj&quot; target=&quot;_new&quot;&gt;28” 4k monitor from V7&lt;/a&gt;, a &lt;a href=&quot;https://www.amazon.com/Dell-Multi-Client-Monitor-P4317Q-DisplayPort/dp/B06ZZ25ZZS&quot; target=&quot;_new&quot;&gt;43” 4k monitor from Dell&lt;/a&gt;, and lastly a &lt;a href=&quot;https://amzn.to/3EywN9n&quot; target=&quot;_new&quot;&gt;29” LG monitor&lt;/a&gt;. The latter stays mostly connected to my personal PC 99.95% of the time! The others are what I predominantly use for “work” generally.&lt;/p&gt;

&lt;p&gt;It doesn’t take long, but navigating the On-Screen Display (OSD) menu and swapping inputs, whilst not terribly time consuming, it takes maybe 5-6 seconds per monitor to switch inputs, providing I don’t fat finger the buttons and changing something else or selecting the wrong input! Sometimes this is multiple times a day especially if I leave for a period and come back and one or both monitors have decided to switch inputs from my work laptop to my personal PC.&lt;/p&gt;

&lt;p&gt;The way this is wired up is my work laptop is connected to a &lt;a href=&quot;https://amzn.to/3Kyuyqs&quot; target=&quot;_new&quot;&gt;Dell D6000 Dock&lt;/a&gt;, the I use the DisplayPort outputs from that and they go into the DisplayPort inputs on the monitors. Likewise, I have HDMI coming from my PC, going into the HDMI inputs.&lt;/p&gt;

&lt;p&gt;Whilst not necessary, I also have 2 GPU’s in my system, a &lt;a href=&quot;https://amzn.to/3Y1qUbI&quot;&gt;AMD Radeon RX580 8GB&lt;/a&gt; and a &lt;a href=&quot;https://amzn.to/3IrsG0e&quot; target=&quot;_new&quot;&gt;MSI NVIDIA GTX 970 4GB&lt;/a&gt; (check out &lt;a href=&quot;/posts/home-office-evolution/&quot; target=&quot;_new&quot;&gt;the evolution of my office&lt;/a&gt;, although its evolved more, and moved, maybe I should do another write up 😄).&lt;/p&gt;

&lt;h2 id=&quot;the-caveat&quot;&gt;The caveat&lt;/h2&gt;

&lt;p&gt;Whilst I have got lucky doing this, it is very much hardware dependent. Not just on your monitor, but also on your GPU, and maybe even your Operating System. This works for me on the hardware I’ve mentioned above, on Windows (10). This is definitely in the realm’s of &lt;code class=&quot;highlighter-rouge&quot;&gt;Your mileage may vary&lt;/code&gt; territory! I do have a 2016 Intel MacBook Pro, maybe I’ll do some more investigation sometime in the future.&lt;/p&gt;

&lt;p&gt;It may also be that once your monitor has switched inputs, it won’t listen from the device the Streamdeck is connected to, again, your mileage may very depending on what hardware you have.&lt;/p&gt;

&lt;h2 id=&quot;the-software&quot;&gt;The software&lt;/h2&gt;

&lt;p&gt;First things first, I wouldn’t have been able to do this without a piece of freeware called &lt;a href=&quot;https://www.nirsoft.net/utils/control_my_monitor.html&quot; target=&quot;_new&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ControlMyMonitor&lt;/code&gt;&lt;/a&gt; from &lt;a href=&quot;https://www.nirsoft.net/&quot; target=&quot;_new&quot;&gt;Nirsoft&lt;/a&gt; - if you don’t want to look at their site or documentation, here is the &lt;a href=&quot;https://www.nirsoft.net/utils/controlmymonitor.zip&quot;&gt;direct download link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once downloaded &amp;amp; unzipped, run the &lt;code class=&quot;highlighter-rouge&quot;&gt;ControlMyMonitor.exe&lt;/code&gt; program and you’ll see a screen like the below&lt;/p&gt;

&lt;p&gt;The two main items to pay notice to is the monitor selection dropdown, and &lt;code class=&quot;highlighter-rouge&quot;&gt;VCP 60&lt;/code&gt; which is the &lt;code class=&quot;highlighter-rouge&quot;&gt;input select&lt;/code&gt;, and the possible values it can have. Now each monitor is different so its very much trial and error to find out what value maps to which input.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2023-02-23-using-a-streamdeck-to-switch-multiple-monitor-inputs-at-the-touch-of-a-button/ControlMyMonitor-monitor-select.png&quot; alt=&quot;Screenshot of ControlMyMonitor software&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2023-02-23-using-a-streamdeck-to-switch-multiple-monitor-inputs-at-the-touch-of-a-button/ControlMyMonitor-highlighted.png&quot; alt=&quot;Screenshot of ControlMyMonitor software&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you have sussed out which number corresponds to which monitor, make a note of them.&lt;/p&gt;

&lt;h2 id=&quot;creating-a-batch-file&quot;&gt;Creating a batch file&lt;/h2&gt;

&lt;p&gt;The ‘secret sauce’ to making this work is the fact we can use this software as a command line tool also, and chain multiple commands to it. For instance, in my use case, to swap two monitors at the same time, I run the following command&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\path\to\controlmymonitor\ControlMyMonitor.exe /SetValue &quot;\\.\DISPLAY2\Monitor0&quot; 60 18 /SetValue &quot;\\.\DISPLAY1\Monitor0&quot; 60 8465
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Where the &lt;code class=&quot;highlighter-rouge&quot;&gt;DISPLAY2&lt;/code&gt; is what you get from the dropdown list, &lt;code class=&quot;highlighter-rouge&quot;&gt;60&lt;/code&gt; is the VCP code for &lt;code class=&quot;highlighter-rouge&quot;&gt;Input Select&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;18&lt;/code&gt; is the value for HDMI2 input on my machine for my PC. Likewise &lt;code class=&quot;highlighter-rouge&quot;&gt;8465&lt;/code&gt; is the value for HDMI on the other monitor.&lt;/p&gt;

&lt;p&gt;The next step is to then save this command into a &lt;code class=&quot;highlighter-rouge&quot;&gt;.bat&lt;/code&gt; file, open up your text editor, paste the command in and save it as a &lt;code class=&quot;highlighter-rouge&quot;&gt;.bat&lt;/code&gt; file.&lt;/p&gt;

&lt;h2 id=&quot;doing-the-magic-with-a-streamdeck&quot;&gt;Doing the magic with a Streamdeck&lt;/h2&gt;

&lt;p&gt;If you are the proud owner of an &lt;a href=&quot;https://amzn.to/3YWyFkD&quot; target=&quot;_new&quot;&gt;Elgato Streamdeck&lt;/a&gt; then the next step is to add a &lt;code class=&quot;highlighter-rouge&quot;&gt;Open&lt;/code&gt; command under &lt;code class=&quot;highlighter-rouge&quot;&gt;System&lt;/code&gt;. Select an icon, give it a title and point to the location of your &lt;code class=&quot;highlighter-rouge&quot;&gt;.bat&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2023-02-23-using-a-streamdeck-to-switch-multiple-monitor-inputs-at-the-touch-of-a-button/Streamdeck.png&quot; alt=&quot;Screenshot of Elgato Streamdeck software&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Thats it, done!&lt;/p&gt;

&lt;p&gt;Here’s a video of it in action (ignore the background audio, that wasn’t related (missus and the 3 year old were in the other room))!&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; data-lang=&quot;en&quot; data-theme=&quot;dark&quot;&gt;&lt;p lang=&quot;zxx&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://t.co/8yFNqKHRGA&quot;&gt;pic.twitter.com/8yFNqKHRGA&lt;/a&gt;&lt;/p&gt;&amp;mdash; Chris Jones (@cmjchrisjones) &lt;a href=&quot;https://twitter.com/cmjchrisjones/status/1628762325053239296?ref_src=twsrc%5Etfw&quot;&gt;February 23, 2023&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In conclusion, you don’t really need to use a Streamdeck, you could just use your mouse to double click on the &lt;code class=&quot;highlighter-rouge&quot;&gt;.bat&lt;/code&gt; file, setup a keyboard shortcut or macro. You could also potentially use the Streamdeck mobile app. This for me, whilst a tiny one, feels like a small quality of life improvement to easily swap between inputs on my monitors at a push of a button.&lt;/p&gt;

&lt;p&gt;Hope someone finds this useful, if you do, reply to the tweet above and let me know 😄&lt;/p&gt;</content><author><name>Chris</name></author><category term="Productivity" /><category term="Productivity" /><category term="Streamdeck" /><category term="Enhancements" /><category term="Monitors" /><category term="Windows" /><category term="Input Switching" /><category term="HDMI" /><category term="DisplayPort" /><category term="Elgato" /><category term="Hotkey" /><category term="Input Select" /><summary type="html">Productivity enhancement - Switch your monitor inputs like a pro with a Streamdeck</summary></entry><entry><title type="html">ISP != WiFi coverage</title><link href="/posts/isp-does-not-equal-wifi-coverage/" rel="alternate" type="text/html" title="ISP != WiFi coverage" /><published>2020-07-23T00:00:00+00:00</published><updated>2020-07-23T00:00:00+00:00</updated><id>/posts/isp-does-not-equal-wifi-coverage</id><content type="html" xml:base="/posts/isp-does-not-equal-wifi-coverage/">&lt;h1 id=&quot;my-wifi-sucks---lets-change-service-providers&quot;&gt;My WiFi sucks - lets change service providers&lt;/h1&gt;

&lt;p&gt;OK, that me be a bit blunt but since the start of the lockdown due to Covid-19 - I’ve seen more and more people complaining on local facebook groups that their WiFi isn’t brilliant or sub-optimal - and were looking for other suppliers.&lt;/p&gt;

&lt;p&gt;However - I’m fortunate enough to be &lt;code class=&quot;highlighter-rouge&quot;&gt;techy&lt;/code&gt; enough to know some things which can somewhat help with this - and rather than keep posting various bits and bobs - I thought I’d sling it in a quick blog post so I can reference here instead!&lt;/p&gt;

&lt;h2 id=&quot;what-affects-my-wifi-signal&quot;&gt;What affects my WiFi signal&lt;/h2&gt;

&lt;p&gt;Well, lots of things actually.&lt;/p&gt;

&lt;p&gt;Depending on the router you have (that is the device that your outside line plugs into), if you’re on a cable service (VirginMedia in the UK) then typically this would come in at the same point as your VirginTV box so is probably situated in your living room). If you have ADSL style broadband (that is done via your telephone line, so BT, Sky, TalkTalk etc), its probably close to where your internal telephone socket comes into the property (do people still use landlines)?!&lt;/p&gt;

&lt;p&gt;The location of your router and where you are, over WiFi is important - WiFi is done over radio waves, the more obstacles between you and the point of origin (the router), and other devices on your network which are using WiFi, cause interference and will weaken your WiFi range.&lt;/p&gt;

&lt;p&gt;Therefore moving your ISP (Internet Service Provider) won’t necessarily fix your problem. You might improve it slightly, but it will be negligible.&lt;/p&gt;

&lt;p&gt;Something else that can cause interference can be what channel your WiFi is being broadcast on. If your neighbour is also broadcasting on the same channel - this can also hurt. A lot of newer routers though have autochannel hopping so may not be something to be concerned about.&lt;/p&gt;

&lt;h2 id=&quot;so-what-are-the-options&quot;&gt;So, what are the options?&lt;/h2&gt;

&lt;p&gt;That all depends on your use case / what you’re using / budget etc.&lt;/p&gt;

&lt;p&gt;If you’re working from home and are lucky enough to have a dedicated corner/room for your working - if you’re not near the router and therefore running a hard wired network connection from your router to your device is not an option, have a look at Powerline adaptors. They are plug in devices that use standard electrical sockets.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-23-ISP-does-not-equal-wifi-coverage/Powerline.png&quot; alt=&quot;Powerline Adapter&quot; class=&quot;smaller-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;They use your existing electrical wiring, you plug one in near your router and plug an ethernet cable from your router into the plug. Then the other one from a plug socket near your device and run an ethernet cable from that to your device.&lt;/p&gt;

&lt;p&gt;If you have limited plug sockets, you can get ‘passthrough’ sockets - this just has a socket on the front so you don’t loose a socket.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-23-ISP-does-not-equal-wifi-coverage/Powerline-with-passthrough.png&quot; alt=&quot;Powerline Adapter with passthrough&quot; class=&quot;smaller-image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;are-there-other-options&quot;&gt;Are there other options?&lt;/h2&gt;

&lt;p&gt;Yes. Another option is a WiFi repeater/range extender. You plug these in again to a standard electrical wall socket on the edge of ‘dead zones’ but where you’d still get a faint WiFi signal. This then boosts the signal extending the reach.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-23-ISP-does-not-equal-wifi-coverage/WiFi-Repeater.png&quot; alt=&quot;WiFi Repeater&quot; class=&quot;smaller-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also, check if you have the latest hardware from your ISP. If you’ve been with them a while -  there maybe hardware (router) upgrades - maybe its worth calling them to ask - technology is advancing rather quickly so if you’ve not had a new router in the last couple of years - its worth a punt.&lt;/p&gt;

&lt;p&gt;You could also buy your own dedicated router - you can spend a fair chunk on money of better/decent routers - these are designed to be the best they can be - the ones you get provided by your ISP aren’t, think of it like a courtesy car from a garage - you’ll never likely get a Bentley Continental when a Ford Ka will do!&lt;/p&gt;

&lt;p&gt;Another option is Mesh Networks - this is something to look into, but I haven’t yet - therefore I can’t form an opinion but just leaving it here as an option for someone to look into - maybe I’ll do some research and be able to come back and update this post in the future!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-23-ISP-does-not-equal-wifi-coverage/dedicated-mesh-router.png&quot; alt=&quot;Mesh/Dedicated Router&quot; class=&quot;smaller-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hopefully this might give people some things to think about if they’re facing problems with their WiFi.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;h2 id=&quot;more-reading&quot;&gt;More reading&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://ccm.net/faq/298-what-is-wifi-and-how-does-it-work&quot; target=&quot;_new&quot;&gt;How WiFi Works&lt;/a&gt;&lt;/p&gt;</content><author><name>Chris</name></author><category term="Information, ISP, WiFi" /><category term="Internet" /><category term="WiFi" /><category term="ISP" /><category term="Internet Service Provider" /><summary type="html">My WiFi sucks - lets change service providers OK, that me be a bit blunt but since the start of the lockdown due to Covid-19 - I’ve seen more and more people complaining on local facebook groups that their WiFi isn’t brilliant or sub-optimal - and were looking for other suppliers. However - I’m fortunate enough to be techy enough to know some things which can somewhat help with this - and rather than keep posting various bits and bobs - I thought I’d sling it in a quick blog post so I can reference here instead! What affects my WiFi signal Well, lots of things actually. Depending on the router you have (that is the device that your outside line plugs into), if you’re on a cable service (VirginMedia in the UK) then typically this would come in at the same point as your VirginTV box so is probably situated in your living room). If you have ADSL style broadband (that is done via your telephone line, so BT, Sky, TalkTalk etc), its probably close to where your internal telephone socket comes into the property (do people still use landlines)?! The location of your router and where you are, over WiFi is important - WiFi is done over radio waves, the more obstacles between you and the point of origin (the router), and other devices on your network which are using WiFi, cause interference and will weaken your WiFi range. Therefore moving your ISP (Internet Service Provider) won’t necessarily fix your problem. You might improve it slightly, but it will be negligible. Something else that can cause interference can be what channel your WiFi is being broadcast on. If your neighbour is also broadcasting on the same channel - this can also hurt. A lot of newer routers though have autochannel hopping so may not be something to be concerned about. So, what are the options? That all depends on your use case / what you’re using / budget etc. If you’re working from home and are lucky enough to have a dedicated corner/room for your working - if you’re not near the router and therefore running a hard wired network connection from your router to your device is not an option, have a look at Powerline adaptors. They are plug in devices that use standard electrical sockets. They use your existing electrical wiring, you plug one in near your router and plug an ethernet cable from your router into the plug. Then the other one from a plug socket near your device and run an ethernet cable from that to your device. If you have limited plug sockets, you can get ‘passthrough’ sockets - this just has a socket on the front so you don’t loose a socket. Are there other options? Yes. Another option is a WiFi repeater/range extender. You plug these in again to a standard electrical wall socket on the edge of ‘dead zones’ but where you’d still get a faint WiFi signal. This then boosts the signal extending the reach. Also, check if you have the latest hardware from your ISP. If you’ve been with them a while - there maybe hardware (router) upgrades - maybe its worth calling them to ask - technology is advancing rather quickly so if you’ve not had a new router in the last couple of years - its worth a punt. You could also buy your own dedicated router - you can spend a fair chunk on money of better/decent routers - these are designed to be the best they can be - the ones you get provided by your ISP aren’t, think of it like a courtesy car from a garage - you’ll never likely get a Bentley Continental when a Ford Ka will do! Another option is Mesh Networks - this is something to look into, but I haven’t yet - therefore I can’t form an opinion but just leaving it here as an option for someone to look into - maybe I’ll do some research and be able to come back and update this post in the future! Hopefully this might give people some things to think about if they’re facing problems with their WiFi. Thanks for reading. More reading How WiFi Works</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="/assets/post-images/2020-07-23-ISP-does-not-equal-wifi-coverage/hero.png" /></entry><entry><title type="html">Contributing to someone else’s git repository</title><link href="/posts/contributing-to-someone-elses-git-repository/" rel="alternate" type="text/html" title="Contributing to someone else's git repository" /><published>2020-07-20T00:00:00+00:00</published><updated>2020-07-20T00:00:00+00:00</updated><id>/posts/contributing-to-someone-elses-git-repository</id><content type="html" xml:base="/posts/contributing-to-someone-elses-git-repository/">&lt;p&gt;So I’ve had the idea to write this blog post for a while, and I’ve just found a repository that I would like to contribute a change to, so I’m going to document the process I follow right here, hoping it might be of use to some folks in the future!&lt;/p&gt;

&lt;p&gt;The repository I would like to make a change to is one from Twilio, it contains a default .NET Core starter app, and can be found over at &lt;a href=&quot;https://github.com/twilio/starter-dotnet-core&quot; target=&quot;_new&quot;&gt;https://github.com/twilio/starter-dotnet-core&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason I want to make a change is because I started to play their addictive &lt;a href=&quot;https://www.twilio.com/quest&quot; target=&quot;_new&quot;&gt;TwilioQuest&lt;/a&gt; game, and being a .NET dev, I of course was going to choose that as my language of choice.&lt;/p&gt;

&lt;p&gt;However, after I cloned the repository  and tried running it, I got an error because it was targeting netcoreapp2.2, and because I didn’t have that installed the build of the solution failed. Why is that bad you may ask? Well, because Microsoft announced that .NET Core 2.2.x will reach end of life on 23rd December 2020, about 5 months from when I wrote this article.&lt;/p&gt;

&lt;p&gt;I had a quick look around the repository , a couple of issues were open, no Pull Requests were outstanding, I thought this might be something fun to do, will help out an open source project and keep it up to date, and also give me a target for using to write this post! So without further ado, lets get started.&lt;/p&gt;

&lt;h2 id=&quot;how-do-we-get-the-code-so-we-can-edit-it&quot;&gt;How do we get the code so we can edit it&lt;/h2&gt;

&lt;p&gt;First things first, we need to create our own version of the repository , on GitHub (and maybe others like GitLab, BitBucket, Azure Repos) this is called Forking. It creates a clone of the repository from the original authors account and puts a copy under yours, all you need to do is simply click the &lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_Fork_Button.png&quot; alt=&quot;&quot; title=&quot;Fork Button in GitHub&quot; /&gt; button, normally found on the top right of the page. Don’t worry if you see a different number - that is just how many people prior have forked the repository.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_repo_before_fork.png&quot; alt=&quot;&quot; title=&quot;Their GitHub before we fork it&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You should see a little splash screen, then after a few seconds you should be jumped into your very own version of the repository&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_repo_fork_splash_screen.png&quot; alt=&quot;&quot; title=&quot;GitHubs fork splash screen&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At first glance it might not look like anything has happened! The commit messages, dates etc are still the same, but look at the difference in the top left, we went from &lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_their_title.png&quot; alt=&quot;&quot; title=&quot;Their GitHub repository  address&quot; /&gt; to &lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_our_title.png&quot; alt=&quot;&quot; title=&quot;Our GitHub repository address&quot; /&gt; in the blink of an eye!&lt;/p&gt;

&lt;h2 id=&quot;lets-get-the-code-locally&quot;&gt;Lets get the code locally&lt;/h2&gt;

&lt;p&gt;The next step, and one which hopefully you should be fairly familiar with, is cloning your newly forked repository onto your local machine, I typically use the command line for git commands I know well, such as cloning, so I’ll open up a command prompt, navigate to somewhere where I typically store my code files, and I’ll do a&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/cmjchrisjones/starter-dotnet-core.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(notice its coming from my GitHub account and not Twilios).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/CMD_clone.png&quot; alt=&quot;&quot; title=&quot;Cloning the repository on the command line&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next we’ll change into the directory, and check where our origin is by running&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/CMD_after_clone_and_remote.png&quot; alt=&quot;&quot; title=&quot;Checking the remote branch&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;now-were-ready-to-make-some-changes&quot;&gt;Now we’re ready to make some changes&lt;/h2&gt;

&lt;p&gt;Typically its bad to commit anything directly against the source repositories main source branch, therefore its better to create your own branch, I’m going to call mine something descriptive for my change, but also something which isn’t too long - &lt;code class=&quot;highlighter-rouge&quot;&gt;update-to-net-core-3.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Some repositories may have naming standards or guidelines, its always worth seeing if a repository has a &lt;code class=&quot;highlighter-rouge&quot;&gt;CONTRIBUTING.md&lt;/code&gt; file in the root of the repository.&lt;/p&gt;

&lt;p&gt;Now were free to make our changes.&lt;/p&gt;

&lt;p&gt;The changes I’ve made are out of scope for this post, but if you really want you can go and check out the repository mentioned above.&lt;/p&gt;

&lt;p&gt;Looking the at the GIT GUI’s I use, you can see the changes/commit I’ve made&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GIT_GUI_GitExtensions.png&quot; alt=&quot;&quot; title=&quot;Commits - GIT GUI - GitExtensions&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GIT_GUI_Fork.png&quot; alt=&quot;&quot; title=&quot;Commits - GIT GUI - Fork&quot; /&gt;&lt;/p&gt;

&lt;p&gt;or via the command line&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/CMD_git_log.png&quot; alt=&quot;&quot; title=&quot;Commits - command line&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;pushing-our-code-to-our-version-of-the-repository&quot;&gt;Pushing our code to our version of the repository&lt;/h2&gt;

&lt;p&gt;So  now we have our changes all committed locally, its time to push our changes to our copy of the repository , I’ll run the following command&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git push &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; origin update-to-net-core-3.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/CMD_git_push.png&quot; alt=&quot;&quot; title=&quot;Pushing our local changes to our fork&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And if we now take a look at our GitHub repository , we can see there is a new message saying a new branch was pushed and we can do a &lt;code class=&quot;highlighter-rouge&quot;&gt;compare and pull request&lt;/code&gt;, lets hit that button&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_ours_after_push.png&quot; alt=&quot;&quot; title=&quot;Our repository on GitHub after we pushed our changes&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;submitting-a-pull-request-pr&quot;&gt;Submitting a Pull Request (PR)&lt;/h2&gt;

&lt;p&gt;Clicking that button takes us to a page where we can create a Pull Request message which is where we can describe what/why the changes were made as well as viewing the changes side by side&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_create_pull_request.png&quot; alt=&quot;&quot; title=&quot;GitHub compare changes for Pull Request&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can also target which branch of the remote (their) repository we want to target, because they only have a master branch that will be the branch we want our changes merged into&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_pull_request_target_branch.png&quot; alt=&quot;&quot; title=&quot;Targeting branch for Pull Request to be merged into&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you’re happy with the changes you’ve made and your commit/pull request message, its time to create the Pull Request by clicking on the &lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_create_pull_request_button.png&quot; alt=&quot;&quot; title=&quot;Create Pull Request Button&quot; /&gt;
Button. And Voila, a PR is now raised against the origin repository.&lt;/p&gt;

&lt;p&gt;You can see the raised PR over at &lt;a href=&quot;https://github.com/twilio/starter-dotnet-core/pull/3&quot; target=&quot;_new&quot;&gt;https://github.com/twilio/starter-dotnet-core/pull/3&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;adding-a-second-remote&quot;&gt;Adding a second remote&lt;/h2&gt;

&lt;p&gt;So you may also be asking, ok, so when/if our changes get approved, that will go into the remote branch, how do I keep my version up to date?&lt;/p&gt;

&lt;p&gt;Well, this is where adding a 2nd remote comes in handy.&lt;/p&gt;

&lt;p&gt;Simply run&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote add upstream &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;the url of the original repository &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;for example in this case I would do&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote add upstream https://github.com/twilio/starter-dotnet-core
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;now if I run &lt;code class=&quot;highlighter-rouge&quot;&gt;git remote -v&lt;/code&gt; again, I’ll see I have 2 remotes, origin (mine) and upstream (theirs).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/CMD_add_second_remote.png&quot; alt=&quot;&quot; title=&quot;Adding a second remote&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-keep-our-repository-up-to-date-with-the-upstream-aka---the-parent-repository&quot;&gt;How to keep our repository up to date with the ‘upstream’ aka - the parent repository&lt;/h2&gt;

&lt;p&gt;So, lets say they have merged our change in, or someone else’s changes, how would I update my version?&lt;/p&gt;

&lt;p&gt;There might be better and/or easier ways, but what I do is this - I’m using a slightly different repository here so I can show the relevant screen shots, as you can see, on another repository I have previously forked on GitHub, I’m a few commits behind on the vNext branch.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_local_behind_remote.png&quot; alt=&quot;&quot; title=&quot;GitHub showing us we're a bit behind&quot; /&gt;&lt;/p&gt;

&lt;p&gt;so, I’ll go to where I have the code cloned on my system, and I’ll checkout the branch I want to update (in this case, its &lt;code class=&quot;highlighter-rouge&quot;&gt;vNext&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Then I’ll pull any changes from the upstream remote version of that branch by running&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git pull upstream vNext
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After that has finished, as long as there weren’t any merge conflicts, I’ll push that updated local version to our forked repository - and hopefully GitHub will show they are now in sync&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/GitHub_upto_date.png&quot; alt=&quot;&quot; title=&quot;GitHub's in sync&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And with that, that concludes the walk-through of contributing to someone else’s repository, and keeping your version up to date. I hope you found this guide somewhat helpful.&lt;/p&gt;</content><author><name>Chris</name></author><category term="Walkthroughs" /><category term="Git" /><category term="GitHub" /><category term="Contributing" /><category term="Forking" /><category term="Branching" /><category term="OSS" /><category term="Open Source" /><category term="Twilio" /><category term="TwilioQuest" /><category term="Tutorials &amp; Walkthroughs" /><summary type="html">So I’ve had the idea to write this blog post for a while, and I’ve just found a repository that I would like to contribute a change to, so I’m going to document the process I follow right here, hoping it might be of use to some folks in the future! The repository I would like to make a change to is one from Twilio, it contains a default .NET Core starter app, and can be found over at https://github.com/twilio/starter-dotnet-core The reason I want to make a change is because I started to play their addictive TwilioQuest game, and being a .NET dev, I of course was going to choose that as my language of choice. However, after I cloned the repository and tried running it, I got an error because it was targeting netcoreapp2.2, and because I didn’t have that installed the build of the solution failed. Why is that bad you may ask? Well, because Microsoft announced that .NET Core 2.2.x will reach end of life on 23rd December 2020, about 5 months from when I wrote this article. I had a quick look around the repository , a couple of issues were open, no Pull Requests were outstanding, I thought this might be something fun to do, will help out an open source project and keep it up to date, and also give me a target for using to write this post! So without further ado, lets get started. How do we get the code so we can edit it First things first, we need to create our own version of the repository , on GitHub (and maybe others like GitLab, BitBucket, Azure Repos) this is called Forking. It creates a clone of the repository from the original authors account and puts a copy under yours, all you need to do is simply click the button, normally found on the top right of the page. Don’t worry if you see a different number - that is just how many people prior have forked the repository. You should see a little splash screen, then after a few seconds you should be jumped into your very own version of the repository At first glance it might not look like anything has happened! The commit messages, dates etc are still the same, but look at the difference in the top left, we went from to in the blink of an eye! Lets get the code locally The next step, and one which hopefully you should be fairly familiar with, is cloning your newly forked repository onto your local machine, I typically use the command line for git commands I know well, such as cloning, so I’ll open up a command prompt, navigate to somewhere where I typically store my code files, and I’ll do a git clone https://github.com/cmjchrisjones/starter-dotnet-core.git (notice its coming from my GitHub account and not Twilios). Next we’ll change into the directory, and check where our origin is by running git remote -v Now we’re ready to make some changes Typically its bad to commit anything directly against the source repositories main source branch, therefore its better to create your own branch, I’m going to call mine something descriptive for my change, but also something which isn’t too long - update-to-net-core-3.1 Some repositories may have naming standards or guidelines, its always worth seeing if a repository has a CONTRIBUTING.md file in the root of the repository. Now were free to make our changes. The changes I’ve made are out of scope for this post, but if you really want you can go and check out the repository mentioned above. Looking the at the GIT GUI’s I use, you can see the changes/commit I’ve made or via the command line Pushing our code to our version of the repository So now we have our changes all committed locally, its time to push our changes to our copy of the repository , I’ll run the following command git push -u origin update-to-net-core-3.1 And if we now take a look at our GitHub repository , we can see there is a new message saying a new branch was pushed and we can do a compare and pull request, lets hit that button Submitting a Pull Request (PR) Clicking that button takes us to a page where we can create a Pull Request message which is where we can describe what/why the changes were made as well as viewing the changes side by side We can also target which branch of the remote (their) repository we want to target, because they only have a master branch that will be the branch we want our changes merged into Once you’re happy with the changes you’ve made and your commit/pull request message, its time to create the Pull Request by clicking on the Button. And Voila, a PR is now raised against the origin repository. You can see the raised PR over at https://github.com/twilio/starter-dotnet-core/pull/3 Adding a second remote So you may also be asking, ok, so when/if our changes get approved, that will go into the remote branch, how do I keep my version up to date? Well, this is where adding a 2nd remote comes in handy. Simply run git remote add upstream [the url of the original repository ] for example in this case I would do git remote add upstream https://github.com/twilio/starter-dotnet-core now if I run git remote -v again, I’ll see I have 2 remotes, origin (mine) and upstream (theirs). How to keep our repository up to date with the ‘upstream’ aka - the parent repository So, lets say they have merged our change in, or someone else’s changes, how would I update my version? There might be better and/or easier ways, but what I do is this - I’m using a slightly different repository here so I can show the relevant screen shots, as you can see, on another repository I have previously forked on GitHub, I’m a few commits behind on the vNext branch. so, I’ll go to where I have the code cloned on my system, and I’ll checkout the branch I want to update (in this case, its vNext) Then I’ll pull any changes from the upstream remote version of that branch by running git pull upstream vNext After that has finished, as long as there weren’t any merge conflicts, I’ll push that updated local version to our forked repository - and hopefully GitHub will show they are now in sync And with that, that concludes the walk-through of contributing to someone else’s repository, and keeping your version up to date. I hope you found this guide somewhat helpful.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="/assets/post-images/2020-07-10-contributing-to-someone-elses-git-repository/optimised/hero.png" /></entry><entry><title type="html">The evolution of my home office</title><link href="/posts/home-office-evolution/" rel="alternate" type="text/html" title="The evolution of my home office" /><published>2020-04-20T00:00:00+00:00</published><updated>2020-04-20T00:00:00+00:00</updated><id>/posts/home-office-evolution</id><content type="html" xml:base="/posts/home-office-evolution/">&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#prologue&quot;&gt;Prologue&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2015&quot;&gt;2015&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#november---we-think-we-found-one&quot;&gt;November - We think we found one&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2016&quot;&gt;2016&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#january---we-did-the-thing---we-bought-the-thing&quot;&gt;January - We did the thing - We bought the thing&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#february---starting-to-expand&quot;&gt;February - Starting to expand&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#march---new-laptoptablet&quot;&gt;March - New Laptop/Tablet&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#july---time-for-a-holiday&quot;&gt;July - Time for a holiday!&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#october---finding-ways-to-create-more-desk-space&quot;&gt;October - Finding ways to create more desk space&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2018&quot;&gt;2018&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#fast-forward---march&quot;&gt;Fast forward - March&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#april---renovations-begin&quot;&gt;April - Renovations begin&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2019&quot;&gt;2019&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#new-years-eve---201819&quot;&gt;New Years Eve - 2018/19&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#january&quot;&gt;January&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#may&quot;&gt;May&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#1st---enter-a-new-pc&quot;&gt;1st - Enter a new PC&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#3rd---time-to-go-shopping&quot;&gt;3rd - Time to go shopping&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#star-wars-day-may-4th&quot;&gt;Star Wars Day (May 4th)&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#may-9th---first-issue-identified&quot;&gt;May 9th - first issue identified&lt;/a&gt;
            &lt;ul&gt;
              &lt;li&gt;&lt;a href=&quot;#tearing-down-the-psu&quot;&gt;Tearing down the PSU&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#may-10th---the-first-upgrade&quot;&gt;May 10th  - The First Upgrade&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#may-11th---rgb-is-go&quot;&gt;May 11th - RGB is go&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#june-2019&quot;&gt;June 2019&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#4th---another-monitor-enters-the-fray&quot;&gt;4th - Another monitor enters the fray!&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#june-16th---18th---operation-wall-mount-all-the-monitors&quot;&gt;June 16th - 18th - Operation wall mount all the monitors!&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#july&quot;&gt;July&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#19th&quot;&gt;19th&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#20th&quot;&gt;20th&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#november&quot;&gt;November&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#22nd---mac-develops-fault&quot;&gt;22nd - Mac develops fault&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#26th&quot;&gt;26th&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#december&quot;&gt;December&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#20th-1&quot;&gt;20th&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2020&quot;&gt;2020&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#january-1&quot;&gt;January&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#february&quot;&gt;February&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#9th&quot;&gt;9th&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#20th-2&quot;&gt;20th&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#april&quot;&gt;April&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#miscellaneous&quot;&gt;Miscellaneous&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;prologue&quot;&gt;Prologue&lt;/h2&gt;

&lt;p&gt;It’s 2015, and my girlfriend and I have been saving up, clearing debts and getting ready to enter one of those ‘proper’ adult moments, that’s right, we started looking at houses… to buy!&lt;/p&gt;

&lt;p&gt;At this point, we were in a 2 bedroom council flat, it wasn’t in a bad location, was quite easy for us both to get to work, but our aim was always to buy our own house. It took a while to get to this point, but we were finally in a position where the bank would offer us a mortgage, so the fun began at looking for houses to buy.&lt;/p&gt;

&lt;p&gt;At this point, my ‘home office’ was nothing more than a corner of the living room (it was previously in the spare room, but the other half decided she’d prefer me to be in the living room, so one day while I was at work and she wasn’t, she decided to unplug everything and move it into the living room, meaning I had a fun evening that night, which I hadn’t planned for, plugging everything back in)!&lt;/p&gt;

&lt;p&gt;At some point after that, I ended up with this (excuse the mess):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/flat-office.jpg&quot; alt=&quot;&quot; title=&quot;My home office when I was living in my flat&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Hardware featured here is a mid 2011 27” iMac with a 2.7 GHz quad core Intel Core i5, an Acer V5-571p Laptop and a 19” IBM monitor&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;2015&quot;&gt;2015&lt;/h2&gt;

&lt;h3 id=&quot;november---we-think-we-found-one&quot;&gt;November - We think we found one&lt;/h3&gt;

&lt;p&gt;So, we’ve looked at various properties now, somewhere in the region of the 20s if I recall correctly, we’d had a couple of false starts, there were a couple of houses I liked but the girlfriend didn’t, and vice versa, and there was one I think we’d put an offer in but it wasn’t accepted, we found another, in an area we both didn’t mind, it looked quite, and after a couple of viewings, we decided we’d make an offer, and it was accepted. Whilst neither of us got everything that was on our wishlist, I did get one thing that was on mine, a space for an office!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution//office-previous-tenant.jfif&quot; alt=&quot;&quot; title=&quot;Before we moved in&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution//floor-plan.png&quot; alt=&quot;&quot; title=&quot;Floor plan&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;This is what it looked like before we moved in (this was the estate agents photos!) and the floor plan, its 6ft 4in x 9ft 10in&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;2016&quot;&gt;2016&lt;/h2&gt;

&lt;h3 id=&quot;january---we-did-the-thing---we-bought-the-thing&quot;&gt;January - We did the thing - We bought the thing&lt;/h3&gt;

&lt;p&gt;Because we’re nice people, and the previous tenants had little ones, we agreed on a date for completion after Christmas 2015, so January 15th 2016 we done the final steps, collected keys etc and completed with the estate agents (well, the other half done that bit whilst I was packing, loading vans, unloading vans and dumping things at the dump)!&lt;/p&gt;

&lt;p&gt;After a few days it was time to setup the computer. It doesn’t appear I took any photos at this point, but it probably did look much different to what it did in the flat!&lt;/p&gt;

&lt;h3 id=&quot;february---starting-to-expand&quot;&gt;February - Starting to expand&lt;/h3&gt;

&lt;p&gt;I started working with a new colleague, and over the course of the previous couple of months built up a really good friendship. He then told me he was going to be upgrading his monitors at home, and that he would be selling his current 2 identical monitors, which were Asus VH-228. My eyes lit up and the brain cogs started turning, and he was offering them at a decent price, I couldn’t say no, could I?!&lt;/p&gt;

&lt;p&gt;Turns out, nope, I couldn’t, the evening of around 26th February 2016, I went and picked them up from his home!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution//triple-screen.jpg&quot; alt=&quot;&quot; title=&quot;Triple Screen setup&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Triple screen hype - not all matching, but still&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At some point between this and October, I found myself having a browse through eBay, how cool would it be if I found another ASUS VH228 I thought to myself, then I found one, refurbished, for not a lot, I stuck a bid on it and forgot about it!&lt;/p&gt;

&lt;p&gt;A couple of weeks later I got the email saying I’d won - what a result!&lt;/p&gt;

&lt;h3 id=&quot;march---new-laptoptablet&quot;&gt;March - New Laptop/Tablet&lt;/h3&gt;

&lt;p&gt;I was fortunate to get an annual performance bonus from work, and wanted something a bit more powerful than my Acer V5-571p laptop, and quite liked the look of the Surface Pro. I didn’t want to pay full price for a brand new one, but I found an advert on Gumtree, for a Surface Pro 4, with the Type Cover keyboard, and the Surface Pro Dock, a couple of message and a bit of negotiating, we had a deal, it just required me doing a 200 mile / 5 hour round trip, but the negotiation we’d agreed on covered my petrol costs plus change!&lt;/p&gt;

&lt;h3 id=&quot;july---time-for-a-holiday&quot;&gt;July - Time for a holiday!&lt;/h3&gt;

&lt;p&gt;Nothing here to do with home office, but this was turning out to be a pretty awesome year, not only had we bought a house, we’d also managed to save up enough to do a road trip across the west coast of the states - that may well be a future blog post! But I did manage to pop into and visit Apple and Google whilst I was there, and by co-incidence, it was also my birthday!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution//me@apple.jpg&quot; alt=&quot;&quot; title=&quot;Me at Apple&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution//me@google.jpg&quot; alt=&quot;&quot; title=&quot;Me at Google&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution//me-leaving-post-it@google.jpg&quot; alt=&quot;&quot; title=&quot;Me leaving a post-it at Google&quot; width=&quot;33%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Apologies, I’m not the most photogenic person!&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;october---finding-ways-to-create-more-desk-space&quot;&gt;October - Finding ways to create more desk space&lt;/h3&gt;

&lt;p&gt;I’ve still only got a relatively small desk, in fact, here’s what I had, which was donated to me by a member of my other half’s family when we moved in!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/the-desk.jpeg&quot; alt=&quot;&quot; title=&quot;The Desk&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;The desk!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I searched around for a bit and finally decided on getting &lt;a href=&quot;https://amzn.to/2K7VJrQ&quot; target=&quot;_new&quot;&gt;this&lt;/a&gt;, I got some vouchers from work which I converted to Amazon vouchers, which meant I effectively didn’t pay for it - result!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/pyramid-stand.jpeg&quot; alt=&quot;&quot; title=&quot;The Stand&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;The stand!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/then-there-were-4-in-a-pyramid.jpg&quot; alt=&quot;&quot; title=&quot;The Desk&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Then there were 4 in a pyramid!&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;2018&quot;&gt;2018&lt;/h2&gt;

&lt;h3 id=&quot;fast-forward---march&quot;&gt;Fast forward - March&lt;/h3&gt;

&lt;p&gt;The trouble with my work office location, is its right opposite a John Lewis department store, like less than a 60 second walk door to door, so normally a couple of lunchtimes a month (or sometimes a week), is spent having a wonder over there and just browsing around their tech department, this can be dangerous from time to time! On a particular day in March 2018, something caught my eye, something I didn’t need, but was/certainly would be a ‘nice to have’ item.&lt;/p&gt;

&lt;p&gt;What was it?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/oops.jpeg&quot; alt=&quot;&quot; title=&quot;The Mac&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;I bought a thing! Yeah, that one with the red label, oops&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/mac-specs.png&quot; alt=&quot;&quot; title=&quot;Mac Specs&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Mac Specs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sometime also during this month, we visited our local IKEA, its only a relatively small shop, which doesn’t stock a huge amount, but its still dangerous.&lt;/p&gt;

&lt;p&gt;We’d done a little bit of planning - not a lot - but still came out with the following on order&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1 x 2x4 Kallax Unit&lt;/li&gt;
  &lt;li&gt;2 x 5 drawer Alex Units&lt;/li&gt;
  &lt;li&gt;2 x Linnmon Desktops @ 120cm x 60cm (w x d)&lt;/li&gt;
  &lt;li&gt;2 x Lack shelves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There were some other bits too, but they were for another room!&lt;/p&gt;

&lt;p&gt;At some point near the end of March, the delivery turned up, time for a bit of a spring clean (my desk also had flipped from one side of the office to the other at some point during this too)!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/what-a-mess.jpg&quot; alt=&quot;&quot; title=&quot;What a mess&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;What a mess - spring cleaning had just started&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It then became clear, I had to empty the whole office, everything had to go!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/its-empty-in-here.jpeg&quot; alt=&quot;&quot; title=&quot;Its Empty in here&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Its Empty in here (just don’t look in the room to the left)!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One thing the other half convinced me to do, was to remove that dado rail, that turned out to be a bit of a bigger job than I’d hoped!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/dado-rail-no-more-1.jpeg&quot; alt=&quot;&quot; title=&quot;Bye Bye Dado Rail&quot; width=&quot;100%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/dado-rail-no-more-2.jpeg&quot; alt=&quot;&quot; title=&quot;Bye Bye Dado Rail&quot; width=&quot;100%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/bye-bye-floor.jpg&quot; alt=&quot;&quot; title=&quot;Bye Bye floor&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Bye Bye floor!&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;april---renovations-begin&quot;&gt;April - Renovations begin&lt;/h3&gt;

&lt;p&gt;Now we’re in April, most of the patch up work has been completed, painted and new laminate flooring laid, and the beginnings of the IKEA furniture assembled!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/patch-up-stage-1.jpeg&quot; alt=&quot;&quot; title=&quot;Patch Up Stage 1&quot; width=&quot;100%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/patch-up-stage-1-1.jpeg&quot; alt=&quot;&quot; title=&quot;Patch Up Stage 1&quot; width=&quot;100%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/patch-up-complete-new-floor.jpeg&quot; alt=&quot;&quot; title=&quot;Patch Up Complete - With flooring&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now its time to get the rest of the furniture assembled&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/Furniture-Assembled.jpeg&quot; alt=&quot;&quot; title=&quot;Furniture Assembled&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Furniture Assembled&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/from-the-outside-in.jpeg&quot; alt=&quot;&quot; title=&quot;From the outside in&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;From the outside in&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/close-up.jpeg&quot; alt=&quot;&quot; title=&quot;Close Up&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Close Up&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;2019&quot;&gt;2019&lt;/h2&gt;

&lt;h3 id=&quot;new-years-eve---201819&quot;&gt;New Years Eve - 2018/19&lt;/h3&gt;

&lt;p&gt;I’m not a massive consumer of alcohol, I’m not tea-total - but having previously worked in a pub and having to deal with people who were under the influence, kinda has put me off.&lt;/p&gt;

&lt;p&gt;I was round a family members, and pretty much everyone else was drinking, I was driving so was just sticking to soft drinks as usual. I was having a look through my phone, then saw a tweet from a streamer I had relatively recently discovered on Twitch, a certain &lt;a href=&quot;https://www.twitch.tv/csharpfritz&quot; target=&quot;_new&quot;&gt;csharpfriz&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;It was here, that I decided I might give streaming a go, I had a project in mind, something I’d kind of already started but stalled. I might blog in more detail about this, as it didn’t really go to plan, but I wanted to give a bit more context as to why the next upgrade happened!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/Tweet-thread.png&quot; alt=&quot;&quot; title=&quot;Tweet thread&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Tweet thread - contemplating starting to stream&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;january&quot;&gt;January&lt;/h3&gt;

&lt;p&gt;So, I decided to dip my toe into the streaming world, I got OBS setup with some basic scenes, and hit that go live button.&lt;/p&gt;

&lt;p&gt;Unfortunately I was quite naive in terms of hardware to run a decent stream! I was attempting to do it from my Surface Pro 4, it had an i7 with 16GB RAM, I thought that would’ve been enough - and it might of been if I wasn’t trying to also use Visual Studio and Docker at the same time.&lt;/p&gt;

&lt;p&gt;I consider myself to be fairly technical, but certain things may have passed me by. I’ve never been much of a gamer so didn’t really follow too much all of the advancements in terms of video cards (GPU) over the last decade or so, as mostly I was learning to write code!&lt;/p&gt;

&lt;p&gt;After 3, pretty awful streams of basically me waiting for my surface to respond, I decided to go on a hiatus with streaming, until I could get something a bit beefier for my streaming adventure.&lt;/p&gt;

&lt;h3 id=&quot;may&quot;&gt;May&lt;/h3&gt;

&lt;h4 id=&quot;1st---enter-a-new-pc&quot;&gt;1st - Enter a new PC&lt;/h4&gt;

&lt;p&gt;So I’d been keeping an eye open for something I thought would be half decent for streaming, I started looking for 2nd hand gaming PCs because I knew I needed something having a dedicated GPU.&lt;/p&gt;

&lt;p&gt;After looking at quite a few, I finally found one in the sort of budget I had, and it seemed quite reasonable for the price. I don’t have the speccy screenshot for it, but, after I made my first upgrade I do.&lt;/p&gt;

&lt;p&gt;The specs were:
    - Intel Core i7 4790k @ 4.00GHz
    - 16GB RAM
    - Asus Z97-A Motherboard
    - MSI GeForce GTX 970 4GB
    - 120GB Samsung SSD 840 EVO
    - 2TB Seagate ST2000DM001 SATA III HDD
    - ASUS VS239 Monitor
    - Corsair CX600 Power Supply&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/the-pc.jpg&quot; alt=&quot;&quot; title=&quot;The PC&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;The PC&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I didn’t really need the monitor, but the guy I bought it from didn’t want to split so I took it - after all, I could replace the 19” VGA only top monitor you saw earlier!&lt;/p&gt;

&lt;p&gt;On the way home I stopped off at my local PC World and picked myself up a Streamdeck - another piece of hardware common with streamers and non-streamers alike, but it was something I had on my wishlist and was fortunate that I had some vouchers and discounts I could use!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/streamdeck.jpeg&quot; alt=&quot;&quot; title=&quot;The Streamdeck&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;The Streamdeck&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I then went about looking to see what upgrades I could do, I checked the motherboard specs on Asus’ website and found the max memory it would support was 32GB, it already had 16GB in 2 slots, so another 2 x 8GB chips would get me to the max supported!&lt;/p&gt;

&lt;h4 id=&quot;3rd---time-to-go-shopping&quot;&gt;3rd - Time to go shopping&lt;/h4&gt;

&lt;p&gt;So with some of my new tech, it was time to do a little bit of shopping, I had a small shopping list in mind:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/2ympClA&quot; target=&quot;_new&quot;&gt;Microphone &amp;amp; Boom arm&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/3csbdTG&quot; target=&quot;_new&quot;&gt;MALE DVI -&amp;gt; FEMALE HDMI adaptors&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/2VxTi72&quot;&gt;LINDY 4 Port USB 3.0 Switch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/2XNPn9g&quot; target=&quot;_new&quot;&gt;10 Port USB3 Powered Hub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/34QzbFI&quot; target=&quot;_new&quot;&gt;3 x 3M HDMI Cables&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/2RNsu1O&quot; target=&quot;_new&quot;&gt;RGB light strip + controller for the case&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/2VgP44S&quot; target=&quot;_new&quot;&gt;Displayport to HDMI Adapter&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/34Ku75s&quot; target=&quot;_new&quot;&gt;Corsair Carbide Series 200R Compact ATX case&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amzn.to/3bmxUs7&quot; target=&quot;_new&quot;&gt;Rocketek Bluetooth 4.0 USB Dongle&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;&quot; target=&quot;_new&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;star-wars-day-may-4th&quot;&gt;Star Wars Day (May 4th)&lt;/h4&gt;

&lt;p&gt;I had taken a stick out just to see what it was and to photograph it on my phone so I always had the details to hand if needed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/memory.jpeg&quot; alt=&quot;&quot; title=&quot;Memory module&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Memory module&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A couple of days or so into using the new PC, and getting bits installed/upgraded, I noticed it had developed its first fault 😒&lt;/p&gt;

&lt;p&gt;It had developed a squeak on one of the fans - investigations started. Typically my luck, it wasn’t any of the case fans, but the fan inside the PSU.&lt;/p&gt;

&lt;video muted=&quot;&quot; autoplay=&quot;&quot; controls=&quot;&quot;&gt;
    &lt;source src=&quot;/assets/post-images/home-office-evolution//squeaky-psu-fan.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;h4 id=&quot;may-9th---first-issue-identified&quot;&gt;May 9th - first issue identified&lt;/h4&gt;

&lt;p&gt;I did some googleing, and found that I might just be able to lube the fan bearings, I had no idea where I might be able to get some appropriate oil from. I found that apparently sewing machine oil might be OK, and if you remember earlier, I said my work office is opposite a department store, well in that store they have a small haberdashery department, so I nipped over there and managed to pick some up.&lt;/p&gt;

&lt;h5 id=&quot;tearing-down-the-psu&quot;&gt;Tearing down the PSU&lt;/h5&gt;

&lt;p&gt;OK, so I get home that evening, and decide to fix it! It wasn’t too difficult, a couple of screws to take the panel of the PSU to gain access to the fan, then I had to remove the fan as the part where I could lube was facing down with no access.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/psu-fan-1.jpeg&quot; alt=&quot;&quot; title=&quot;PSU Teardown&quot; width=&quot;33%&quot; /&gt;  &lt;img src=&quot;/assets/post-images/home-office-evolution/psu-fan-2.jpeg&quot; alt=&quot;&quot; title=&quot;PSU Teardown&quot; width=&quot;33%&quot; /&gt;  &lt;img src=&quot;/assets/post-images/home-office-evolution/psu-fan-3.jpeg&quot; alt=&quot;&quot; title=&quot;PSU Teardown&quot; width=&quot;33%&quot; /&gt;&lt;/p&gt;

&lt;video muted=&quot;&quot; autoplay=&quot;&quot; controls=&quot;&quot; style=&quot;width: 45%&quot;&gt;
    &lt;source src=&quot;/assets/post-images/home-office-evolution//psu-fan-4.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;video muted=&quot;&quot; autoplay=&quot;&quot; controls=&quot;&quot; style=&quot;width: 45%&quot;&gt;
    &lt;source src=&quot;/assets/post-images/home-office-evolution//psu-fan-fixed.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;The PSU teardown &amp;amp; fix&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;may-10th----the-first-upgrade&quot;&gt;May 10th  - The First Upgrade&lt;/h4&gt;

&lt;p&gt;During a bit of downtime (think its called waiting for a build to finish), I just happened to be flicking through Facebook Marketplace again, and low and behold, a college student had just upgraded his rig and was selling 2 8GB modules, same clock speed etc, I had to strike while the iron was hot!&lt;/p&gt;

&lt;p&gt;Technically speaking, its always advisable to always buy chips all at the same time, as occasionally you might end up with a different revision and this can cause problems.&lt;/p&gt;

&lt;p&gt;On this occasion I threw caution to the wind, so I messaged him and later went to meet during my work lunch break.&lt;/p&gt;

&lt;p&gt;That evening I got home, and plugged the new modules in - first time one of them wasn’t recognised but I did the ‘take it out and put it back in again’ thing, and it worked - happy days!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/more-memory1.jpeg&quot; alt=&quot;&quot; title=&quot;More memory&quot; width=&quot;49%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/more-memory2.jpeg&quot; alt=&quot;&quot; title=&quot;More memory&quot; width=&quot;49%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;More Memory&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;may-11th---rgb-is-go&quot;&gt;May 11th - RGB is go&lt;/h4&gt;

&lt;p&gt;So I also fitted the RGB strip inside the case - of course I’d prefer a case with a clear side panel, but this is how it came!&lt;/p&gt;

&lt;video muted=&quot;&quot; autoplay=&quot;&quot; controls=&quot;&quot; style=&quot;width: 45%&quot;&gt;
    &lt;source src=&quot;/assets/post-images/home-office-evolution//case-lights.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/specs-upgrade-1.jpg&quot; alt=&quot;&quot; title=&quot;Specs&quot; width=&quot;49%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Flashy lights &amp;amp; Specs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/updated-pyramid.jpeg&quot; alt=&quot;&quot; title=&quot;Office&quot; width=&quot;49%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/updated-pyramid-2.jpeg&quot; alt=&quot;&quot; title=&quot;Office&quot; width=&quot;49%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Excuse the mess! New monitor added to the setup and tower lurking under desk&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;june-2019&quot;&gt;June 2019&lt;/h3&gt;

&lt;h4 id=&quot;4th---another-monitor-enters-the-fray&quot;&gt;4th - Another monitor enters the fray!&lt;/h4&gt;

&lt;p&gt;So I was looking around on Facebook marketplace (again), not really looking for anything in particular, but something caught my eye - that something was a 29” LG 29EB93 Monitor! Again not something required but it wasn’t a bad price. I picked it up later that evening! I then added it to the pyramid!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/oops-another-monitor.jpeg&quot; alt=&quot;&quot; title=&quot;Oops - another monitor!&quot; width=&quot;49%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/updated-pyramid-3.jpeg&quot; alt=&quot;&quot; title=&quot;Office&quot; width=&quot;49%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Oops - another monitor!&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;june-16th---18th---operation-wall-mount-all-the-monitors&quot;&gt;June 16th - 18th - Operation wall mount all the monitors!&lt;/h4&gt;

&lt;p&gt;So, that didn’t last long until another plan started forming! Begin operation wall mount monitors, it took a little while trying to figure out a pattern that I would be happy with, I knew I wanted to flip the 29” monitor vertical, but wasn’t sure how to position the rest.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-1.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-2.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-3.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-4.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-5.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-6.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/operation-wall-mount-7.jpeg&quot; alt=&quot;&quot; title=&quot;Wall mounting the monitors (all 5 of them)!&quot; width=&quot;33%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Wall mounting the monitors (all 5 of them”)! And I added a shelf (well 2 right next to each other - that wasn’t fun)!&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;july&quot;&gt;July&lt;/h3&gt;

&lt;h4 id=&quot;19th&quot;&gt;19th&lt;/h4&gt;

&lt;p&gt;The other half was visiting her friends in London for the weekend, and I once again found myself looking through that inevitable site again! Yep, you guessed it, it was Facebook Marketplace! This time the thing that had caught my eye was another GPU (nothing ground breaking, it was a Nvidia GTX 670 2GB). Now some of you, the more eagle eyed and more technical minded/intrigued of you may have started to wonder, if I have just one GPU (and if you haven’t look it up to check), it only has 4 outputs on the MSI GeForce GTX 970 (HDMI, DVI-I, DVI-D, and DP), how an I managing to get a signal to 5 monitors independently without mirroring screens? Well, back in February 2018, another national electronics chain, with a local shop near me, called &lt;a href=&quot;https://en.wikipedia.org/wiki/Maplin_(retailer)&quot; target=&quot;_new&quot;&gt;Maplins&lt;/a&gt;, unfortunately went out of business. I’d nipped there a couple of times as they started to sell the last of their remaining stock. One of the items I managed to pick up on these visits was a USB3 to HDMI adaptor - that is what provided me the ability to get a video feed out to the 5th Monitor.&lt;/p&gt;

&lt;p&gt;Any way, I picked up the new GPU, went home and proceeded to fit it. However, after installing the new GPU, windows recognised there was something there but it wasn’t working. I had a chat with a colleague the following day, and it turned out it required both 6 pin power supplies also, there weren’t any more available from the PSU, so once again went on to amazon to see if I could find some &lt;a href=&quot;https://amzn.to/3cxHmJr&quot; target=&quot;_new&quot;&gt;Molex to SATA adaptors&lt;/a&gt; and some &lt;a href=&quot;https://amzn.to/3bqfzKW&quot; target=&quot;_new&quot;&gt;15 pin SATA to 8 pin PCI-e adaptors&lt;/a&gt;. Having these fixed the issue and I could now run both GPU’s.&lt;/p&gt;

&lt;p&gt;Whilst not a very significant upgrade, it meant that I could now run all 5 monitors from GPU’s, and not rely on any dongles!&lt;/p&gt;

&lt;h4 id=&quot;20th&quot;&gt;20th&lt;/h4&gt;

&lt;p&gt;I saw something that caught my eye again on Facebook Marketplace, again not something I strictly needed, but something that would be a nice to have. It wasn’t particularly local to me, but a friend of mine is constantly travelling in and around our adjacent counties. I asked him if he was near where this item was located and he was. I managed to negotiate a price and for £60 I became an owner of an &lt;a href=&quot;https://amzn.to/3auTA4o&quot; target=&quot;_new&quot;&gt;Elgato HD60s&lt;/a&gt;. At the time, the standard HD60 were also going for around the same price, with the s model being a bit over £100, so this felt like a small win!&lt;/p&gt;

&lt;h3 id=&quot;november&quot;&gt;November&lt;/h3&gt;

&lt;h4 id=&quot;22nd---mac-develops-fault&quot;&gt;22nd - Mac develops fault&lt;/h4&gt;

&lt;p&gt;I turn my MacBook on whilst sitting on the sofa, still adjusting to becoming a first time dad less than 2 weeks ago. Missus and baby were sleeping, so I though I’d turn the mac on and see what was happening, and I notice something on screen, dread starts to fill up, I start panicking. Not 1, not 2, but a whole line of pixels seem to have developed a fault :( - these are bad times!&lt;/p&gt;

&lt;p&gt;The line that sits right under the top status bar when you’re logged in, and 2 yellow dots.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/mac-issues-1.jpg&quot; alt=&quot;&quot; title=&quot;Mac Issues&quot; width=&quot;32%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/mac-issues-2.jpg&quot; alt=&quot;&quot; title=&quot;Mac Issues&quot; width=&quot;32%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/mac-issues-3.jpg&quot; alt=&quot;&quot; title=&quot;Mac Issues&quot; width=&quot;32%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Mac Issues&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;26th&quot;&gt;26th&lt;/h4&gt;

&lt;p&gt;Because little me decided to arrive 3 weeks early I had to nip into the office to clear my desk off. My employer is very generous in that they offer new fathers 6 months company paternity leave, with full pay &amp;amp; benefits. As I wasn’t going to be going back for a while, I needed to clear my desk, pick my laptop up etc. Of course some of the team wanted to meet him too! We also nipped over the road to the department store I mentioned to try my luck and see if they would repair my MacBook, it was worth asking. When I bought it they supplied a 2 year warranty on it, I looked online but they said they don’t cover pixel spots. My issue didn’t quite fit that so thought it was worth a try! I spoke to one of their reps, explained the situation, showed him the fault, and the overall condition of the MacBook, I might be biased but I think it’s been pretty well looked after. He said they’d need to send it off to their repair team, and it would be one of three outcomes:
    - It gets fixed under warranty
    - It doesn’t get fixed
    - It gets fixed at a cost to me&lt;/p&gt;

&lt;p&gt;Of course being this close to Christmas there is no guarantee I’d get it back before then, but it was worth a try.&lt;/p&gt;

&lt;h3 id=&quot;december&quot;&gt;December&lt;/h3&gt;

&lt;h4 id=&quot;20th-1&quot;&gt;20th&lt;/h4&gt;

&lt;p&gt;I get an email from the department store, and a phone call too. They’ve fixed it under warranty, result. I go and pick it up later that day!&lt;/p&gt;

&lt;h2 id=&quot;2020&quot;&gt;2020&lt;/h2&gt;

&lt;h3 id=&quot;january-1&quot;&gt;January&lt;/h3&gt;

&lt;p&gt;The next upgrade on my list, was to install a new and bigger SSD as my boot drive, so my other half got me this as a Christmas present.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/ssd-upgrade-1.jpg&quot; alt=&quot;&quot; title=&quot;SSD Upgrade&quot; width=&quot;49%&quot; /&gt;
&lt;img src=&quot;/assets/post-images/home-office-evolution/ssd-upgrade-2.jpg&quot; alt=&quot;&quot; title=&quot;SSD Upgrade&quot; width=&quot;49%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;SSD Upgrade&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;february&quot;&gt;February&lt;/h3&gt;

&lt;h4 id=&quot;9th&quot;&gt;9th&lt;/h4&gt;

&lt;p&gt;Not a lot was happening, again I found myself having a bit of a flick through Facebook Marketplace (I’m not addicted)! I saw someone was advertising a fairly decent monitor for £10! Did I need another monitor? Not really, but for £10 I thought it might be worth a punt. It was an LG 25UM58-P. The girl selling it didn’t have any of the leads for it but thought it might be worth a punt, I sent a message to confirm the price wasn’t a typo (I looked up the same models which were going for £70-80 plus) and arranged a time to pick it, a couple  of hours later I had it in my possession and was on the way home. I got home and decided to test it, having already having an LG monitor, I checked the output voltage matched the required for the newly acquired monitor, plugged it in and crossed my fingers! Hooray, it’s in fully working order - no dead pixels, and apart from some surface dust, was actually in pretty good condition. So off to Amazon I went to look for a replacement power supply. &lt;a href=&quot;https://amzn.to/2RTwE8m&quot; target=&quot;_new&quot;&gt;I found this&lt;/a&gt; so decided to order it - it arrived the next day and so I had another fully working monitor, some might say a bit overkill, but I had managed to back myself a monitor for less than 30 quid which normally sell 2nd hand for 70 quid plus. I wasn’t sure whether to keep it or to try and sell it on for profit, but for now, its staying where it is!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/then-there-were-six.jpg&quot; alt=&quot;&quot; title=&quot;Then there were 6&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Then there were 6&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;20th-2&quot;&gt;20th&lt;/h4&gt;

&lt;p&gt;As I mentioned earlier my Mac had developed a fault, and I was contemplating the idea of maybe a dual boot with a ‘Hackintosh’, however the latest OSX operating systems don’t support NVidia cards but do AMD GPUs. I then decided to bid on one on eBay, a Radeon RX580 8GB Sapphire Nitro+ to be exact. It turns up and I set about making this my primary GPU, the 4GB GeForce GTX 970 secondary, and removing the 2GB one.&lt;/p&gt;

&lt;h3 id=&quot;april&quot;&gt;April&lt;/h3&gt;

&lt;p&gt;This is where I currently am, writing this blog post and trying to remember all of the little upgrades that I’ve done over the last 4 years ish. There is still some more I’d like to do, need to get my electrician friend round to install some new sockets and get better with some of that cable management - this blog post may end up becoming part of a series as my home office space continues to evolve.&lt;/p&gt;

&lt;h2 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h2&gt;

&lt;p&gt;Some of the things I haven’t covered but also exist on my desk, are some &lt;a href=&quot;https://amzn.to/34OiNWb&quot; target=&quot;_new&quot;&gt;HDMI switches&lt;/a&gt; for a couple of monitors. Why? I have 2 docks (hidden behind the Surface in the photo above), my Surface pro dock, and a &lt;a href=&quot;https://amzn.to/2VpFX1X&quot; target=&quot;_new&quot;&gt;Dell D6000 Universal Dock&lt;/a&gt;. You may ask why I have the dell dock, the reason being is my work laptop, provided by my employer, is a Dell Latitude 7480, and when I got it, they also upgraded all our docks on our desks in the office. Because the laptop is USB-C, it got me wondering if I could use it with my MacBook, I took a punt on one on eBay on October 2018 and it works, it charges my MacBook and also allows me to use up to 3 of my monitors. This is handy for when I want to work with my Mac, or when I need to work from home using my Dell work laptop.&lt;/p&gt;

&lt;p&gt;So this is what I’m now currently running:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/speccy-april-20.png&quot; alt=&quot;&quot; title=&quot;Speccy Screenshot&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Speccy Screenshot&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;and here’s proof that all 6 monitors are being driven from the same PC!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/home-office-evolution/all-6.png&quot; alt=&quot;&quot; title=&quot;Display Settings&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;image-caption&quot;&gt;&lt;em&gt;Display Settings showing all 6 monitors&lt;/em&gt;&lt;/p&gt;</content><author><name>Chris</name></author><category term="General" /><category term="General" /><category term="Home Office" /><summary type="html">Prologue 2015 November - We think we found one 2016 January - We did the thing - We bought the thing February - Starting to expand March - New Laptop/Tablet July - Time for a holiday! October - Finding ways to create more desk space 2018 Fast forward - March April - Renovations begin 2019 New Years Eve - 2018/19 January May 1st - Enter a new PC 3rd - Time to go shopping Star Wars Day (May 4th) May 9th - first issue identified Tearing down the PSU May 10th - The First Upgrade May 11th - RGB is go June 2019 4th - Another monitor enters the fray! June 16th - 18th - Operation wall mount all the monitors! July 19th 20th November 22nd - Mac develops fault 26th December 20th 2020 January February 9th 20th April Miscellaneous Prologue It’s 2015, and my girlfriend and I have been saving up, clearing debts and getting ready to enter one of those ‘proper’ adult moments, that’s right, we started looking at houses… to buy! At this point, we were in a 2 bedroom council flat, it wasn’t in a bad location, was quite easy for us both to get to work, but our aim was always to buy our own house. It took a while to get to this point, but we were finally in a position where the bank would offer us a mortgage, so the fun began at looking for houses to buy. At this point, my ‘home office’ was nothing more than a corner of the living room (it was previously in the spare room, but the other half decided she’d prefer me to be in the living room, so one day while I was at work and she wasn’t, she decided to unplug everything and move it into the living room, meaning I had a fun evening that night, which I hadn’t planned for, plugging everything back in)! At some point after that, I ended up with this (excuse the mess): Hardware featured here is a mid 2011 27” iMac with a 2.7 GHz quad core Intel Core i5, an Acer V5-571p Laptop and a 19” IBM monitor 2015 November - We think we found one So, we’ve looked at various properties now, somewhere in the region of the 20s if I recall correctly, we’d had a couple of false starts, there were a couple of houses I liked but the girlfriend didn’t, and vice versa, and there was one I think we’d put an offer in but it wasn’t accepted, we found another, in an area we both didn’t mind, it looked quite, and after a couple of viewings, we decided we’d make an offer, and it was accepted. Whilst neither of us got everything that was on our wishlist, I did get one thing that was on mine, a space for an office! This is what it looked like before we moved in (this was the estate agents photos!) and the floor plan, its 6ft 4in x 9ft 10in 2016 January - We did the thing - We bought the thing Because we’re nice people, and the previous tenants had little ones, we agreed on a date for completion after Christmas 2015, so January 15th 2016 we done the final steps, collected keys etc and completed with the estate agents (well, the other half done that bit whilst I was packing, loading vans, unloading vans and dumping things at the dump)! After a few days it was time to setup the computer. It doesn’t appear I took any photos at this point, but it probably did look much different to what it did in the flat! February - Starting to expand I started working with a new colleague, and over the course of the previous couple of months built up a really good friendship. He then told me he was going to be upgrading his monitors at home, and that he would be selling his current 2 identical monitors, which were Asus VH-228. My eyes lit up and the brain cogs started turning, and he was offering them at a decent price, I couldn’t say no, could I?! Turns out, nope, I couldn’t, the evening of around 26th February 2016, I went and picked them up from his home! Triple screen hype - not all matching, but still At some point between this and October, I found myself having a browse through eBay, how cool would it be if I found another ASUS VH228 I thought to myself, then I found one, refurbished, for not a lot, I stuck a bid on it and forgot about it! A couple of weeks later I got the email saying I’d won - what a result! March - New Laptop/Tablet I was fortunate to get an annual performance bonus from work, and wanted something a bit more powerful than my Acer V5-571p laptop, and quite liked the look of the Surface Pro. I didn’t want to pay full price for a brand new one, but I found an advert on Gumtree, for a Surface Pro 4, with the Type Cover keyboard, and the Surface Pro Dock, a couple of message and a bit of negotiating, we had a deal, it just required me doing a 200 mile / 5 hour round trip, but the negotiation we’d agreed on covered my petrol costs plus change! July - Time for a holiday! Nothing here to do with home office, but this was turning out to be a pretty awesome year, not only had we bought a house, we’d also managed to save up enough to do a road trip across the west coast of the states - that may well be a future blog post! But I did manage to pop into and visit Apple and Google whilst I was there, and by co-incidence, it was also my birthday! Apologies, I’m not the most photogenic person! October - Finding ways to create more desk space I’ve still only got a relatively small desk, in fact, here’s what I had, which was donated to me by a member of my other half’s family when we moved in! The desk! I searched around for a bit and finally decided on getting this, I got some vouchers from work which I converted to Amazon vouchers, which meant I effectively didn’t pay for it - result! The stand! Then there were 4 in a pyramid! 2018 Fast forward - March The trouble with my work office location, is its right opposite a John Lewis department store, like less than a 60 second walk door to door, so normally a couple of lunchtimes a month (or sometimes a week), is spent having a wonder over there and just browsing around their tech department, this can be dangerous from time to time! On a particular day in March 2018, something caught my eye, something I didn’t need, but was/certainly would be a ‘nice to have’ item. What was it? I bought a thing! Yeah, that one with the red label, oops Mac Specs Sometime also during this month, we visited our local IKEA, its only a relatively small shop, which doesn’t stock a huge amount, but its still dangerous. We’d done a little bit of planning - not a lot - but still came out with the following on order 1 x 2x4 Kallax Unit 2 x 5 drawer Alex Units 2 x Linnmon Desktops @ 120cm x 60cm (w x d) 2 x Lack shelves There were some other bits too, but they were for another room! At some point near the end of March, the delivery turned up, time for a bit of a spring clean (my desk also had flipped from one side of the office to the other at some point during this too)! What a mess - spring cleaning had just started It then became clear, I had to empty the whole office, everything had to go! Its Empty in here (just don’t look in the room to the left)! One thing the other half convinced me to do, was to remove that dado rail, that turned out to be a bit of a bigger job than I’d hoped! Bye Bye floor! April - Renovations begin Now we’re in April, most of the patch up work has been completed, painted and new laminate flooring laid, and the beginnings of the IKEA furniture assembled! Now its time to get the rest of the furniture assembled Furniture Assembled From the outside in Close Up 2019 New Years Eve - 2018/19 I’m not a massive consumer of alcohol, I’m not tea-total - but having previously worked in a pub and having to deal with people who were under the influence, kinda has put me off. I was round a family members, and pretty much everyone else was drinking, I was driving so was just sticking to soft drinks as usual. I was having a look through my phone, then saw a tweet from a streamer I had relatively recently discovered on Twitch, a certain csharpfriz! It was here, that I decided I might give streaming a go, I had a project in mind, something I’d kind of already started but stalled. I might blog in more detail about this, as it didn’t really go to plan, but I wanted to give a bit more context as to why the next upgrade happened! Tweet thread - contemplating starting to stream January So, I decided to dip my toe into the streaming world, I got OBS setup with some basic scenes, and hit that go live button. Unfortunately I was quite naive in terms of hardware to run a decent stream! I was attempting to do it from my Surface Pro 4, it had an i7 with 16GB RAM, I thought that would’ve been enough - and it might of been if I wasn’t trying to also use Visual Studio and Docker at the same time. I consider myself to be fairly technical, but certain things may have passed me by. I’ve never been much of a gamer so didn’t really follow too much all of the advancements in terms of video cards (GPU) over the last decade or so, as mostly I was learning to write code! After 3, pretty awful streams of basically me waiting for my surface to respond, I decided to go on a hiatus with streaming, until I could get something a bit beefier for my streaming adventure. May 1st - Enter a new PC So I’d been keeping an eye open for something I thought would be half decent for streaming, I started looking for 2nd hand gaming PCs because I knew I needed something having a dedicated GPU. After looking at quite a few, I finally found one in the sort of budget I had, and it seemed quite reasonable for the price. I don’t have the speccy screenshot for it, but, after I made my first upgrade I do. The specs were: - Intel Core i7 4790k @ 4.00GHz - 16GB RAM - Asus Z97-A Motherboard - MSI GeForce GTX 970 4GB - 120GB Samsung SSD 840 EVO - 2TB Seagate ST2000DM001 SATA III HDD - ASUS VS239 Monitor - Corsair CX600 Power Supply The PC I didn’t really need the monitor, but the guy I bought it from didn’t want to split so I took it - after all, I could replace the 19” VGA only top monitor you saw earlier! On the way home I stopped off at my local PC World and picked myself up a Streamdeck - another piece of hardware common with streamers and non-streamers alike, but it was something I had on my wishlist and was fortunate that I had some vouchers and discounts I could use! The Streamdeck I then went about looking to see what upgrades I could do, I checked the motherboard specs on Asus’ website and found the max memory it would support was 32GB, it already had 16GB in 2 slots, so another 2 x 8GB chips would get me to the max supported! 3rd - Time to go shopping So with some of my new tech, it was time to do a little bit of shopping, I had a small shopping list in mind: Microphone &amp;amp; Boom arm MALE DVI -&amp;gt; FEMALE HDMI adaptors LINDY 4 Port USB 3.0 Switch 10 Port USB3 Powered Hub 3 x 3M HDMI Cables RGB light strip + controller for the case Displayport to HDMI Adapter Corsair Carbide Series 200R Compact ATX case Rocketek Bluetooth 4.0 USB Dongle Star Wars Day (May 4th) I had taken a stick out just to see what it was and to photograph it on my phone so I always had the details to hand if needed. Memory module A couple of days or so into using the new PC, and getting bits installed/upgraded, I noticed it had developed its first fault 😒 It had developed a squeak on one of the fans - investigations started. Typically my luck, it wasn’t any of the case fans, but the fan inside the PSU. May 9th - first issue identified I did some googleing, and found that I might just be able to lube the fan bearings, I had no idea where I might be able to get some appropriate oil from. I found that apparently sewing machine oil might be OK, and if you remember earlier, I said my work office is opposite a department store, well in that store they have a small haberdashery department, so I nipped over there and managed to pick some up. Tearing down the PSU OK, so I get home that evening, and decide to fix it! It wasn’t too difficult, a couple of screws to take the panel of the PSU to gain access to the fan, then I had to remove the fan as the part where I could lube was facing down with no access. The PSU teardown &amp;amp; fix May 10th - The First Upgrade During a bit of downtime (think its called waiting for a build to finish), I just happened to be flicking through Facebook Marketplace again, and low and behold, a college student had just upgraded his rig and was selling 2 8GB modules, same clock speed etc, I had to strike while the iron was hot! Technically speaking, its always advisable to always buy chips all at the same time, as occasionally you might end up with a different revision and this can cause problems. On this occasion I threw caution to the wind, so I messaged him and later went to meet during my work lunch break. That evening I got home, and plugged the new modules in - first time one of them wasn’t recognised but I did the ‘take it out and put it back in again’ thing, and it worked - happy days! More Memory May 11th - RGB is go So I also fitted the RGB strip inside the case - of course I’d prefer a case with a clear side panel, but this is how it came! Flashy lights &amp;amp; Specs Excuse the mess! New monitor added to the setup and tower lurking under desk June 2019 4th - Another monitor enters the fray! So I was looking around on Facebook marketplace (again), not really looking for anything in particular, but something caught my eye - that something was a 29” LG 29EB93 Monitor! Again not something required but it wasn’t a bad price. I picked it up later that evening! I then added it to the pyramid! Oops - another monitor! June 16th - 18th - Operation wall mount all the monitors! So, that didn’t last long until another plan started forming! Begin operation wall mount monitors, it took a little while trying to figure out a pattern that I would be happy with, I knew I wanted to flip the 29” monitor vertical, but wasn’t sure how to position the rest. Wall mounting the monitors (all 5 of them”)! And I added a shelf (well 2 right next to each other - that wasn’t fun)! July 19th The other half was visiting her friends in London for the weekend, and I once again found myself looking through that inevitable site again! Yep, you guessed it, it was Facebook Marketplace! This time the thing that had caught my eye was another GPU (nothing ground breaking, it was a Nvidia GTX 670 2GB). Now some of you, the more eagle eyed and more technical minded/intrigued of you may have started to wonder, if I have just one GPU (and if you haven’t look it up to check), it only has 4 outputs on the MSI GeForce GTX 970 (HDMI, DVI-I, DVI-D, and DP), how an I managing to get a signal to 5 monitors independently without mirroring screens? Well, back in February 2018, another national electronics chain, with a local shop near me, called Maplins, unfortunately went out of business. I’d nipped there a couple of times as they started to sell the last of their remaining stock. One of the items I managed to pick up on these visits was a USB3 to HDMI adaptor - that is what provided me the ability to get a video feed out to the 5th Monitor. Any way, I picked up the new GPU, went home and proceeded to fit it. However, after installing the new GPU, windows recognised there was something there but it wasn’t working. I had a chat with a colleague the following day, and it turned out it required both 6 pin power supplies also, there weren’t any more available from the PSU, so once again went on to amazon to see if I could find some Molex to SATA adaptors and some 15 pin SATA to 8 pin PCI-e adaptors. Having these fixed the issue and I could now run both GPU’s. Whilst not a very significant upgrade, it meant that I could now run all 5 monitors from GPU’s, and not rely on any dongles! 20th I saw something that caught my eye again on Facebook Marketplace, again not something I strictly needed, but something that would be a nice to have. It wasn’t particularly local to me, but a friend of mine is constantly travelling in and around our adjacent counties. I asked him if he was near where this item was located and he was. I managed to negotiate a price and for £60 I became an owner of an Elgato HD60s. At the time, the standard HD60 were also going for around the same price, with the s model being a bit over £100, so this felt like a small win! November 22nd - Mac develops fault I turn my MacBook on whilst sitting on the sofa, still adjusting to becoming a first time dad less than 2 weeks ago. Missus and baby were sleeping, so I though I’d turn the mac on and see what was happening, and I notice something on screen, dread starts to fill up, I start panicking. Not 1, not 2, but a whole line of pixels seem to have developed a fault :( - these are bad times! The line that sits right under the top status bar when you’re logged in, and 2 yellow dots. Mac Issues 26th Because little me decided to arrive 3 weeks early I had to nip into the office to clear my desk off. My employer is very generous in that they offer new fathers 6 months company paternity leave, with full pay &amp;amp; benefits. As I wasn’t going to be going back for a while, I needed to clear my desk, pick my laptop up etc. Of course some of the team wanted to meet him too! We also nipped over the road to the department store I mentioned to try my luck and see if they would repair my MacBook, it was worth asking. When I bought it they supplied a 2 year warranty on it, I looked online but they said they don’t cover pixel spots. My issue didn’t quite fit that so thought it was worth a try! I spoke to one of their reps, explained the situation, showed him the fault, and the overall condition of the MacBook, I might be biased but I think it’s been pretty well looked after. He said they’d need to send it off to their repair team, and it would be one of three outcomes: - It gets fixed under warranty - It doesn’t get fixed - It gets fixed at a cost to me Of course being this close to Christmas there is no guarantee I’d get it back before then, but it was worth a try. December 20th I get an email from the department store, and a phone call too. They’ve fixed it under warranty, result. I go and pick it up later that day! 2020 January The next upgrade on my list, was to install a new and bigger SSD as my boot drive, so my other half got me this as a Christmas present. SSD Upgrade February 9th Not a lot was happening, again I found myself having a bit of a flick through Facebook Marketplace (I’m not addicted)! I saw someone was advertising a fairly decent monitor for £10! Did I need another monitor? Not really, but for £10 I thought it might be worth a punt. It was an LG 25UM58-P. The girl selling it didn’t have any of the leads for it but thought it might be worth a punt, I sent a message to confirm the price wasn’t a typo (I looked up the same models which were going for £70-80 plus) and arranged a time to pick it, a couple of hours later I had it in my possession and was on the way home. I got home and decided to test it, having already having an LG monitor, I checked the output voltage matched the required for the newly acquired monitor, plugged it in and crossed my fingers! Hooray, it’s in fully working order - no dead pixels, and apart from some surface dust, was actually in pretty good condition. So off to Amazon I went to look for a replacement power supply. I found this so decided to order it - it arrived the next day and so I had another fully working monitor, some might say a bit overkill, but I had managed to back myself a monitor for less than 30 quid which normally sell 2nd hand for 70 quid plus. I wasn’t sure whether to keep it or to try and sell it on for profit, but for now, its staying where it is! Then there were 6 20th As I mentioned earlier my Mac had developed a fault, and I was contemplating the idea of maybe a dual boot with a ‘Hackintosh’, however the latest OSX operating systems don’t support NVidia cards but do AMD GPUs. I then decided to bid on one on eBay, a Radeon RX580 8GB Sapphire Nitro+ to be exact. It turns up and I set about making this my primary GPU, the 4GB GeForce GTX 970 secondary, and removing the 2GB one. April This is where I currently am, writing this blog post and trying to remember all of the little upgrades that I’ve done over the last 4 years ish. There is still some more I’d like to do, need to get my electrician friend round to install some new sockets and get better with some of that cable management - this blog post may end up becoming part of a series as my home office space continues to evolve. Miscellaneous Some of the things I haven’t covered but also exist on my desk, are some HDMI switches for a couple of monitors. Why? I have 2 docks (hidden behind the Surface in the photo above), my Surface pro dock, and a Dell D6000 Universal Dock. You may ask why I have the dell dock, the reason being is my work laptop, provided by my employer, is a Dell Latitude 7480, and when I got it, they also upgraded all our docks on our desks in the office. Because the laptop is USB-C, it got me wondering if I could use it with my MacBook, I took a punt on one on eBay on October 2018 and it works, it charges my MacBook and also allows me to use up to 3 of my monitors. This is handy for when I want to work with my Mac, or when I need to work from home using my Dell work laptop. So this is what I’m now currently running: Speccy Screenshot and here’s proof that all 6 monitors are being driven from the same PC! Display Settings showing all 6 monitors</summary></entry><entry><title type="html">Identifying ports in use on Windows via Powershell</title><link href="/posts/identifying-ports-in-use-on-windows-via-powershell/" rel="alternate" type="text/html" title="Identifying ports in use on Windows via Powershell" /><published>2020-04-08T00:00:00+00:00</published><updated>2020-04-08T00:00:00+00:00</updated><id>/posts/identifying-ports-in-use-on-windows-via-powershell</id><content type="html" xml:base="/posts/identifying-ports-in-use-on-windows-via-powershell/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;Occasionally you might find yourself struggling to launch an application or website that you’ve been building locally, due to a port conflict issue. If you’re unable to change the port on either of the applications, you then find yourself in the predicament of trying to figure out which application it is that is using said port, so you can see if its an app that isn’t essential and can therefore be closed allowing you to continue your original task.&lt;/p&gt;

&lt;p&gt;In Powershell (or command prompt), you can get a list of ports that are currently in use by running&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;netstat &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The output will look something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-04-08-identifying-ports-in-use-on-windows-via-powershell/netstat-a-output.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;filter&quot;&gt;Filter&lt;/h2&gt;

&lt;p&gt;We’re able to filter this list, if we run the following command&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;netstat &lt;span class=&quot;nt&quot;&gt;-aon&lt;/span&gt; | findstr &lt;span class=&quot;s2&quot;&gt;&quot;4000&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The output returned will look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-04-08-identifying-ports-in-use-on-windows-via-powershell/netstat-aon-filter-output.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;identifying-the-process-the-port-belongs-too&quot;&gt;Identifying the process the port belongs too&lt;/h2&gt;

&lt;p&gt;OK, that last column on the right (which has 22344 in the above screen-shot), tells use the &lt;code class=&quot;highlighter-rouge&quot;&gt;PID&lt;/code&gt; (process ID) of whichever application is using the port.&lt;/p&gt;

&lt;p&gt;Using the following command, we can filter by the &lt;code class=&quot;highlighter-rouge&quot;&gt;PID&lt;/code&gt; we’ve just obtained&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tasklist | findstr 22344
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which will yield an output like the below&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2020-04-08-identifying-ports-in-use-on-windows-via-powershell/tasklist-filter-output.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This tells me that its Docker that is using the port 4000.&lt;/p&gt;</content><author><name>Chris</name></author><category term="Powershell" /><category term="Ports" /><category term="Windows" /><summary type="html">Background Occasionally you might find yourself struggling to launch an application or website that you’ve been building locally, due to a port conflict issue. If you’re unable to change the port on either of the applications, you then find yourself in the predicament of trying to figure out which application it is that is using said port, so you can see if its an app that isn’t essential and can therefore be closed allowing you to continue your original task. In Powershell (or command prompt), you can get a list of ports that are currently in use by running netstat -a The output will look something like this: Filter We’re able to filter this list, if we run the following command netstat -aon | findstr &quot;4000&quot; The output returned will look like this: Identifying the process the port belongs too OK, that last column on the right (which has 22344 in the above screen-shot), tells use the PID (process ID) of whichever application is using the port. Using the following command, we can filter by the PID we’ve just obtained tasklist | findstr 22344 which will yield an output like the below This tells me that its Docker that is using the port 4000.</summary></entry><entry><title type="html">Generating PDF contents via the form</title><link href="/posts/lets-create-a-pdf/" rel="alternate" type="text/html" title="Generating PDF contents via the form" /><published>2020-04-08T00:00:00+00:00</published><updated>2020-04-08T00:00:00+00:00</updated><id>/posts/lets-create-a-pdf</id><content type="html" xml:base="/posts/lets-create-a-pdf/">&lt;h2 id=&quot;creating-the-pdf&quot;&gt;Creating the PDF&lt;/h2&gt;

&lt;p&gt;Coming soon&amp;#8230;&lt;/p&gt;</content><author><name></name></author><category term="MongoDB" /><category term="Node" /><category term="PDF" /><category term="Tutorials &amp; Walkthroughs" /><summary type="html">Creating the PDF Coming soon&amp;#8230;</summary></entry><entry><title type="html">Ground work - setting up the project</title><link href="/posts/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/" rel="alternate" type="text/html" title="Ground work - setting up the project" /><published>2020-04-04T00:00:00+00:00</published><updated>2020-04-04T00:00:00+00:00</updated><id>/posts/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container</id><content type="html" xml:base="/posts/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/">&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#pre-requisites&quot;&gt;Pre-requisites&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#onwards&quot;&gt;Onwards&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#setting-up-the-project-and-installing-all-the-things&quot;&gt;Setting up the project and installing all the things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#adding-a-form-to-capture-the-inputs&quot;&gt;Adding a form to capture the inputs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#processing-the-form-data&quot;&gt;Processing the form data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#finishing-up-part-1&quot;&gt;Finishing up (part 1)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#source-code&quot;&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So this morning I got a whatsapp of a good friend asking me how good I am with Excel, I told him I wasn&amp;#8217;t too bad, and after a few messages back and forth, turns out he doesn&amp;#8217;t need Excel whatsoever, but potentially a website which can generate dynamic PDFs. I thought it might be a good candidate for a blog post, so here goes&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve decided that as I&amp;#8217;m writing this, it should probably be split out into multiple posts, so this will be post 1 of 2. For part 2, click &lt;a href=&quot;&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-requisites&lt;/h2&gt;

&lt;p&gt;So, first things first, we need to have Visual Studio installed on your OS of choice with the following VS Code extensions (not sure if all of these are 100% required but I had them installed)!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl&quot; target=&quot;_new&quot;&gt;Remote WSL&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack&quot; target=&quot;_new&quot;&gt;Remote Development&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;onwards&quot;&gt;Onwards&lt;/h2&gt;

&lt;p&gt;First thing I did was to create a new folder where I was going to store this project.&lt;/p&gt;

&lt;p&gt;I then opened VS Code and selected the &lt;code class=&quot;highlighter-rouge&quot;&gt;Open a remote window&lt;/code&gt; &lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/OpenARemoteWindowIcon.png&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/OpenARemoteWindowIcon.png&quot; /&gt; icon in the bottom left of VS Code (or you can use the command pallette (by pressing &lt;kbd&gt;ctrl&lt;/kbd&gt; + &lt;kbd&gt;p&lt;/kbd&gt;) and search for remote containers) 
and select &lt;code class=&quot;highlighter-rouge&quot;&gt;Remote-Containers: Open folder in container...&lt;/code&gt; the option and navigate to the folder which you&amp;#8217;ve just created.&lt;/p&gt;

&lt;p&gt;It will then popup with a whole list of options of different development environments (you can filter these as I have done in the below screenshot), and select &lt;code class=&quot;highlighter-rouge&quot;&gt;Node.js 12 &amp;amp; Mongo DB&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/container-options.png&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/container-options.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It may take a couple of minutes to finish setting up, but once its up and running you should see something similar to the below like &lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/dev-container-running.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This will create a &lt;code class=&quot;highlighter-rouge&quot;&gt;.devcontainer&lt;/code&gt; folder on disk which will have a dockerfile, docker-compose.yml and devcontainer.json files.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-the-project-and-installing-all-the-things&quot;&gt;Setting up the project and installing all the things&lt;/h2&gt;

&lt;p&gt;So, as with every great node based project, its all starts with a package.json, so I&amp;#8217;ll hit &lt;kbd&gt;ctrl&lt;/kbd&gt; + &lt;kbd&gt;&amp;apos;&lt;/kbd&gt; to bring up&lt;/p&gt;

&lt;p&gt;So, first off I think we&amp;#8217;ll want to install the following things, I&amp;#8217;ll add them in the terminal by running npm i {package name}&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;pdfkit&lt;/li&gt;
  &lt;li&gt;express&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;If you&amp;#8217;ve done a fresh clone, or &amp;#8216;nuked&amp;#8217; the node_modules folder, its worth noting that you&amp;#8217;ll need to re-run npm -i in the console window to restore the dependencies&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because the template container hasn&amp;#8217;t exposed a port, we&amp;#8217;ll need to amend both the dockerfile and docker-compose file to expose the port&lt;/p&gt;

&lt;p&gt;We also need to tell express how to run and what to serve, so we&amp;#8217;ll create a new file called &lt;code class=&quot;highlighter-rouge&quot;&gt;server.js&lt;/code&gt; user the /workspace directory.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m just going to add a simple route for now so we can test things work, so the code inside &lt;code class=&quot;highlighter-rouge&quot;&gt;server.js&lt;/code&gt; for now will just be the following:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'express'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
 
&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Hello World'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
 
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'ready and waiting for connections'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2020&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In my &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; I&amp;#8217;ve added the following to the end of it:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;RUN&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;install&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;EXPOSE&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2020&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;CMD&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;server.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt;, under &lt;code class=&quot;highlighter-rouge&quot;&gt;services:web&lt;/code&gt; item, I&amp;#8217;ve added in&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;2020:2020&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, with the &lt;code class=&quot;highlighter-rouge&quot;&gt;server.js&lt;/code&gt; file selected, we can select &lt;strong&gt;Run&lt;/strong&gt; -&amp;gt; &lt;strong&gt;&lt;em&gt;Start Debugging&lt;/em&gt;&lt;/strong&gt; (or without debugging), or use the keyboard shortcut &lt;kbd&gt;ctrl&lt;/kbd&gt; + &lt;kbd&gt;F5&lt;/kbd&gt;&lt;/p&gt;

&lt;p&gt;If you swap over to your browser and navigate to &lt;a href=&quot;http://localhost:2020&quot;&gt;http://localhost:2020&lt;/a&gt; (or whatever port you chose), then you should see an output similar to&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/Hello World.png&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/Hello World.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;adding-a-form-to-capture-the-inputs&quot;&gt;Adding a form to capture the inputs&lt;/h2&gt;

&lt;p&gt;So the next thing we&amp;#8217;re going to need now is an HTML form to capture the text that we want displayed on the certificates, so in my &lt;code class=&quot;highlighter-rouge&quot;&gt;server.js&lt;/code&gt; file, I&amp;#8217;m going to edit the default (root) endpoint (the one that just says &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt;)  which will serve the static HTML page which has the form on it&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sendfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'index.html'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We&amp;#8217;ll also need to create a basic index.html page with a simple one input form with a submit button:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;lang=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Enter details&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Please enter the following information&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;method=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'post'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;action=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'process'&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'text'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;placeholder=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'submit'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Generate PDF&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should be relatively self explanatory, but in case you&amp;#8217;re completely new, a quick run-down&lt;/p&gt;

&lt;p&gt;The first 7 lines are general boilerplate HTML (in fact, it was generated by a VS code extension that I have installed)&lt;/p&gt;

&lt;p&gt;The pieces between the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;body&amp;gt;&lt;/code&gt; &amp;amp; &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; tags are the bits that get displayed on the web page, and the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tag gives us information as to how and where we want to process the collected inputs, which are what the &lt;code class=&quot;highlighter-rouge&quot;&gt;method&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;action&lt;/code&gt; attributes are for.&lt;/p&gt;

&lt;p&gt;Now if we restart our debugging session (by either hitting &lt;kbd&gt;ctrl&lt;/kbd&gt; + &lt;kbd&gt;shift&lt;/kbd&gt; + &lt;kbd&gt;F5&lt;/kbd&gt;) or hitting the restart icon of the debug toolbar &lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/vs-code-debug-toolbar.png&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/vs-code-debug-toolbar.png&quot; /&gt; (2nd from the right).&lt;/p&gt;

&lt;p&gt;Now, if you flick back to your web browser and refresh, you should see the form, like so&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/basic-form.png&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/basic-form.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;processing-the-form-data&quot;&gt;Processing the form data&lt;/h2&gt;

&lt;p&gt;OK, so if you&amp;#8217;ve tried entering data and submitting the form, you&amp;#8217;ll have likely noticed an error gets thrown up like this, because we&amp;#8217;ve not wired up how to handle this data (yet);&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/not-hooked-up.png&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF/not-hooked-up.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So we can check with multiple inputs, I&amp;#8217;ve added an additional field to our HTML page, so we can check multiple inputs coming in, so our form code now looks like&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;method=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'post'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;action=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'process'&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'text'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;placeholder=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'text'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'achievement'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'achievement'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;placeholder=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Achievement&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'submit'&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Generate PDF&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#8217;m going to add a new route block, that is listening on the /process path, but we also need to install something extra that allows us to look at the incoming data from the form.&lt;/p&gt;

&lt;p&gt;In the terminal, run &lt;code class=&quot;highlighter-rouge&quot;&gt;npm i body-parser&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, in our &lt;code class=&quot;highlighter-rouge&quot;&gt;server.js&lt;/code&gt; file we can tell Express how to handle this request and data.&lt;/p&gt;

&lt;p&gt;First, add &lt;code class=&quot;highlighter-rouge&quot;&gt;const bodyParser = require('body-parser');&lt;/code&gt; near the top of the file with the other dependencies that a required.&lt;/p&gt;

&lt;p&gt;Below that, you also need to add &lt;code class=&quot;highlighter-rouge&quot;&gt;app.use(bodyParser.urlencoded({ extended: true }));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, we can add our route, currently we&amp;#8217;ll just return some JSON data back to the browser&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/process'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, save everything and don&amp;#8217;t forget to restart your debugging session again, and starting from the route page, fill in the data, and you should see the data returned back to you in JSON format, as per the below screen animation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF//form-submit-to-json.gif&quot; alt=&quot;/assets/post-images/DevelopingInAContainerNodeMongoPDF//form-submit-to-json.gif&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;finishing-up-part-1&quot;&gt;Finishing up (part 1)&lt;/h2&gt;

&lt;p&gt;This concludes things for this part of this tutorial, I&amp;#8217;m sure you&amp;#8217;ll agree we&amp;#8217;ve covered a fair bit, and we&amp;#8217;ve still got more to come.&lt;/p&gt;

&lt;h2 id=&quot;source-code&quot;&gt;Source code&lt;/h2&gt;

&lt;p&gt;I wanted to ensure that the source code would be available, and I&amp;#8217;ve branched it as such so it aligns with the posts, and it can be viewed on my GitHub &lt;a href=&quot;https://github.com/cmjchrisjones/blog-post-demos/tree/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/post1&quot; target=&quot;_new&quot;&gt;https://github.com/cmjchrisjones/blog-post-demos/tree/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/post1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;or if you want to see the entire source code from this entire series, check out &lt;a href=&quot;https://github.com/cmjchrisjones/blog-post-demos/tree/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/full&quot; target=&quot;_new&quot;&gt;https://github.com/cmjchrisjones/blog-post-demos/tree/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/full&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, if you&amp;#8217;re using source control, don&amp;#8217;t forget to add a .gitignore to ignore things like node_modules&lt;/p&gt;

&lt;!--

/assets/post-images/DevelopingInAContainerNodeMongoPDF/

![/assets/post-images/DevelopingInAContainerNodeMongoPDF/xxx.xxx](/assets/post-images/DevelopingInAContainerNodeMongoPDF/xxx.xxx)

&lt;kbd&gt;key&lt;/kbd&gt;
--&gt;</content><author><name></name></author><category term="MongoDB" /><category term="Node" /><category term="PDF" /><category term="Tutorials &amp; Walkthroughs" /><summary type="html">Pre-requisites Onwards Setting up the project and installing all the things Adding a form to capture the inputs Processing the form data Finishing up (part 1) Source code So this morning I got a whatsapp of a good friend asking me how good I am with Excel, I told him I wasn&amp;#8217;t too bad, and after a few messages back and forth, turns out he doesn&amp;#8217;t need Excel whatsoever, but potentially a website which can generate dynamic PDFs. I thought it might be a good candidate for a blog post, so here goes I&amp;#8217;ve decided that as I&amp;#8217;m writing this, it should probably be split out into multiple posts, so this will be post 1 of 2. For part 2, click here Pre-requisites So, first things first, we need to have Visual Studio installed on your OS of choice with the following VS Code extensions (not sure if all of these are 100% required but I had them installed)! Remote WSL Remote Development Onwards First thing I did was to create a new folder where I was going to store this project. I then opened VS Code and selected the Open a remote window icon in the bottom left of VS Code (or you can use the command pallette (by pressing ctrl + p) and search for remote containers) and select Remote-Containers: Open folder in container... the option and navigate to the folder which you&amp;#8217;ve just created. It will then popup with a whole list of options of different development environments (you can filter these as I have done in the below screenshot), and select Node.js 12 &amp;amp; Mongo DB It may take a couple of minutes to finish setting up, but once its up and running you should see something similar to the below like This will create a .devcontainer folder on disk which will have a dockerfile, docker-compose.yml and devcontainer.json files. Setting up the project and installing all the things So, as with every great node based project, its all starts with a package.json, so I&amp;#8217;ll hit ctrl + &amp;apos; to bring up So, first off I think we&amp;#8217;ll want to install the following things, I&amp;#8217;ll add them in the terminal by running npm i {package name} pdfkit express NOTE If you&amp;#8217;ve done a fresh clone, or &amp;#8216;nuked&amp;#8217; the node_modules folder, its worth noting that you&amp;#8217;ll need to re-run npm -i in the console window to restore the dependencies Because the template container hasn&amp;#8217;t exposed a port, we&amp;#8217;ll need to amend both the dockerfile and docker-compose file to expose the port We also need to tell express how to run and what to serve, so we&amp;#8217;ll create a new file called server.js user the /workspace directory. I&amp;#8217;m just going to add a simple route for now so we can test things work, so the code inside server.js for now will just be the following: const express = require('express') const app = express() app.get('/', function (req, res) { res.send('Hello World') }) console.log('ready and waiting for connections'); module.exports = app.listen(2020); In my Dockerfile I&amp;#8217;ve added the following to the end of it: RUN npm install EXPOSE 2020 CMD [&quot;node&quot;, &quot;server.js&quot;] and inside the docker-compose.yml, under services:web item, I&amp;#8217;ve added in ports: - 2020:2020 Now, with the server.js file selected, we can select Run -&amp;gt; Start Debugging (or without debugging), or use the keyboard shortcut ctrl + F5 If you swap over to your browser and navigate to http://localhost:2020 (or whatever port you chose), then you should see an output similar to Adding a form to capture the inputs So the next thing we&amp;#8217;re going to need now is an HTML form to capture the text that we want displayed on the certificates, so in my server.js file, I&amp;#8217;m going to edit the default (root) endpoint (the one that just says /) which will serve the static HTML page which has the form on it app.get('/', function (req, res) { res.sendfile('index.html'); }) We&amp;#8217;ll also need to create a basic index.html page with a simple one input form with a submit button: &amp;lt;!DOCTYPE html&amp;gt; &amp;lt;html lang=&quot;en&quot;&amp;gt; &amp;lt;head&amp;gt; &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt; &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt; &amp;lt;title&amp;gt;Enter details&amp;lt;/title&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body&amp;gt; &amp;lt;h1&amp;gt;Please enter the following information&amp;lt;/h1&amp;gt; &amp;lt;form method='post' action='process'&amp;gt; &amp;lt;input type='text' name='name' id='name' placeholder=&quot;Name&quot; /&amp;gt; &amp;lt;input type='submit' value=&quot;Generate PDF&quot; /&amp;gt; &amp;lt;/form&amp;gt; &amp;lt;/body&amp;gt; &amp;lt;/html&amp;gt; This should be relatively self explanatory, but in case you&amp;#8217;re completely new, a quick run-down The first 7 lines are general boilerplate HTML (in fact, it was generated by a VS code extension that I have installed) The pieces between the &amp;lt;body&amp;gt; &amp;amp; &amp;lt;/body&amp;gt; tags are the bits that get displayed on the web page, and the &amp;lt;form&amp;gt; tag gives us information as to how and where we want to process the collected inputs, which are what the method and action attributes are for. Now if we restart our debugging session (by either hitting ctrl + shift + F5) or hitting the restart icon of the debug toolbar (2nd from the right). Now, if you flick back to your web browser and refresh, you should see the form, like so Processing the form data OK, so if you&amp;#8217;ve tried entering data and submitting the form, you&amp;#8217;ll have likely noticed an error gets thrown up like this, because we&amp;#8217;ve not wired up how to handle this data (yet); So we can check with multiple inputs, I&amp;#8217;ve added an additional field to our HTML page, so we can check multiple inputs coming in, so our form code now looks like &amp;lt;form method='post' action='process'&amp;gt; &amp;lt;input type='text' name='name' id='name' placeholder=&quot;Name&quot; /&amp;gt; &amp;lt;input type='text' name='achievement' id='achievement' placeholder=&quot;Achievement&quot; /&amp;gt; &amp;lt;input type='submit' value=&quot;Generate PDF&quot; /&amp;gt; &amp;lt;/form&amp;gt; I&amp;#8217;m going to add a new route block, that is listening on the /process path, but we also need to install something extra that allows us to look at the incoming data from the form. In the terminal, run npm i body-parser. Now, in our server.js file we can tell Express how to handle this request and data. First, add const bodyParser = require('body-parser'); near the top of the file with the other dependencies that a required. Below that, you also need to add app.use(bodyParser.urlencoded({ extended: true })); Now, we can add our route, currently we&amp;#8217;ll just return some JSON data back to the browser app.post('/process', (req, res) =&amp;gt; { res.send({ data: [req.body] }); }); Now, save everything and don&amp;#8217;t forget to restart your debugging session again, and starting from the route page, fill in the data, and you should see the data returned back to you in JSON format, as per the below screen animation: Finishing up (part 1) This concludes things for this part of this tutorial, I&amp;#8217;m sure you&amp;#8217;ll agree we&amp;#8217;ve covered a fair bit, and we&amp;#8217;ve still got more to come. Source code I wanted to ensure that the source code would be available, and I&amp;#8217;ve branched it as such so it aligns with the posts, and it can be viewed on my GitHub https://github.com/cmjchrisjones/blog-post-demos/tree/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/post1 or if you want to see the entire source code from this entire series, check out https://github.com/cmjchrisjones/blog-post-demos/tree/developing-a-node-app-with-mongo-and-pdf-generator-in-vs-code-in-a-container/full Lastly, if you&amp;#8217;re using source control, don&amp;#8217;t forget to add a .gitignore to ignore things like node_modules</summary></entry><entry><title type="html">My Journey From A Manual Labourer To A Call Centre Worker To Software Developer</title><link href="/blog/more-about-me/" rel="alternate" type="text/html" title="My Journey From A Manual Labourer To A Call Centre Worker To Software Developer" /><published>2019-12-01T00:00:00+00:00</published><updated>2019-12-01T00:00:00+00:00</updated><id>/blog/my-journey-from-a-manual-labourer-to-a-call-centre-worker-to-software-developer</id><content type="html" xml:base="/blog/more-about-me/">&lt;h3 id=&quot;my-background-and-how-i-got-a-software-engineer-role&quot;&gt;My background and how I got a software engineer role&lt;/h3&gt;

&lt;p&gt;I’ve been a software engineer now for around 20 months, after months and years of thinking about starting a blog, I’ve finally decided to do it! I’m going to cover topics which I believe are quite useful, such as software development which shouldn’t be any surprise, to some security things, such as how to identify spam emails or hoaxes. I hope that people will find this useful.&lt;/p&gt;

&lt;p&gt;In a nutshell, I just wanted to prove that it is possible and within reach, to get a software development job without a computer science degree and into your 30’s!&lt;/p&gt;

&lt;p&gt;Although I’ve always had a strong interest in IT, I was never that academic, and I thought that to get into IT you needed various degrees to be able to just get your foot in the door of a company, unless of course you went solo.&lt;/p&gt;

&lt;p&gt;Turns out that is just a myth!&lt;/p&gt;

&lt;p&gt;When I left school in 2000 at age 16, I had relatively poor exam results, they weren’t bad, but they weren’t brilliant either! The prospect of going to college to do A Levels didn’t appeal, neither did university. So, I went straight out to work, physical/manual jobs to start off with as I didn’t think I’d be able to get anything in an office.&lt;/p&gt;

&lt;h3 id=&quot;timeline&quot;&gt;Timeline&lt;/h3&gt;

&lt;h4 id=&quot;2008&quot;&gt;2008&lt;/h4&gt;

&lt;p&gt;After various jobs both in a manual and office environment, I went back to a previous employer and started working again in a call centre (for the 2nd time). Although this isn’t many people’s idea of a perfect job, it’s one of the main employers in the city I live in and was again my ‘foot in the door’ so to speak.&lt;/p&gt;

&lt;p&gt;All this time I was learning various bits of coding and software development, initially it was just PHP, MySQL, HTML &amp;amp; CSS.&lt;/p&gt;

&lt;p&gt;I moved teams in the call centre after a couple of years due to an organisation restructure, and it was my new manager who really kicked things off for me.&lt;/p&gt;

&lt;h5 id=&quot;2010&quot;&gt;2010&lt;/h5&gt;

&lt;p&gt;One of my new team colleagues started giving me the nickname of &lt;em&gt;techy&lt;/em&gt; shortly after I joined, and then a couple of months later, my manager said there was an opportunity to be involved in an IT project from an inception stage, because he also knew I was into the technical side of things he asked if I’d be interested, of course I jumped at the chance.&lt;/p&gt;

&lt;p&gt;The project itself was to look at building a new web based front end system which was able to connect with various old backend systems, some which still ran on mainframe, and one that was VB6 application. I done some analysis and identified that the call centre agents (me included) used on average around 10-15 different systems to deal with customer enquiries on a daily basis, depending on what the customer needed, to add to this, I think overall our department had around 50 overall applications that were probably used at least once a fortnight, if not more.&lt;/p&gt;

&lt;p&gt;What we wanted to achieve was building a simple, easy to use and understand system, which anyone could use, our mantra at the time was we wanted call handlers to be customer &amp;amp; product experts, not system experts, that’s where I and 5 other colleagues from different departments came in.&lt;/p&gt;

&lt;p&gt;Our job was to be Subject Matter Experts (SME’s), for the product which was to be built by our IT department. We were representing the end users of this new application, what did we need in order to be able to do our job better. Before, there had been a culture of requesting something or other from IT, they built it, then what we got back wasn’t either what was required, fit for purpose or was just completely different to what was needed. Those familiar using the Agile methodologies may have seen this diagram before!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i2.wp.com/blogs.perficientdigital.com/files/2011/07/treecomicbig.jpg?resize=800%2C600&amp;amp;ssl=1&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So, the 6 of us were brought in, to sit with the people from IT, this was quite daunting at first, but soon got to know the inner workings of IT Project Management. From Project Managers, Programme Managers, Business Analysts, Solution Designers, Programmers and lots of other people whose roles I can no longer remember.&lt;/p&gt;

&lt;p&gt;Over the next 6-9 months, we worked closely with the Business Analysts, where we would tell them our requirements, and ideas as to what we would like our new system to do. This involved mocking up some wireframes and bouncing ideas of one another.&lt;/p&gt;

&lt;p&gt;Shortly after this, we found ourselves seconded into the testing teams, me and 2 others were put into a component level test team, while the rest went into the User Acceptance Test (UAT) team.&lt;/p&gt;

&lt;p&gt;It was here where I started to learn about different testing approaches, writing test scripts, and test conditions from a set of requirements, writing test plans etc. We were using waterfall and I was introduced to things such as the V-Model paradigm&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Systems_Engineering_Process_II.svg/880px-Systems_Engineering_Process_II.svg.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Fast-forward a couple of years, my job had changed, and I was a full time Software Tester, I’d stayed at the company but was fortunate enough to change my secondment into my permanent role.&lt;/p&gt;

&lt;h5 id=&quot;2012&quot;&gt;2012&lt;/h5&gt;

&lt;p&gt;We then started to use Agile on more and more projects, and I was lucky enough to get assigned a role within a new sub-organisation of the company which was just for Software Development and testing, unsurprisingly this was called &lt;strong&gt;Digital&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;I was also more experienced in testing, including picking up some new skills along the way such as automated software testing using Selenium, and was introduced to Behaviour Driven Development. For the first time, I had a decent career, and I knew which direction I wanted it to go.&lt;/p&gt;

&lt;p&gt;Working in this agile environment, meant I was embedded in teams of software engineers, so every now and again I would either sit with them, watching trying to turn our user stories into code to make our website do some neat things, so I started to learn C# in some of my spare time.&lt;/p&gt;

&lt;p&gt;I ended up developing an application which is now used by our whole testing department, it allows them to query our non-production databases to find and identify test customers who have &lt;em&gt;x&lt;/em&gt; or &lt;em&gt;y&lt;/em&gt;, or have a combination of &lt;em&gt;x, y and z&lt;/em&gt;. They use this by using a website and not needing to know any SQL or what the database schema looks like behind the scenes (and its pretty complicated)!&lt;/p&gt;

&lt;h5 id=&quot;2017&quot;&gt;2017&lt;/h5&gt;

&lt;p&gt;So, by now, I’ve dropped some big hints to various people I work with about my career aspirations, which are to move into Software Development. I had one of the senior managers tell me there was an internal vacancy coming up to join the software development team and that I should apply, nervously I did, and I waited with bated breath, then, about 2 weeks later, I received an email from our HR department confirming I had got an interview.&lt;/p&gt;

&lt;p&gt;So, I start swatting up the best I can, I start asking around some of our lead software engineers what I should be looking out for, what sort of questions I might be asked, what would be good to have under my hat so to speak.&lt;/p&gt;

&lt;p&gt;So, now I find myself the evening before my interview for the job I’ve wanted since I’ve left school, however I’m now 30! Would I stand a chance?&lt;/p&gt;

&lt;p&gt;I’m sat with my girlfriend (non-techy) trying to fire questions at me, I thought some of them were a little daft or that they wouldn’t be asked in the interview, but I was wrong!&lt;/p&gt;

&lt;p&gt;The next day I went into work, my interview not until 10AM. I had a few pointers from other colleagues, however I was still a little nervous, who isn’t on an interview!&lt;/p&gt;

&lt;p&gt;So now I’m sat in a room with 2 people I kind of know, but not that well, a Platform Manager and a Senior Technical Architect. They fired questions to me one after the other taking it in turns, some related to software development, others around my other competencies and experiences over my years at the company and why I wanted to make the move.&lt;/p&gt;

&lt;p&gt;45 minutes later and the interview is over, I go back and carry on my normal day job, and so it goes over the next couple of days, I was told in the interview that they would like me to do a technical test, which they would send me instructions for.&lt;/p&gt;

&lt;p&gt;About 2 days later, I got the instructions, I needed to write a Fizz Buzz application. I was vaguely aware this is what it was going to be, but I had imagined it a little bit too simply.&lt;/p&gt;

&lt;p&gt;My manager managed to get me some time to put aside to complete this, I had a set of instructions and was told I needed to complete as much as I could within 2 hours, while committing and pushing to a GIT repository every 10 minutes.&lt;/p&gt;

&lt;p&gt;I did my best, but about a fortnight after, I was taken into a room, and was told I had been unsuccessful. It was a little disheartening, but at the same time I was being praised about how well I was doing my current job as a Test Analyst but was also told that it wasn’t a hard ‘No’, but more of a ‘not yet’. As a result of this I was paired with a senior developer to go over the results of my technical test, and what I should’ve or could’ve done better, this was supposed to happen roughly fortnightly however because we both were in different teams scheduling times was never easy.&lt;/p&gt;

&lt;p&gt;However, I was still able to learn, I got to know the developers in my team really well, I could always ask them questions and if they had time, they wouldn’t hesitate to help me!&lt;/p&gt;

&lt;p&gt;December 2016 - I was approached and was told there was another vacancy in the pipeline, it needed to be signed off by our director, but once it had I was told I should apply. January the role was advertised, I applied, and an interview was scheduled. It was to be the same 2 people that originally interviewed me back in 2015. I asked one of them, whether it was going to be another proper formal interview, I was told it wasn’t going to be, they had become aware of this testing tool that I had written and wanted an informal chat about what it was I had learnt since my earlier interview, and a demo of the functionality of this tool that I had built almost single-handedly for the past 3 years.&lt;/p&gt;

&lt;p&gt;February - I received fantastic news, I was given the opportunity I’d always wanted, I’d got the job! I just had to wait for the interdepartmental politics to run its course, by me leaving my testing role I was leaving a bit of a knowledge gap, so I needed to get a couple of others up to speed.&lt;/p&gt;

&lt;h5 id=&quot;1st-april-2017&quot;&gt;1st April 2017&lt;/h5&gt;

&lt;p&gt;This is the day I started the job I’ve always wanted since I left school in 2000, although I’m now 33!&lt;/p&gt;

&lt;p&gt;I started work in a new team, I was told it was going to be tough, with a steep learning curve but I didn’t care, this was the job I wanted! But boy, they weren’t wrong!&lt;/p&gt;

&lt;p&gt;The department I joined was our quote and buy team. It had been separated into 2 team, one dealing with the legacy system which is a .NET MVC application, and the team I joined, using all pretty new technologies which I hadn’t really heard of before, Akka.NET, ReactJS to name 2. This was going to be something that was going to replace the older system one day, so a decision was made to put me into the team building all the new and shiny stuff, even though I’d been teaching myself MVC for the last 3 years!&lt;/p&gt;

&lt;h5 id=&quot;now---december-2018&quot;&gt;Now - December 2018&lt;/h5&gt;

&lt;p&gt;I’m still finding my feet in terms of software development and using AKKA.NET, but I’m getting better and getting a bit more confident with making code changes, although I do still probably ask my tech lead far too many questions!&lt;/p&gt;

&lt;p&gt;In some of my spare time I try and invest as much as I can in learning whilst juggling a few personal projects. This is mostly from either YouTube, Pluralsight or Lynda (I’m fortunate that I get currently get a licence for the latter 2 from my employer).&lt;/p&gt;

&lt;p&gt;I’m also really liking some of the content that’s now becoming readily available, especially via the medium of Twitch. There are quite a few software development streams that now seem to be popping up, but one channel I would like to give a shout-out to, and one which I stumbled across is a &lt;a href=&quot;https://twitch.tv/csharpfritz&quot; target=&quot;_new&quot;&gt;channel hosted by Jeff Fritz (csharpfritz)&lt;/a&gt;. What I really like about this, is the way that you can ask almost anything development or software related, and Jeff will try and answer, and if not, he might know someone who can as he is also a Microsoft Program Manager. He also manages to get some other big names on from the developer community, and occasionally hosts full day workshops, and if you can’t make those, then they’re normally uploaded to YouTube a little later for OnDemand watching.&lt;/p&gt;

&lt;p&gt;Not only that, during the streams, Jeff is working on some real-world tools and applications to help share his knowledge with us, and we’re encouraged to try and help him out if we can. All his code is on GitHub and can be read / downloaded or forked so you can work on it too. All of which, is free. He even makes donations to an organisation to try and help get those that are underprivileged or minority groups into software development. It’s something I’ve been recommending to various friends and colleagues of mine who are also looking to try and get into C# development.&lt;/p&gt;</content><author><name>Chris</name></author><category term="General" /><summary type="html">My background and how I got a software engineer role I’ve been a software engineer now for around 20 months, after months and years of thinking about starting a blog, I’ve finally decided to do it! I’m going to cover topics which I believe are quite useful, such as software development which shouldn’t be any surprise, to some security things, such as how to identify spam emails or hoaxes. I hope that people will find this useful. In a nutshell, I just wanted to prove that it is possible and within reach, to get a software development job without a computer science degree and into your 30’s! Although I’ve always had a strong interest in IT, I was never that academic, and I thought that to get into IT you needed various degrees to be able to just get your foot in the door of a company, unless of course you went solo. Turns out that is just a myth! When I left school in 2000 at age 16, I had relatively poor exam results, they weren’t bad, but they weren’t brilliant either! The prospect of going to college to do A Levels didn’t appeal, neither did university. So, I went straight out to work, physical/manual jobs to start off with as I didn’t think I’d be able to get anything in an office. Timeline 2008 After various jobs both in a manual and office environment, I went back to a previous employer and started working again in a call centre (for the 2nd time). Although this isn’t many people’s idea of a perfect job, it’s one of the main employers in the city I live in and was again my ‘foot in the door’ so to speak. All this time I was learning various bits of coding and software development, initially it was just PHP, MySQL, HTML &amp;amp; CSS. I moved teams in the call centre after a couple of years due to an organisation restructure, and it was my new manager who really kicked things off for me. 2010 One of my new team colleagues started giving me the nickname of techy shortly after I joined, and then a couple of months later, my manager said there was an opportunity to be involved in an IT project from an inception stage, because he also knew I was into the technical side of things he asked if I’d be interested, of course I jumped at the chance. The project itself was to look at building a new web based front end system which was able to connect with various old backend systems, some which still ran on mainframe, and one that was VB6 application. I done some analysis and identified that the call centre agents (me included) used on average around 10-15 different systems to deal with customer enquiries on a daily basis, depending on what the customer needed, to add to this, I think overall our department had around 50 overall applications that were probably used at least once a fortnight, if not more. What we wanted to achieve was building a simple, easy to use and understand system, which anyone could use, our mantra at the time was we wanted call handlers to be customer &amp;amp; product experts, not system experts, that’s where I and 5 other colleagues from different departments came in. Our job was to be Subject Matter Experts (SME’s), for the product which was to be built by our IT department. We were representing the end users of this new application, what did we need in order to be able to do our job better. Before, there had been a culture of requesting something or other from IT, they built it, then what we got back wasn’t either what was required, fit for purpose or was just completely different to what was needed. Those familiar using the Agile methodologies may have seen this diagram before! So, the 6 of us were brought in, to sit with the people from IT, this was quite daunting at first, but soon got to know the inner workings of IT Project Management. From Project Managers, Programme Managers, Business Analysts, Solution Designers, Programmers and lots of other people whose roles I can no longer remember. Over the next 6-9 months, we worked closely with the Business Analysts, where we would tell them our requirements, and ideas as to what we would like our new system to do. This involved mocking up some wireframes and bouncing ideas of one another. Shortly after this, we found ourselves seconded into the testing teams, me and 2 others were put into a component level test team, while the rest went into the User Acceptance Test (UAT) team. It was here where I started to learn about different testing approaches, writing test scripts, and test conditions from a set of requirements, writing test plans etc. We were using waterfall and I was introduced to things such as the V-Model paradigm Fast-forward a couple of years, my job had changed, and I was a full time Software Tester, I’d stayed at the company but was fortunate enough to change my secondment into my permanent role. 2012 We then started to use Agile on more and more projects, and I was lucky enough to get assigned a role within a new sub-organisation of the company which was just for Software Development and testing, unsurprisingly this was called Digital! I was also more experienced in testing, including picking up some new skills along the way such as automated software testing using Selenium, and was introduced to Behaviour Driven Development. For the first time, I had a decent career, and I knew which direction I wanted it to go. Working in this agile environment, meant I was embedded in teams of software engineers, so every now and again I would either sit with them, watching trying to turn our user stories into code to make our website do some neat things, so I started to learn C# in some of my spare time. I ended up developing an application which is now used by our whole testing department, it allows them to query our non-production databases to find and identify test customers who have x or y, or have a combination of x, y and z. They use this by using a website and not needing to know any SQL or what the database schema looks like behind the scenes (and its pretty complicated)! 2017 So, by now, I’ve dropped some big hints to various people I work with about my career aspirations, which are to move into Software Development. I had one of the senior managers tell me there was an internal vacancy coming up to join the software development team and that I should apply, nervously I did, and I waited with bated breath, then, about 2 weeks later, I received an email from our HR department confirming I had got an interview. So, I start swatting up the best I can, I start asking around some of our lead software engineers what I should be looking out for, what sort of questions I might be asked, what would be good to have under my hat so to speak. So, now I find myself the evening before my interview for the job I’ve wanted since I’ve left school, however I’m now 30! Would I stand a chance? I’m sat with my girlfriend (non-techy) trying to fire questions at me, I thought some of them were a little daft or that they wouldn’t be asked in the interview, but I was wrong! The next day I went into work, my interview not until 10AM. I had a few pointers from other colleagues, however I was still a little nervous, who isn’t on an interview! So now I’m sat in a room with 2 people I kind of know, but not that well, a Platform Manager and a Senior Technical Architect. They fired questions to me one after the other taking it in turns, some related to software development, others around my other competencies and experiences over my years at the company and why I wanted to make the move. 45 minutes later and the interview is over, I go back and carry on my normal day job, and so it goes over the next couple of days, I was told in the interview that they would like me to do a technical test, which they would send me instructions for. About 2 days later, I got the instructions, I needed to write a Fizz Buzz application. I was vaguely aware this is what it was going to be, but I had imagined it a little bit too simply. My manager managed to get me some time to put aside to complete this, I had a set of instructions and was told I needed to complete as much as I could within 2 hours, while committing and pushing to a GIT repository every 10 minutes. I did my best, but about a fortnight after, I was taken into a room, and was told I had been unsuccessful. It was a little disheartening, but at the same time I was being praised about how well I was doing my current job as a Test Analyst but was also told that it wasn’t a hard ‘No’, but more of a ‘not yet’. As a result of this I was paired with a senior developer to go over the results of my technical test, and what I should’ve or could’ve done better, this was supposed to happen roughly fortnightly however because we both were in different teams scheduling times was never easy. However, I was still able to learn, I got to know the developers in my team really well, I could always ask them questions and if they had time, they wouldn’t hesitate to help me! December 2016 - I was approached and was told there was another vacancy in the pipeline, it needed to be signed off by our director, but once it had I was told I should apply. January the role was advertised, I applied, and an interview was scheduled. It was to be the same 2 people that originally interviewed me back in 2015. I asked one of them, whether it was going to be another proper formal interview, I was told it wasn’t going to be, they had become aware of this testing tool that I had written and wanted an informal chat about what it was I had learnt since my earlier interview, and a demo of the functionality of this tool that I had built almost single-handedly for the past 3 years. February - I received fantastic news, I was given the opportunity I’d always wanted, I’d got the job! I just had to wait for the interdepartmental politics to run its course, by me leaving my testing role I was leaving a bit of a knowledge gap, so I needed to get a couple of others up to speed. 1st April 2017 This is the day I started the job I’ve always wanted since I left school in 2000, although I’m now 33! I started work in a new team, I was told it was going to be tough, with a steep learning curve but I didn’t care, this was the job I wanted! But boy, they weren’t wrong! The department I joined was our quote and buy team. It had been separated into 2 team, one dealing with the legacy system which is a .NET MVC application, and the team I joined, using all pretty new technologies which I hadn’t really heard of before, Akka.NET, ReactJS to name 2. This was going to be something that was going to replace the older system one day, so a decision was made to put me into the team building all the new and shiny stuff, even though I’d been teaching myself MVC for the last 3 years! Now - December 2018 I’m still finding my feet in terms of software development and using AKKA.NET, but I’m getting better and getting a bit more confident with making code changes, although I do still probably ask my tech lead far too many questions! In some of my spare time I try and invest as much as I can in learning whilst juggling a few personal projects. This is mostly from either YouTube, Pluralsight or Lynda (I’m fortunate that I get currently get a licence for the latter 2 from my employer). I’m also really liking some of the content that’s now becoming readily available, especially via the medium of Twitch. There are quite a few software development streams that now seem to be popping up, but one channel I would like to give a shout-out to, and one which I stumbled across is a channel hosted by Jeff Fritz (csharpfritz). What I really like about this, is the way that you can ask almost anything development or software related, and Jeff will try and answer, and if not, he might know someone who can as he is also a Microsoft Program Manager. He also manages to get some other big names on from the developer community, and occasionally hosts full day workshops, and if you can’t make those, then they’re normally uploaded to YouTube a little later for OnDemand watching. Not only that, during the streams, Jeff is working on some real-world tools and applications to help share his knowledge with us, and we’re encouraged to try and help him out if we can. All his code is on GitHub and can be read / downloaded or forked so you can work on it too. All of which, is free. He even makes donations to an organisation to try and help get those that are underprivileged or minority groups into software development. It’s something I’ve been recommending to various friends and colleagues of mine who are also looking to try and get into C# development.</summary></entry><entry><title type="html">Creating a basic WebApp with MySQL and CICD pipeline using azure release pipelines</title><link href="/posts/creating-a-basic-WebApp-with-MySQL-and-CICD-pipeline-using-azure-release-pipelines/" rel="alternate" type="text/html" title="Creating a basic WebApp with MySQL and CICD pipeline using azure release pipelines" /><published>2018-11-27T00:00:00+00:00</published><updated>2018-11-27T00:00:00+00:00</updated><id>/posts/creating-a-basic-WebApp-with-MySQL-and-CICD-pipeline-using-azure-release-pipelines</id><content type="html" xml:base="/posts/creating-a-basic-WebApp-with-MySQL-and-CICD-pipeline-using-azure-release-pipelines/">&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-Requisites&lt;/h2&gt;

&lt;p&gt;In order to follow along, it would be useful if you already had the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An Azure Account&lt;/li&gt;
  &lt;li&gt;A Website you want to deploy which integrates with a MySQL database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;setting-up-the-azure-website&quot;&gt;Setting up the Azure Website&lt;/h2&gt;

&lt;p&gt;Start of, by creating an account on Azure if you do not already have one, once you have, navigate to your dashboard (https://portal.azure.com)&lt;/p&gt;

&lt;p&gt;If you’re planning on managing multiple projects, or are just wanting to try this out, then as a suggestion I could recommend creating a resource group first and foremost as this helps organise all your bits and pieces, for the latter reason, if you are just wanting this temporarily, then its easy to just tear it all down!&lt;/p&gt;

&lt;p&gt;To create a resource group, select resource group from the left hand menu, and in the main pane (called blades in Azure), click on the + Add button, and give your resource group a name, select subscription and region, and click on create.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Create-Resource-Group.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once your resource group has been created, you can now add more applications to it, and to add our Web App + MySQL resource, and select the Add button and search for Web App + MySQL&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Add-Application.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Select the Web App + MySQL, click on Create which will open up a new settings blade, as we’re setting this up just for testing a website, we can select MySQL In App as the Database provider, you just need to select what your planning on using as your App name, this would be what would be your website address (pre DNS if you choose to have that later on (I’ll cover that in a separate post)), then if they’re not prefilled already, select your subscription and resource group, and select create.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Settings.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Great, now we’ve got that done, you should be able to navigate to &lt;code class=&quot;highlighter-rouge&quot;&gt;http://{your App name}.azurewebsites.net&lt;/code&gt;, all being well you should see the Azure Websites holding page&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Holding-Page.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;setting-up-the-azure-pipeline&quot;&gt;Setting up the Azure Pipeline&lt;/h2&gt;

&lt;p&gt;Next step is we’re going to configure Azure DevOps Pipelines, I’m also going to use Azure DevOps Repos to host my code in a GIT style (see this post for how to set up a Azure Repo’s)&lt;/p&gt;

&lt;p&gt;When your code is pushed to an Azure Repos, login to your organisation, select your project, and click on Pipeline in the left hand menu, indicated by the space ship icon, and select builds, you should see a page where you can create a new pipeline&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Azure-Repos.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click on the new pipeline button, select where your code is hosted (for me its in Azure Repos GIT), select your team project, repository and which branch you want to run your CI/CD pipeline for, as I’m pretty much the sole developer, I’m going to select master and press continue&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Connecting-to-a-repo.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now I can either use a template or manually create my build definition, for simplicity at this time, I’m going to select ASP.NET Core&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Setting-up-the-pipeline.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now I can customise the build job&lt;/p&gt;

&lt;p&gt;I’ll keep the name as it is for now, select an agent pool (this is just a VM that spins up to build your application, then publishes the artefacts and destroys itself).&lt;/p&gt;

&lt;p&gt;I’ll leave the options as they are for the time being&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Default-Options.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’m now going to see how much of this just works out of the box by hitting the save and queue button, however, because we are doing a web project I need to ensure that is what gets published, select the Publish step, and tick the Publish Web Projects option&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Publish-Options.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If all goes to plan, it should all pass&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Success.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So now we have a passing build pipeline, we can now create a release pipeline, to do this, select the Releases tab under the Piplenes menu and click on the new pipelines button&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Release.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here is where we can link it up to our Azure Website, ,select Axxure App Service deploylemtn from the right hand side and click apply&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Link-it-up.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now we need to link it to the build artifact from above&lt;/p&gt;

&lt;p&gt;Click on the ‘Add an artifact’ link, select build, and the build pipeline and click add.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Add-artifact.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Give it a Stage Name, then click on Tasks in the top menu&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Setting-up-a-task.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Select your appropriate settings for your Azure app&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Task-Settings.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Save, and then click Release to create a manual release&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2019-01-01-Creating-a-basic-webapp-with-mysql-and-CICD-pipeline-using-azure-release-pipelines/Queing-a-release.png&quot; alt=&quot;&quot; class=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;All being well, you should now be able to navigate to your website at &lt;code class=&quot;highlighter-rouge&quot;&gt;http://{your App name}.azurewebsites.net&lt;/code&gt; and see your code/website running&lt;/p&gt;

&lt;p&gt;I will be covering how to setup automatic deployment when code is pushed or merged into the master branch in a future post.&lt;/p&gt;</content><author><name>Chris</name></author><category term="Continuous Integration" /><category term="Continuous Deployment" /><category term="Tutorials &amp; Walkthroughs" /><category term="Website Deployment" /><category term="CICD" /><category term="Azure" /><category term="MySQL" /><category term="WebApp" /><category term="Azure Release Pipelines" /><summary type="html">Pre-Requisites In order to follow along, it would be useful if you already had the following: An Azure Account A Website you want to deploy which integrates with a MySQL database Setting up the Azure Website Start of, by creating an account on Azure if you do not already have one, once you have, navigate to your dashboard (https://portal.azure.com) If you’re planning on managing multiple projects, or are just wanting to try this out, then as a suggestion I could recommend creating a resource group first and foremost as this helps organise all your bits and pieces, for the latter reason, if you are just wanting this temporarily, then its easy to just tear it all down! To create a resource group, select resource group from the left hand menu, and in the main pane (called blades in Azure), click on the + Add button, and give your resource group a name, select subscription and region, and click on create. Once your resource group has been created, you can now add more applications to it, and to add our Web App + MySQL resource, and select the Add button and search for Web App + MySQL Select the Web App + MySQL, click on Create which will open up a new settings blade, as we’re setting this up just for testing a website, we can select MySQL In App as the Database provider, you just need to select what your planning on using as your App name, this would be what would be your website address (pre DNS if you choose to have that later on (I’ll cover that in a separate post)), then if they’re not prefilled already, select your subscription and resource group, and select create. Great, now we’ve got that done, you should be able to navigate to http://{your App name}.azurewebsites.net, all being well you should see the Azure Websites holding page Setting up the Azure Pipeline Next step is we’re going to configure Azure DevOps Pipelines, I’m also going to use Azure DevOps Repos to host my code in a GIT style (see this post for how to set up a Azure Repo’s) When your code is pushed to an Azure Repos, login to your organisation, select your project, and click on Pipeline in the left hand menu, indicated by the space ship icon, and select builds, you should see a page where you can create a new pipeline Click on the new pipeline button, select where your code is hosted (for me its in Azure Repos GIT), select your team project, repository and which branch you want to run your CI/CD pipeline for, as I’m pretty much the sole developer, I’m going to select master and press continue Now I can either use a template or manually create my build definition, for simplicity at this time, I’m going to select ASP.NET Core Now I can customise the build job I’ll keep the name as it is for now, select an agent pool (this is just a VM that spins up to build your application, then publishes the artefacts and destroys itself). I’ll leave the options as they are for the time being I’m now going to see how much of this just works out of the box by hitting the save and queue button, however, because we are doing a web project I need to ensure that is what gets published, select the Publish step, and tick the Publish Web Projects option If all goes to plan, it should all pass So now we have a passing build pipeline, we can now create a release pipeline, to do this, select the Releases tab under the Piplenes menu and click on the new pipelines button Here is where we can link it up to our Azure Website, ,select Axxure App Service deploylemtn from the right hand side and click apply Now we need to link it to the build artifact from above Click on the ‘Add an artifact’ link, select build, and the build pipeline and click add. Give it a Stage Name, then click on Tasks in the top menu Select your appropriate settings for your Azure app Save, and then click Release to create a manual release All being well, you should now be able to navigate to your website at http://{your App name}.azurewebsites.net and see your code/website running I will be covering how to setup automatic deployment when code is pushed or merged into the master branch in a future post.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="/assets/post-images/azure-web-app/AzureMySQLBlogHero.jpg" /></entry></feed>