<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-AU" xmlns:media="http://search.yahoo.com/mrss/">
  <id>https://david.gardiner.net.au/tags/Docker.xml</id>
  <title type="html">David Gardiner - Docker</title>
  <updated>2026-07-13T00:27:34.062Z</updated>
  <subtitle>Blog posts tagged with &apos;Docker&apos; - A blog of software development, .NET and other interesting things</subtitle>
  <rights>Copyright 2026 David Gardiner</rights>
  <icon>https://www.gravatar.com/avatar/37edf2567185071646d62ba28b868fab?s=64</icon>
  <logo>https://www.gravatar.com/avatar/37edf2567185071646d62ba28b868fab?s=256</logo>
  <generator uri="https://github.com/flcdrg/astrojs-atom" version="3">astrojs-atom</generator>
  <author>
    <name>David Gardiner</name>
  </author>
  <link href="https://david.gardiner.net.au/tags/Docker.xml" rel="self" type="application/atom+xml"/>
  <link href="https://david.gardiner.net.au/tags/Docker" rel="alternate" type="text/html" hreflang="en-AU"/>
  <category term="Docker"/>
  <category term="Software Development"/>
  <entry>
    <id>https://david.gardiner.net.au/2022/01/synology-speedtest</id>
    <updated>2022-01-03T13:00:00.000+10:30</updated>
    <title>Running Speedtest on a Synology NAS</title>
    <link href="https://david.gardiner.net.au/2022/01/synology-speedtest" rel="alternate" type="text/html" title="Running Speedtest on a Synology NAS"/>
    <category term="Synology"/>
    <category term="Docker"/>
    <published>2022-01-03T13:00:00.000+10:30</published>
    <summary type="html">How to install and configure Speedtest Tracker on a Synology NAS using Docker to run scheduled internet speed tests and monitor your home connection quality over time.</summary>
    <content type="html">
&lt;p&gt;Yesterday I noticed that our home Internet speed seemed a bit sluggish. Logging into the modem showed that instead of the usual 48-50Mbps, we were only getting around 25 (and sometimes much worse). Restarting the modem did not improve the speed, so I resorted to calling our ISP (Internode). They tried a reset from their end (on the NBN &apos;Node&apos; I believe) but still no improvement. They&apos;ve logged a call with the NBN who are scheduled to investigate the problem tomorrow. Interestingly the Internode support person said I was the third person she&apos;d dealt with in the last few hours with a speed problem in my area.&lt;/p&gt;
&lt;p&gt;Anyway this got me thinking. It would be nice to have some kind of regular scheduled speed test running to be able to monitor (and possibly even be notified of changes) to our Internet speed.&lt;/p&gt;
&lt;p&gt;Doing a search for &quot;synology speed test&quot; came up with &lt;a href=&quot;https://mariushosting.com/how-to-install-speedtest-tracker-on-your-synology-nas/&quot;&gt;How to Install Speedtest Tracker on Your Synology NAS&lt;/a&gt;, which I started to follow when I realised that actually I think this could be done through the Synology Docker UI, rather than using a scheduled task. Here&apos;s what I did:&lt;/p&gt;
&lt;h2&gt;Installing Speedtest Tracker&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the Synology UI, open the &lt;strong&gt;Docker&lt;/strong&gt; application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the &lt;strong&gt;Registry&lt;/strong&gt; page, and enter &lt;code&gt;speedtest-tracker&lt;/code&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-01.C8BvOzgx_ZdI0kC.webp&quot; alt=&quot;Docker Registry page&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;henrywhitaker3/speedtest-tracker&lt;/strong&gt;, then click &lt;strong&gt;Download&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At the &lt;strong&gt;Choose Tag&lt;/strong&gt; prompt, select &lt;strong&gt;latest&lt;/strong&gt; and click &lt;strong&gt;Select&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the &lt;strong&gt;Image&lt;/strong&gt; page and wait for the image to finish downloading&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-02.DWxiHnb5_ctV1f.webp&quot; alt=&quot;Docker Image page&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;henrywhitaker3/speedtest-tracker:latest&lt;/strong&gt; image and click on &lt;strong&gt;Launch&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Container Name&lt;/strong&gt; enter &lt;code&gt;Speedtest&lt;/code&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-03.cDt2bamd_Z2tnixs.webp&quot; alt=&quot;Create container&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;strong&gt;Advanced Settings&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under &lt;strong&gt;Advanced Settings&lt;/strong&gt; tab, check &lt;strong&gt;Enable auto-restart&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under &lt;strong&gt;Volume&lt;/strong&gt; tab, click &lt;strong&gt;Add Folder&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-04.C9fMEih__11NvWr.webp&quot; alt=&quot;Create folder&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;docker&lt;/strong&gt; folder and click on &lt;strong&gt;Create Folder&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter &lt;code&gt;speedtest&lt;/code&gt; and click &lt;strong&gt;OK&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Select&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Mount Path&lt;/strong&gt; field, enter &lt;code&gt;/config&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under &lt;strong&gt;Port Settings&lt;/strong&gt; tab, select the &lt;strong&gt;443&lt;/strong&gt; row and click on the &lt;strong&gt;-&lt;/strong&gt; button to delete the row.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;80&lt;/strong&gt; row and in the &lt;strong&gt;Local Port&lt;/strong&gt; field, enter &lt;code&gt;8788&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-05.BwETSnhm_26VPm4.webp&quot; alt=&quot;Port settings tab&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under the &lt;strong&gt;Environment&lt;/strong&gt; tab, click the &lt;strong&gt;+&lt;/strong&gt; button to add the following environment variables. Refer to Marius&apos;s &lt;a href=&quot;https://mariushosting.com/synology-find-uid-userid-and-gid-groupid-in-5-seconds/&quot;&gt;tip on getting the values for PUID and PGID&lt;/a&gt;, and unless you also live in Adelaide you&apos;ll need to change the &lt;strong&gt;TZ&lt;/strong&gt; value to something from &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_tz_database_time_zones&quot;&gt;this list&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;variable&lt;/th&gt;
&lt;th&gt;value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PUID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PGID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TZ&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Australia/Adelaide&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OOKLA_EULA_GDPR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-06.Cc6OrhDP_1GlHOz.webp&quot; alt=&quot;Environment tab&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Apply&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review the summary to confirm the details are correct then click on &lt;strong&gt;Apply&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-07.CusfTE8X_Z1F71qM.webp&quot; alt=&quot;Create Container summary&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch to the &lt;strong&gt;Container&lt;/strong&gt; page and confirm that the container is running.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-08.BWCdV-au_1a92gG.webp&quot; alt=&quot;Docker Container page with Speedtest running&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now browse to &lt;a href=&quot;http://your-synology:8788&quot;&gt;http://your-synology:8788&lt;/a&gt; (Change &lt;code&gt;your-synology&lt;/code&gt; to the IP address or name of your Synology). Either click the button to start the test, or just wait a minute or so (as it started automatically for me).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/speedtest-09.KCfDrcfQ_dn3qB.webp&quot; alt=&quot;Speedtest running&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So now Speedtest Tracker application is running a test every hour. Over time, this should become a useful reference to map our average Internet speed (and be able to identify outages or degradations). Hopefully tomorrow it might also track the restoration of our speed if NBN can fix the problem.&lt;/p&gt;
</content>
    <media:thumbnail url="https://david.gardiner.net.au/_astro/speedtest-09.KCfDrcfQ.png" width="1920" height="899"/>
    <media:content medium="image" url="https://david.gardiner.net.au/_astro/speedtest-09.KCfDrcfQ.png" width="1920" height="899"/>
  </entry>
  <entry>
    <id>https://david.gardiner.net.au/2021/07/synology-unifi</id>
    <updated>2021-07-26T09:00:00.000+09:30</updated>
    <title>UniFi Controller on a Synology</title>
    <link href="https://david.gardiner.net.au/2021/07/synology-unifi" rel="alternate" type="text/html" title="UniFi Controller on a Synology"/>
    <category term="Docker"/>
    <category term="Hardware"/>
    <category term="Networking"/>
    <category term="Synology"/>
    <published>2021-07-26T09:00:00.000+09:30</published>
    <summary type="html">I&apos;ve been using Ubiquiti&apos;s UniFi wireless access points for a few years around home.</summary>
    <content type="html">
&lt;p&gt;I&apos;ve been using Ubiquiti&apos;s UniFi wireless access points for a few years around home. Until now I&apos;ve only used the UniFi Controller application on an as-need basis (when setting the configuration or installing updates). But having the &lt;a href=&quot;/2021/04/synology-DS1621xs-review&quot;&gt;Synology DS1621xs&lt;/a&gt; on hand gives me an opportunity to try out its Docker support and in particular being able to run UniFi Controller continuously in a Docker container on the Synology.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-00.CHXYgEjY_10gqAW.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I say &apos;UniFi Controller&apos; but I gather that as of version 6.2 they&apos;ve renamed it to &apos;UniFi Network Application&apos;. Same software, just an updated name.&lt;/p&gt;
&lt;h2&gt;Installing Docker on the Synology&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the &lt;strong&gt;Package Center&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;All Packages&lt;/strong&gt; and scroll down to the &lt;strong&gt;Third-party&lt;/strong&gt; section&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &apos;Docker&apos; package click &lt;strong&gt;Install&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-01.CpUzPeBQ_p1mMH.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When installation has completed, the button changes to &lt;strong&gt;Open&lt;/strong&gt;. Click on it to open the Docker UI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The first time you open Docker a welcome screen message is displayed. Select &lt;strong&gt;Don&apos;t show this again&lt;/strong&gt; and close the message.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker is now running on your Synology&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;  &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-02.NW1uzbxA_Z9HHun.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Installing UniFi Controller&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;Registry&lt;/strong&gt; page.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-03.CH_lqIiL_ZEROuB.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the search bar enter &lt;code&gt;unifi&lt;/code&gt; and click &lt;strong&gt;Search&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Double-click on the &lt;strong&gt;jacobalberty/unifi&lt;/strong&gt; image.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-04.dKbQ9Krz_1n83iP.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You now need to select a tag. &lt;a href=&quot;https://github.com/jacobalberty/unifi-docker#supported-docker-hub-tags-and-respective-dockerfile-links&quot;&gt;Review the options&lt;/a&gt; to understand what the different tag values mean. (Choose &lt;strong&gt;latest&lt;/strong&gt; to go with the latest stable version).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The image is now being downloaded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the &lt;strong&gt;Image&lt;/strong&gt; page.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the download has completed, the &lt;strong&gt;Launch&lt;/strong&gt; button will be enabled. Click on &lt;strong&gt;Launch&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If desired, you can customise the &lt;strong&gt;Container Name&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-05.ByFNLiBy_Z8o0Nz.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Enable resource limitation&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;strong&gt;Advanced Settings&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Enable auto-restart&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-06.Cd-vTBrZ_ttwwM.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Volume&lt;/strong&gt; tab and click &lt;strong&gt;Add Folder&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;docker&lt;/strong&gt; folder and then click on &lt;strong&gt;Create Folder&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter &lt;code&gt;unifi&lt;/code&gt; and click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Select&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Mount path&lt;/strong&gt; column, enter &lt;code&gt;/unifi&lt;/code&gt;. (See &lt;a href=&quot;https://github.com/jacobalberty/unifi-docker#volumes&quot;&gt;Volumes&lt;/a&gt; for volumes used by this image).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-07.f-7PYZUD_Z2krGaI.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Network&lt;/strong&gt; tab and select &lt;strong&gt;use the same network as Docker Host&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-08.DI60RDCk_Zg4jr9.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/jacobalberty/unifi-docker#run-as-non-root-user&quot;&gt;It is recommended&lt;/a&gt; to not run this image as root. Go to the &lt;strong&gt;Environment&lt;/strong&gt; tab.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the value of &lt;strong&gt;RUNAS_UID0&lt;/strong&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As we will be binding to a port &amp;gt; 1024, we can also set the value of &lt;strong&gt;BIND_PRIV&lt;/strong&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-09.DnRGKulk_Z14lx6w.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Apply&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review the Summary details, then if they look correct click &lt;strong&gt;Apply&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-10.B_eox-5f_Z25mNoI.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;Container&lt;/strong&gt; page.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can see the UniFi image is now running in a container.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-11.iTqgaAo0_Z21EPfP.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you have the Synology Firewall enabled, you will need to allow access to the application, the port needs to be opened in the Synology Firewall. In my case because I hadn&apos;t exposed the Synology directly to the Internet, the firewall was disabled. I figured it was probably a good idea to enable the firewall.&lt;/p&gt;
&lt;p&gt;From the &lt;a href=&quot;https://github.com/jacobalberty/unifi-docker#expose&quot;&gt;Ports&lt;/a&gt; documentation there are a number of TCP and UDP ports to select.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to the Synology main menu and select &lt;strong&gt;Control Panel&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Advanced Mode&lt;/strong&gt; and click on &lt;strong&gt;Security&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Firewall&lt;/strong&gt; tab, select the &lt;strong&gt;custom&lt;/strong&gt; profile and click &lt;strong&gt;Edit Rules&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-12.9TvHJgqO_2sdqG0.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt; and under &lt;strong&gt;Ports&lt;/strong&gt; select &lt;strong&gt;Custom&lt;/strong&gt; and then click on &lt;strong&gt;Custom&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure &lt;strong&gt;Protocol&lt;/strong&gt; is set to &lt;strong&gt;TCP&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Ports&lt;/strong&gt; field enter &lt;code&gt;8080,8443,8843,8880,6789&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-13.BrGixDIJ_Z27VNQK.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;OK&lt;/strong&gt;, and &lt;strong&gt;OK&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt; and under &lt;strong&gt;Ports&lt;/strong&gt; select &lt;strong&gt;Custom&lt;/strong&gt; and then click on &lt;strong&gt;Custom&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Protocol&lt;/strong&gt; select &lt;strong&gt;UDP&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;strong&gt;Ports&lt;/strong&gt; field enter &lt;code&gt;3478&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-14.DdtJUzXv_29Sv1v.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;OK&lt;/strong&gt;, and &lt;strong&gt;OK&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to save the firewall profile changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it is highlighted, click &lt;strong&gt;Apply&lt;/strong&gt; to save firewall changes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Accessing UniFi Controller&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Navigate to &lt;a href=&quot;https://your-synology-box:8443/&quot;&gt;https://your-synology-box:8443/&lt;/a&gt; (replacing &lt;code&gt;your-synology-box&lt;/code&gt; with the DNS name of your Synology).&lt;/li&gt;
&lt;li&gt;As the UniFi Controller comes with a self-signed TLS certificate you&apos;ll need to tell your browser to trust the certificate.&lt;/li&gt;
&lt;li&gt;After this you should see the UniFi start-up wizard. If this is the first time you&apos;ve used the software, proceed through the wizard following the steps. Alternatively (like me) if you&apos;re migrating from another installation you can click the &lt;strong&gt;or restore setup from backup&lt;/strong&gt; to upload a back from the old system.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/synology-unifi-15.CAqTxZSC_1ClDl7.webp&quot; alt=&quot;UniFi Controller screenshot&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And with that you should be good to go!&lt;/p&gt;
&lt;h2&gt;Final thoughts&lt;/h2&gt;
&lt;p&gt;The ability to run Docker containers on a Synology is a great advantage. The UI is easy to use but flexible enough to allow you to run useful Docker images. Do check out my review of the &lt;a href=&quot;/2021/04/synology-DS1621xs-review&quot;&gt;DS1621xs&lt;/a&gt;, and check it out on &lt;a href=&quot;https://www.amazon.com/Synology-Bay-DiskStation-DS1621xs-Diskless/dp/B08HYRYLPS?dchild=1&amp;amp;keywords=DS1621xs%2B&amp;amp;qid=1616751434&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=flcdrg0e-20&amp;amp;linkId=160b2c8e5878fc4d957cbfde6027cd35&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;amazon.com&lt;/a&gt; or &lt;a href=&quot;https://www.amazon.com.au/Synology-DiskStation-DS1621xs-Diskless-1x10GbE/dp/B08HM5YZMJ?dchild=1&amp;amp;keywords=DS1621xs%2B&amp;amp;qid=1616744805&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=flcdrg07-22&amp;amp;linkId=d1b97c8358787908de58e1700f665d78&amp;amp;language=en_AU&amp;amp;ref_=as_li_ss_tl&quot;&gt;amazon.com.au&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Acknowledgements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There are quite a few different Docker images for running UniFi. Thanks to &lt;a href=&quot;https://blog.siliconvalve.com/&quot;&gt;Simon Waight&lt;/a&gt; for the suggestion of &lt;a href=&quot;https://github.com/jacobalberty/unifi-docker&quot;&gt;https://github.com/jacobalberty/unifi-docker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lazyadmin.nl/home-network/unifi-controller-on-a-synology-nas-with-docker/&quot;&gt;Ruud&apos;s instructions&lt;/a&gt; which formed the basis of the steps I followed here.&lt;/li&gt;
&lt;/ul&gt;
</content>
    <media:thumbnail url="https://david.gardiner.net.au/_astro/synology-unifi-00.CHXYgEjY.jpg" width="365" height="252"/>
    <media:content medium="image" url="https://david.gardiner.net.au/_astro/synology-unifi-00.CHXYgEjY.jpg" width="365" height="252"/>
  </entry>
  <entry>
    <id>https://david.gardiner.net.au/2020/05/docker-perf-on-azure-pipelines</id>
    <updated>2020-05-23T17:30:00.000+09:30</updated>
    <title>Docker performance on Azure Pipelines agents</title>
    <link href="https://david.gardiner.net.au/2020/05/docker-perf-on-azure-pipelines" rel="alternate" type="text/html" title="Docker performance on Azure Pipelines agents"/>
    <category term="Docker"/>
    <category term="Azure Pipelines"/>
    <published>2020-05-23T17:30:00.000+09:30</published>
    <summary type="html">I&apos;ve noticed some interesting variations in build times on Azure Pipelines related to using Docker to build and/or run containers.</summary>
    <content type="html">
&lt;p&gt;I&apos;ve noticed some interesting variations in build times on Azure Pipelines related to using Docker to build and/or run containers. I tracked down the issue to excessive time downloading docker images, so I started investigating whether there&apos;s ways to cache or optimise the &lt;code&gt;docker pull&lt;/code&gt; steps.&lt;/p&gt;
&lt;p&gt;So what to do?&lt;/p&gt;
&lt;h2&gt;Self-hosted agents&lt;/h2&gt;
&lt;p&gt;First off, if you can run your own build agent you&apos;re probably not going to see these problems. Having a dedicated agent means that Docker caches all images locally and can reuse them for subsequent build jobs. That&apos;s issue with &lt;a href=&quot;https://learn.microsoft.com/azure/devops/pipelines/agents/hosted?view=azure-devops&amp;amp;tabs=yaml&quot;&gt;Microsoft-hosted agents&lt;/a&gt; - you get a brand new agent for each job - there&apos;s no possibility to persist any changes, so the value of Docker&apos;s image caching is reduced.&lt;/p&gt;
&lt;h2&gt;Cache Task&lt;/h2&gt;
&lt;p&gt;First off I did some research into whether the &lt;a href=&quot;https://learn.microsoft.com/azure/devops/pipelines/release/caching?view=azure-devops&quot;&gt;Cache Task&lt;/a&gt; could be used as a way to more efficiently restore the Docker image cache. I think the answer is probably &apos;no&apos;. I&apos;ve started using this task for another build involving NuGet packages, and in that case it makes the &lt;code&gt;dotnet restore&lt;/code&gt; step much faster, but I think the problem with Docker is the files are stored in various places, so trying to cache &lt;code&gt;C:\ProgramData\Docker\image\windowsfilter\layerdb\sha256&lt;/code&gt; and/or &lt;code&gt;C:\ProgramData\Docker\windowsfilter&lt;/code&gt; didn&apos;t seem to have any effect.&lt;/p&gt;
&lt;h2&gt;Docker Save/Load&lt;/h2&gt;
&lt;p&gt;There&apos;s a &lt;a href=&quot;https://github.com/microsoft/azure-pipelines-tasks/issues/11034&quot;&gt;GitHub issue&lt;/a&gt; with some discussion about using &lt;code&gt;docker save&lt;/code&gt;/&lt;code&gt;load&lt;/code&gt; and I can confirm the comments on the issue that this did not make things faster (in fact it made things slower).&lt;/p&gt;
&lt;p&gt;Here&apos;s an example - a pipeline that&apos;s saving 4.8-windowsservercore-ltsc2019 in the cache.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pool:
  vmImage: &apos;windows-latest&apos;

variables:
  dockerCache: $(Build.ArtifactStagingDirectory)\.dockercache

steps:

- script: docker images --digests
  displayName: Docker images

- task: Cache@2
  inputs:
    key: &apos;nuget | &quot;$(Agent.OS)&quot; | azure-pipelines-docker-cache.yml&apos;
    path: &apos;$(dockerCache)&apos;
    cacheHitVar: DOCKER_CACHE_HIT
  displayName: 1. Cache Task

- script: |
    if exist $(dockerCache)\4.8-windowsservercore-ltsc2019.tar docker load -i $(dockerCache)/4.8-windowsservercore-ltsc2019.tar
  displayName: 2. Docker Load

- script: docker pull mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
  displayName: 3. Docker Pull

- script: |
    if not exist $(dockerCache) mkdir $(dockerCache)
    docker image save -o $(dockerCache)/4.8-windowsservercore-ltsc2019.tar mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
  condition: ne(variables[&apos;DOCKER_CACHE_HIT&apos;], &apos;true&apos;)
  displayName: 4. Docker Save
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Build&lt;/th&gt;
&lt;th&gt;1. Cache Task&lt;/th&gt;
&lt;th&gt;2. Docker Load&lt;/th&gt;
&lt;th&gt;3. Docker Pull&lt;/th&gt;
&lt;th&gt;4. Docker Save&lt;/th&gt;
&lt;th&gt;5. Cache Save&lt;/th&gt;
&lt;th&gt;Job time (total)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Build 1 (cache miss)&lt;/td&gt;
&lt;td&gt;00:00:03&lt;/td&gt;
&lt;td&gt;00:00:01&lt;/td&gt;
&lt;td&gt;00:08:04&lt;/td&gt;
&lt;td&gt;00:17:06&lt;/td&gt;
&lt;td&gt;00:06:09&lt;/td&gt;
&lt;td&gt;00:31:50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build 2 (cache hit)&lt;/td&gt;
&lt;td&gt;00:05:45&lt;/td&gt;
&lt;td&gt;00:10:56&lt;/td&gt;
&lt;td&gt;00:00:03&lt;/td&gt;
&lt;td&gt;00:00:01&lt;/td&gt;
&lt;td&gt;00:00:03&lt;/td&gt;
&lt;td&gt;00:17:15&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;So yes, the second build was faster, but both of these are way slower than a build that had no caching at all (cf just the first &lt;code&gt;docker pull&lt;/code&gt; at 00:08:04). So that&apos;s no help.&lt;/p&gt;
&lt;h2&gt;Buildctl&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/microsoft/azure-pipelines-tasks/issues/11034#issuecomment-534670515&quot;&gt;issue also mentions using &lt;code&gt;buildctl&lt;/code&gt;&lt;/a&gt;, which is part of BuildKit. The trouble is I&apos;m working with Windows Containers and BuildKit currently supported with those. If you&apos;re working with Linux containers, this does sound promising.&lt;/p&gt;
&lt;h2&gt;Existing images on the agent&lt;/h2&gt;
&lt;p&gt;It occurred to me that shouldn&apos;t Docker be making use of some existing images that are shipped on the hosted agent. The software and tools pre-installed on each agent is documented. For example, the &lt;a href=&quot;https://web.archive.org/web/20200529063927/https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md&quot;&gt;Windows 2019 agent&lt;/a&gt;. This is not a static list, the agents will be updated over time as patches and updates are issued for both the OS and applications.&lt;/p&gt;
&lt;p&gt;You can see the list of pre-installed images listed, or just to confirm, you can run &lt;code&gt;docker images --digests&lt;/code&gt; in a pipeline step to confirm. Here&apos;s the output I got which matches the documentation.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;REPOSITORY                                   TAG                              DIGEST                                                                    IMAGE ID            CREATED             SIZE
mcr.microsoft.com/dotnet/framework/aspnet    4.8-windowsservercore-ltsc2019   sha256:dbf97206264133cdef6b49b06fa5d4028482845547c2858a086b5ce5c4513f00   8280f73a9be1        9 days ago          6.87GB
mcr.microsoft.com/dotnet/framework/runtime   4.8-windowsservercore-ltsc2019   sha256:bf47599181ae3877ec680428a99f76d43ffb26251155a6f0b0b76f4e70304c26   bcd511658148        9 days ago          6.51GB
mcr.microsoft.com/windows/servercore         ltsc2019                         sha256:2629881183feda906459163cb58fbdbc001bea76a92b2dc4695c8e5b14f747ae   561b89eac394        2 weeks ago         3.7GB
mcr.microsoft.com/windows/nanoserver         1809                             sha256:8e6807c213b52405fec8a861e0b766055ba9d4f941267adf49ee67526755b63a   9e7d556b2b51        2 weeks ago         251MB
microsoft/aspnetcore-build                   1.0-2.0                          sha256:9ecc7c5a8a7a11dca5f08c860165646cb30d084606360a3a72b9cbe447241c0c   5d8be0910d37        21 months ago       3.99GB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Out of curiosity, I added a &lt;code&gt;docker pull mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019&lt;/code&gt; step to the pipeline. Now that should be super-quick as you can see that image is already cached. But it wasn&apos;t! It too almost 8 minutes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
========================== Starting Command Output ===========================
&quot;C:\windows\system32\cmd.exe&quot; /D /E:ON /V:OFF /S /C &quot;CALL &quot;D:\a\_temp\d190c5d8-262b-4a70-9c04-216b9ac2b165.cmd&quot;&quot;
4.8-windowsservercore-ltsc2019: Pulling from dotnet/framework/aspnet
4612f6d0b889: Already exists
eed17b4baac2: Pulling fs layer
565c587c68c2: Pulling fs layer
c732b140f2ad: Pulling fs layer
84ae672f9921: Pulling fs layer
cd04865d4563: Pulling fs layer
7c75100d3a4d: Pulling fs layer
bea74093ac0e: Pulling fs layer
6353217bf85b: Pulling fs layer
ca397bdd5ee0: Pulling fs layer
ef8702482a58: Pulling fs layer
84ae672f9921: Waiting
cd04865d4563: Waiting
7c75100d3a4d: Waiting
bea74093ac0e: Waiting
6353217bf85b: Waiting
ca397bdd5ee0: Waiting
ef8702482a58: Waiting
c732b140f2ad: Verifying Checksum
c732b140f2ad: Download complete
565c587c68c2: Verifying Checksum
565c587c68c2: Download complete
eed17b4baac2: Verifying Checksum
eed17b4baac2: Download complete
cd04865d4563: Verifying Checksum
cd04865d4563: Download complete
7c75100d3a4d: Verifying Checksum
7c75100d3a4d: Download complete
6353217bf85b: Verifying Checksum
6353217bf85b: Download complete
ca397bdd5ee0: Verifying Checksum
ca397bdd5ee0: Download complete
84ae672f9921: Verifying Checksum
84ae672f9921: Download complete
ef8702482a58: Verifying Checksum
ef8702482a58: Download complete
bea74093ac0e: Verifying Checksum
bea74093ac0e: Download complete
eed17b4baac2: Pull complete
565c587c68c2: Pull complete
c732b140f2ad: Pull complete
84ae672f9921: Pull complete
cd04865d4563: Pull complete
7c75100d3a4d: Pull complete
bea74093ac0e: Pull complete
6353217bf85b: Pull complete
ca397bdd5ee0: Pull complete
ef8702482a58: Pull complete
Digest: sha256:3579480a92f0795c37d6e551139b431eb7cafe798d257c7ce279e10adbd0cb6d
Status: Downloaded newer image for mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why is it pulling all those layers? When does &lt;code&gt;mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019&lt;/code&gt; != &lt;code&gt;mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;I then took a look at the Docker Hub page for ASP.NET. It lists the same tag, though interestingly the &apos;last modified&apos; date was 19th of May (4 days ago). Compare that with the &lt;code&gt;docker images&lt;/code&gt; list above - it says &apos;9 days ago&apos; - and on closer examination the sha256 values are different too!&lt;/p&gt;
&lt;p&gt;So I&apos;m pretty sure that&apos;s the problem - there&apos;s a lag between when a new image is published on Docker Hub and when that image will be included in the current hosted agent VM.&lt;/p&gt;
&lt;h2&gt;Image architecture&lt;/h2&gt;
&lt;p&gt;One other thing to watch out for. Notice that the one of the images listed on the agent is mcr.microsoft.com/windows/servercore:ltsc2019? There&apos;s different &apos;architecture&apos; options for container images. For Windows Containers, these are usually either &apos;multiarch&apos; or &apos;amd64&apos;. For example see both listed for &lt;a href=&quot;https://hub.docker.com/r/microsoft/windows-servercore&quot;&gt;Windows Server Core&lt;/a&gt;. The trap is that these are two different images. If you specify the &lt;code&gt;ltsc2019-amd64&lt;/code&gt; tag, that won&apos;t match the image on the agent.&lt;/p&gt;
&lt;h2&gt;Possible solutions&lt;/h2&gt;
&lt;p&gt;So that seems like a reasonable hypothesis. Because we&apos;re either explicitly doing a &lt;code&gt;docker pull&lt;/code&gt; or we&apos;re depending on images that were built with a different version of the base image, we&apos;re experiencing a cache miss and paying the penalty by needing to download an entirely new image.&lt;/p&gt;
&lt;p&gt;I think the problem can be managed by ensuring that images are built against the current base images on the agent. If you&apos;re building images in different pipelines and then storing those in a private registry (Azure Container Registry for example), then you&apos;re probably going to need to refresh those as soon as the agent images are updated.&lt;/p&gt;
&lt;p&gt;Following the &lt;a href=&quot;https://github.com/actions/runner-images/releases&quot;&gt;releases&lt;/a&gt; in the GitHub Actions virtual-environments repo appears to be the easiest way to know when the agent software is changing. Yes, GitHub Actions and Azure Pipelines share the same agent configurations.&lt;/p&gt;
&lt;p&gt;If you really need to fix on a version, don&apos;t just rely on the tags - you&apos;re best bet then is to reference the sha256. That way there&apos;s no ambiguity. But be aware you&apos;ll more than likely end up referring to an image that isn&apos;t cached. In that case if build time matters, then using a self-hosted agent is probably the best strategy.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>https://david.gardiner.net.au/2020/05/json-env-converter</id>
    <updated>2020-05-11T08:00:00.000+09:30</updated>
    <title>JSON to Environment Converter</title>
    <link href="https://david.gardiner.net.au/2020/05/json-env-converter" rel="alternate" type="text/html" title="JSON to Environment Converter"/>
    <category term=".NET"/>
    <category term="Docker"/>
    <published>2020-05-11T08:00:00.000+09:30</published>
    <summary type="html">I made a thing!</summary>
    <content type="html">&lt;p&gt;I made a thing!&lt;/p&gt;
&lt;p&gt;I needed to translate some JSON configuration (like the &lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#environment-variables&quot;&gt;&lt;code&gt;appsettings.json&lt;/code&gt; file used by ASP.NET Core&lt;/a&gt;) into equivalent environment variables (so that they could be set in a &lt;a href=&quot;https://docs.docker.com/engine/reference/builder/#env&quot;&gt;Dockerfile&lt;/a&gt;). Rather than try and figure it out, I created a simple web tool to do the conversion for me.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://david.gardiner.net.au/_astro/jsontoenvironmentconverter-screenshot.CvzU0hKb_Z1PiS1Y.webp&quot; alt=&quot;Website screenshot&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Paste your JSON into the first text field&lt;/li&gt;
&lt;li&gt;Select the formatting options&lt;ol&gt;
&lt;li&gt;Dockerfile-style or Yaml (suitable for &lt;code&gt;docker-compose.yml&lt;/code&gt; or &lt;code&gt;azure-pipelines.yml&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Whether to include entries with a key but no value&lt;/li&gt;
&lt;li&gt;Use colons or underscores as separators&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Convert&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Review and/or copy the text that appears in the second text field.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can find it at &lt;a href=&quot;https://jsontoenvironmentconverter.azurewebsites.net/&quot;&gt;https://jsontoenvironmentconverter.azurewebsites.net/&lt;/a&gt;, and the source code is at &lt;a href=&quot;https://github.com/flcdrg/JsonToEnvironmentConverter&quot;&gt;https://github.com/flcdrg/JsonToEnvironmentConverter&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>https://david.gardiner.net.au/2019/11/docker-windows-linux</id>
    <updated>2019-11-16T14:45:00.000+10:30</updated>
    <title>Trying Docker for Windows and Linux</title>
    <link href="https://david.gardiner.net.au/2019/11/docker-windows-linux" rel="alternate" type="text/html" title="Trying Docker for Windows and Linux"/>
    <category term="Docker"/>
    <category term="Windows"/>
    <published>2019-11-16T14:45:00.000+10:30</published>
    <summary type="html">I&apos;ve been spending a bit of time trying out Docker over the past few days, with the goal of making builds more reliable and repeatable.</summary>
    <content type="html">&lt;p&gt;I&apos;ve been spending a bit of time trying out Docker over the past few days, with the goal of making builds more reliable and repeatable.&lt;/p&gt;
&lt;p&gt;Docker Desktop for Windows has the ability to run in Windows mode and Linux mode. Usually that means you can only run containers of one OS at at a time.&lt;/p&gt;
&lt;p&gt;However, if you run &lt;a href=&quot;https://devblogs.microsoft.com/premier-developer/running-docker-windows-and-linux-containers-simultaneously/&quot;&gt;configure Docker to enable &apos;Experimental&apos; mode&lt;/a&gt;, then you can actually run both platforms simultaneously.&lt;/p&gt;
&lt;p&gt;Interestingly, when you&apos;re in this mode and you set &apos;Windows&apos; as the default container platform, you don&apos;t see an extra virtual machine listed in HyperV.&lt;/p&gt;
&lt;p&gt;Here&apos;s Docker running with Linux containers:
&lt;img src=&quot;https://david.gardiner.net.au/_astro/hyperv-docker-vm.5aqE4uyb_1jHu5S.webp&quot; alt=&quot;Hyper-V Manager showing Docker virtual machine&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And here&apos;s Docker with Windows containers:
&lt;img src=&quot;https://david.gardiner.net.au/_astro/hyperv-docker-lcow.Bwla9J1c_2pbYIJ.webp&quot; alt=&quot;Hyper-V Manager showing Docker machine not running&quot; /&gt;
Notice the VM may be there, but it is not running, even when I&apos;m actually building a Linux container when that screenshot was taken.&lt;/p&gt;
&lt;p&gt;So with experimental mode on, how can Docker be also running Linux containers in Windows mode?&lt;/p&gt;
&lt;p&gt;Currently it uses something called LCOW - Linux Containers on Windows.&lt;/p&gt;
&lt;p&gt;I know Docker also has &lt;a href=&quot;https://docs.docker.com/desktop/features/wsl/&quot;&gt;preview support&lt;/a&gt; for &lt;a href=&quot;https://learn.microsoft.com/windows/wsl/compare-versions&quot;&gt;WSL2&lt;/a&gt;. I think the plan is that once that ships (presumably with Windows 10 20H1) then Docker will be able to leverage that for Linux execution.&lt;/p&gt;
&lt;p&gt;So in theory, if you need to spin up Linux and Windows containers, then this is the technology that will make that happen.&lt;/p&gt;
&lt;p&gt;There&apos;s still a few rough edges - probably why it&apos;s all behind &apos;preview&apos; or &apos;experimental&apos; flags.&lt;/p&gt;
&lt;p&gt;I hit one issue where trying to spin up a Node Linux container which has a step to run &lt;code&gt;yarn&lt;/code&gt; resulted in some weird internal error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Step 14/22 : RUN yarn
---&amp;gt; Running in eb14f055a9aa
container eb14f055a9aaa23db5f35493feec9009b775c6688e3c488b26c6880517bdd9f1 encountered an error during CreateProcess: failure in a Windows system call: Unspecified error (0x80004005)
[Event Detail: failed to run runc create/exec call for container eb14f055a9aaa23db5f35493feec9009b775c6688e3c488b26c6880517bdd9f1: exit status 1 Stack Trace:
github.com/Microsoft/opengcs/service/gcs/runtime/runc.(*container).startProcess
/go/src/github.com/Microsoft/opengcs/service/gcs/runtime/runc/runc.go:580
github.com/Microsoft/opengcs/service/gcs/runtime/runc.(*runcRuntime).runCreateCommand
/go/src/github.com/Microsoft/opengcs/service/gcs/runtime/runc/runc.go:471
github.com/Microsoft/opengcs/service/gcs/runtime/runc.(*runcRuntime).CreateContainer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No idea what&apos;s going on there other than maybe I&apos;ve managed to hit some issue where some API isn&apos;t implemented?&lt;/p&gt;
&lt;p&gt;It&apos;s strange, as a different container (based on a different Linux distribution) didn&apos;t have that problem.&lt;/p&gt;
&lt;p&gt;So it has potential, but it&apos;s obviously a work in progress.&lt;/p&gt;
</content>
  </entry>
</feed>
