<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>docker on Marcin Zabłocki blog</title>
    <link>https://zablo.net/tags/docker/</link>
    <description>Recent content in docker on Marcin Zabłocki blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <managingEditor>Marcin Zabłocki</managingEditor>
    <webMaster>Marcin Zabłocki</webMaster>
    <copyright>2026 Marcin Zabłocki</copyright>
    <lastBuildDate>Sat, 03 Jan 2026 15:52:00 +0000</lastBuildDate>
    <atom:link href="https://zablo.net/tags/docker/index.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>How to connect to Home Assistant from anywhere using NordVPN meshnet</title>
      <link>https://zablo.net/blog/post/home-assistant-nordvpn-meshnet-remote-access/</link>
      <pubDate>Sat, 03 Jan 2026 15:52:00 +0000</pubDate>
      <author>Marcin Zabłocki</author>
      <guid>https://zablo.net/blog/post/home-assistant-nordvpn-meshnet-remote-access/</guid>
      <category>home-assistant</category>
      <category>nordvpn</category>
      <category>meshnet</category>
      <category>docker</category>
      <category>linux</category>
      <category>ufw</category>
      <category>networking</category>
      <description>&lt;p&gt;So you have your Home Assistant working just fine, but you can only access it on your mobile app while you&amp;rsquo;re at home. I had the same problem, but I wanted to be able to play with my LED lights and power switches remotely, without having to pay for Home Assistant Cloud. I already had NordVPN at hand and I knew it had Meshnet, so it was a great opportunity to use it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-nordvpn-meshnet&#34;&gt;What is NordVPN Meshnet?&lt;/h2&gt;&#xA;&lt;p&gt;Meshnet is NordVPN&amp;rsquo;s peer-to-peer networking feature that lets you connect multiple devices into a private virtual network. Unlike traditional VPN services that route traffic through a central server, Meshnet creates direct connections between your devices, giving you lower latency and the ability to access services (like Home Assistant) on any device in your mesh without exposing them to the public internet.&lt;/p&gt;&#xA;&lt;p&gt;The best part? Meshnet is completely free. You don&amp;rsquo;t need a special subscription beyond the standard NordVPN subscription, and it works on Windows, macOS, Linux, iOS, and Android. You can add up to 60 devices to a single Meshnet, which is more than enough for most home setups.&lt;/p&gt;&#xA;&lt;p&gt;Each device in your Meshnet gets assigned a unique device name (like &lt;code&gt;homeassistant-linux&lt;/code&gt; in my case, which is the actual NordVPN Meshnet name of my Home Assistant server) and a private IP address in the &lt;code&gt;100.64.0.0/10&lt;/code&gt; range. This makes it easy to remember and access your services by name, similar to how you&amp;rsquo;d use DNS.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-it-works-in-practice&#34;&gt;How it works in practice&lt;/h2&gt;&#xA;&lt;p&gt;When you enable Meshnet on both your Home Assistant server and your client device, they can communicate directly over an encrypted tunnel. Port forwarding, dynamic DNS, and exposing your server to the internet are all unnecessary. It&amp;rsquo;s just a private network between your devices.&lt;/p&gt;&#xA;&lt;p&gt;The problem I ran into (and you probably will too) is that Meshnet blocks access to Docker containers and local networks by default. This guide shows you exactly how to fix it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;quick-solution-summary&#34;&gt;Quick solution summary&lt;/h2&gt;&#xA;&lt;p&gt;If you just want the steps without the explanation, here&amp;rsquo;s what you need to do:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Enable UFW firewall on your Linux server&lt;/li&gt;&#xA;&lt;li&gt;Add a rule: &lt;code&gt;sudo ufw allow in on nordlynx to any port 8123 proto tcp&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Grant Meshnet access: &lt;code&gt;sudo nordvpn meshnet peer local allow &amp;lt;your-device-name&amp;gt;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Test with: &lt;code&gt;curl http://homeassistant-linux:8123&lt;/code&gt; (replace with your actual Meshnet device name)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The key insight: Meshnet treats Docker networks as &amp;ldquo;local&amp;rdquo; and blocks access by default. That&amp;rsquo;s why SSH works but Home Assistant doesn&amp;rsquo;t. The &lt;code&gt;peer local allow&lt;/code&gt; command fixes this.&lt;/p&gt;&#xA;&lt;h2 id=&#34;meshnet-configuration-on-ios&#34;&gt;Meshnet configuration on iOS&lt;/h2&gt;&#xA;&lt;p&gt;Once everything is set up correctly, you will be able to access Home Assistant remotely, e.g. when you&amp;rsquo;re out of home on iOS:&lt;/p&gt;&#xA;&lt;div class=&#34;mfp-play-wrapper&#34;&gt;&#xA;&lt;a class=&#34;video-hover mfp-gif&#34; href=&#34;https://zablo.net/resources/home-assistant-meshnet/home-assistant-nordvpn-meshnet.jpeg&#34; title=&#34;HomeAssistant on iOS connected via NordVPN meshnet&#34;&gt;&#xA;&lt;div class=&#34;text-center&#34;&gt;&#xA;&lt;img src=&#34;https://zablo.net/resources/home-assistant-meshnet/home-assistant-nordvpn-meshnet.jpeg&#34; alt=&#34;HomeAssistant on iOS connected via NordVPN meshnet&#34; title=&#34;HomeAssistant on iOS connected via NordVPN meshnet&#34; class=&#34;fig-25&#34;&gt;&#xA;&lt;div class=&#34;mfp-btn-play&#34;&gt;&lt;i class=&#34;fa fa-eye&#34;&gt;&lt;/i&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/a&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;&#xA;&lt;p&gt;Before you start, make sure you have:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A Linux server running Home Assistant (preferably in Docker with docker-compose)&lt;/li&gt;&#xA;&lt;li&gt;NordVPN installed on that Linux server&lt;/li&gt;&#xA;&lt;li&gt;NordVPN Meshnet enabled on both your Home Assistant server and your client device&lt;/li&gt;&#xA;&lt;li&gt;UFW firewall (Uncomplicated Firewall) installed on the Linux server&lt;/li&gt;&#xA;&lt;li&gt;At least one other device with NordVPN Meshnet enabled to test the connection&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re running Home Assistant in Docker, your setup should look something like this:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;yaml&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# ... other services skipped&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;homeassistant&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;homeassistant&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ghcr.io/home-assistant/home-assistant:stable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;./data/homeassistant:/config&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;ha_net&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ha_net&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bridge&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h2 id=&#34;diagnostic-steps-how-to-debug-home-assistant-not-working-on-meshnet&#34;&gt;Diagnostic steps: How to debug &amp;ldquo;Home Assistant not working on meshnet&amp;rdquo;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;check-if-home-assistant-is-actually-listening&#34;&gt;Check if Home Assistant is actually listening&lt;/h3&gt;&#xA;&lt;p&gt;From the Linux server itself, verify the port is exposed:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker ps &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep homeassistant&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;You should see &lt;code&gt;0.0.0.0:8123-&amp;gt;8123/tcp&lt;/code&gt; in the PORTS column. If you see something else, your Docker port mapping is misconfigured.&lt;/p&gt;&#xA;&lt;p&gt;Also check if something is listening:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ss -tulpn &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;or&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo netstat -tulpn &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;You should see a line with &lt;code&gt;LISTEN&lt;/code&gt; on &lt;code&gt;0.0.0.0:8123&lt;/code&gt; or &lt;code&gt;:::8123&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h3 id=&#34;verify-the-local-network-path-works-first&#34;&gt;Verify the local network path works first&lt;/h3&gt;&#xA;&lt;p&gt;From another device on your LAN, try accessing Home Assistant using the server&amp;rsquo;s local IP:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -v http://192.168.x.x:8123&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;or if you prefer a simple port check:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -vz 192.168.x.x &lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;You should get an HTTP response or &amp;ldquo;succeeded&amp;rdquo; message. If this fails, your Docker setup or local network is broken. Fix this before moving on.&lt;/p&gt;&#xA;&lt;h3 id=&#34;test-the-meshnet-connection-itself&#34;&gt;Test the meshnet connection itself&lt;/h3&gt;&#xA;&lt;p&gt;From your client device that has Meshnet enabled, try to reach SSH first:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -vz &amp;lt;meshnet-device-name&amp;gt; &lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Replace &lt;code&gt;&amp;lt;meshnet-device-name&amp;gt;&lt;/code&gt; with the device name from Meshnet (like the &lt;code&gt;homeassistant-linux&lt;/code&gt; name in your Meshnet settings). If SSH works, Meshnet itself is working.&lt;/p&gt;&#xA;&lt;p&gt;Now try Home Assistant:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -vz &amp;lt;meshnet-device-name&amp;gt; &lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;If SSH succeeds but this fails, you&amp;rsquo;ve found the exact problem: Meshnet is blocking traffic to port 8123 specifically.&lt;/p&gt;&#xA;&lt;h3 id=&#34;understand-why-ssh-works-but-home-assistant-doesnt&#34;&gt;Understand why SSH works but Home Assistant doesn&amp;rsquo;t&lt;/h3&gt;&#xA;&lt;p&gt;SSH works because it binds to the host&amp;rsquo;s &lt;code&gt;nordlynx&lt;/code&gt; interface directly. Home Assistant runs inside a Docker container on a bridge network (&lt;code&gt;172.17.0.0/16&lt;/code&gt; range by default). Meshnet treats Docker networks as &amp;ldquo;local networks&amp;rdquo; and blocks peer access to them unless you explicitly grant permission.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-complete-solution-step-by-step&#34;&gt;The complete solution: step-by-step&lt;/h2&gt;&#xA;&lt;h3 id=&#34;step-1-enable-ufw&#34;&gt;Step 1: enable UFW&lt;/h3&gt;&#xA;&lt;p&gt;First, enable UFW on your Linux server (if not already enabled):&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ufw enable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Check current status:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ufw status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h3 id=&#34;step-2-allow-meshnet-traffic-on-port-8123&#34;&gt;Step 2: allow meshnet traffic on port 8123&lt;/h3&gt;&#xA;&lt;p&gt;The key command that makes Home Assistant accessible over Meshnet:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ufw allow in on nordlynx to any port &lt;span class=&#34;m&#34;&gt;8123&lt;/span&gt; proto tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;This tells the firewall: &amp;ldquo;If traffic comes in via the NordVPN Meshnet interface (&lt;code&gt;nordlynx&lt;/code&gt;) on TCP port 8123, allow it.&amp;rdquo;&lt;/p&gt;&#xA;&lt;h3 id=&#34;step-3-reload-ufw&#34;&gt;Step 3: reload UFW&lt;/h3&gt;&#xA;&lt;p&gt;Apply the changes immediately:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ufw reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Verify the rule was added:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ufw status numbered&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;You should see something like:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;text&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[ N] 8123/tcp on nordlynx  ALLOW       Anywhere&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h3 id=&#34;step-4-grant-meshnet-local-network-access&#34;&gt;Step 4: grant meshnet local network access&lt;/h3&gt;&#xA;&lt;p&gt;This is the critical step that most guides miss. On your Linux server, run:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nordvpn meshnet peer list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;This will show all connected Meshnet peers. Find the device you&amp;rsquo;re connecting from (like the Meshnet device name shown in your NordVPN app).&lt;/p&gt;&#xA;&lt;p&gt;Then allow that device to access local networks:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nordvpn meshnet peer &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; allow &amp;lt;your-connecting-device-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;For example:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nordvpn meshnet peer &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; allow secret.cat-everest.nord&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;This is essential. Docker containers live on a bridge network, which Meshnet classifies as a &amp;ldquo;local network.&amp;rdquo; By default, Meshnet blocks peer access to local networks. This command explicitly grants permission.&lt;/p&gt;&#xA;&lt;p&gt;If you want to allow all Meshnet peers (less secure, but simpler), you can run:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nordvpn meshnet peer &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; allow all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h3 id=&#34;step-5-test-the-connection&#34;&gt;Step 5: test the connection&lt;/h3&gt;&#xA;&lt;p&gt;From your client device, try accessing Home Assistant using the Meshnet device name:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;bash&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://homeassistant-linux:8123&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Or open a browser and navigate to:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;text&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://homeassistant-linux:8123&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Replace &lt;code&gt;homeassistant-linux&lt;/code&gt; with whatever your actual Meshnet device name is.&lt;/p&gt;&#xA;&lt;p&gt;It should work now. If it doesn&amp;rsquo;t, double-check that:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The device name in &lt;code&gt;meshnet peer local allow&lt;/code&gt; matches exactly (case-sensitive)&lt;/li&gt;&#xA;&lt;li&gt;UFW is allowing traffic on the &lt;code&gt;nordlynx&lt;/code&gt; interface&lt;/li&gt;&#xA;&lt;li&gt;Home Assistant is still running and listening on 8123&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;thats-all&#34;&gt;That&amp;rsquo;s all&lt;/h2&gt;&#xA;&lt;p&gt;Good luck and happy Zigbee&amp;rsquo;ing 🐝&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Setup Apache Kafka in Docker on Windows</title>
      <link>https://zablo.net/blog/post/setup-apache-kafka-in-docker-on-windows/</link>
      <pubDate>Wed, 26 Apr 2017 22:00:00 +0000</pubDate>
      <author>Marcin Zabłocki</author>
      <guid>https://zablo.net/blog/post/setup-apache-kafka-in-docker-on-windows/</guid>
      <category>apache-kafka</category>
      <category>kafka</category>
      <category>docker</category>
      <category>windows</category>
      <description>&lt;p&gt;This post describes how to quickly setup development environment for &lt;strong&gt;Apache Kafka in Docker on Windows&lt;/strong&gt;. Apache Kafka is distributed streaming platform, which allows you to build reliable messaging channel between various systems. Its functionality supports publish/subscribe model, reliable message persistence, real-time stream processing and many more.&lt;/p&gt;&#xA;&lt;p&gt;When I start learning any new technology, I want to get my hands drity as fast as possible, without spending too much time on environment setup. I wrote this post, to help you get started with Apache Kafka as fast as possible. In this post I cover full setup on Windows, but since it uses Docker, the process should be easily applicable for Linux/Mac machines. Besides Apache Kafka itself, the setup involves lauching &lt;a href=&#39;https://github.com/yahoo/kafka-manager&#39; target=&#39;_blank&#39;&gt;&lt;strong&gt;Kafka-Manager UI&lt;/strong&gt;&lt;/a&gt; (developed by Yahoo), so you will be able to manage your Kafka instance with ease. Let&amp;rsquo;s get started!&lt;/p&gt;&#xA;&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;&#xA;&lt;p&gt;How to setup development environment for Apache Kafka + Kafka-Manager on Windows (using Docker).&lt;/p&gt;&#xA;&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Docker installed (I use version 17.03.1-ce on Windows)&lt;/li&gt;&#xA;&lt;li&gt;docker-compose installed (I use version 1.11.2)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;not-required&#34;&gt;Not required&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;knowledge of Docker&lt;/li&gt;&#xA;&lt;li&gt;knowledge of Apache Kafka&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;setup-apache-kafka-with-docker-compose&#34;&gt;Setup Apache Kafka with docker-compose&lt;/h2&gt;&#xA;&lt;p&gt;The setup will contain two containers:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Apache Kafka container (with Zookeeper built-in)&lt;/li&gt;&#xA;&lt;li&gt;Kafka-Manger container&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;In order to join those two containers, we will use docker-compose. Create &lt;code&gt;docker-compose.yml&lt;/code&gt; file and put the following content:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;html&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;version: &amp;#34;2&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;services:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  kafkaserver:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    image: &amp;#34;spotify/kafka:latest&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    container_name: kafka&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    hostname: kafkaserver&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    networks:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      - kafkanet&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ports:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      - 2181:2181&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      - 9092:9092&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    environment:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      ADVERTISED_HOST: kafkaserver&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      ADVERTISED_PORT: 9092&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  kafka_manager:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    image: &amp;#34;mzagar/kafka-manager-docker:1.3.3.4&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    container_name: kafkamanager&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    networks:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      - kafkanet&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ports:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      - 9000:9000&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    links:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      - kafkaserver&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    environment:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      ZK_HOSTS: &amp;#34;kafkaserver:2181&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;networks:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  kafkanet:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    driver: bridge&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;This docker-compose file decalres two mentioned containers. First one, &lt;em&gt;kafkaserver&lt;/em&gt; runs Kafka image developed by Spotify team (it includes Zookeeper). It exposes itself under &lt;strong&gt;kafkaserver hostname&lt;/strong&gt; in &lt;strong&gt;kafkanet network&lt;/strong&gt;. Two environment variables need to be set:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;ADVERTISED_HOST: kafkaserver&lt;/li&gt;&#xA;&lt;li&gt;ADVERTISED_PORT: 9092&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Those two describe to which hostname the Kafka server should respond from within the container.&lt;/p&gt;&#xA;&lt;p&gt;Second container, &lt;em&gt;kafka_manager&lt;/em&gt; runs newest (at the time of writing this post) kafka-manager tool. It needs to connect to the running Kafka server, that&amp;rsquo;s why there is the &lt;em&gt;link&lt;/em&gt; entry in docker-compose:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;html&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;links:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    - kafkaserver&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Environment variable &lt;code&gt;ZK_HOST&lt;/code&gt; also needs to be set in order to connect it to our Kafka server. We use &lt;strong&gt;hostname from kafkaserver container&lt;/strong&gt; in order to achieve that.&lt;/p&gt;&#xA;&lt;p&gt;Last thing in docker-compose file is network declaration, we use simple bridge networking there, so both containers can see one another.&lt;/p&gt;&#xA;&lt;h2 id=&#34;starting-the-environment&#34;&gt;Starting the environment&lt;/h2&gt;&#xA;&lt;p&gt;Once the &lt;code&gt;docker-compose.yml&lt;/code&gt; file is ready, open your favorite terminal in the folder which contains it and run:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;docker-compose&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;After running this command, you can check status of the containers by invoking:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;docker-compose&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ps&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;You should see output similar to this one:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/7f88b935-bc15-4ab2-b3b9-16bd9f7d42fa.png&#34; alt=&#34;Starting Apache Kafka in Docker on Windows&#34;&#xA;        title=&#34;Starting Apache Kafka in Docker on Windows&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;h2 id=&#34;creating-kafka-topic-through-kafka-manger-ui&#34;&gt;Creating Kafka topic through Kafka-Manger UI&lt;/h2&gt;&#xA;&lt;p&gt;Now when the Kafka server is up and running, we can create a &lt;strong&gt;Kafka Topic&lt;/strong&gt;. Topic in the Apache Kafka terminology is an isolated fragment to which multiple applications/systems can send messages and from which multiple consumers can receive (subscribe) data. One Kafka server can have any number of topics. I would say that &lt;strong&gt;Kafka Topic is equivalent of Table in SQL databases&lt;/strong&gt;. It&amp;rsquo;s a separate category, isolated from the rest of the system.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s launch Kafka-Manager, by opening&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;html&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:9000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;in the browser:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/ea504d22-7292-4006-83d2-3ce583403e9f.png&#34; alt=&#34;Kafka Manager on Windows in Docker&#34;&#xA;        title=&#34;Kafka Manager on Windows in Docker&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;h3 id=&#34;creating-kafka-cluster&#34;&gt;Creating Kafka Cluster&lt;/h3&gt;&#xA;&lt;p&gt;As you can see, there are no Clusters yet (since it&amp;rsquo;s still an empty environment). Cluster is where Kafka stores all the data pushed to the topics. Let&amp;rsquo;s create one by using the Cluster menu:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/c4f07067-f9c0-472a-ab5a-c5e9b376a21e.png&#34; alt=&#34;Create Kafka Cluster on Windows in Docker&#34;&#xA;        title=&#34;Create Kafka Cluster on Windows in Docker&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;p&gt;For the quick setup, you can enter only:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Cluster Name - the name of your choice&lt;/li&gt;&#xA;&lt;li&gt;Cluster Zookeeper Hosts - hostname of zookeeper (which is &lt;strong&gt;kafkaserver&lt;/strong&gt; as configured in docker-compose.yml file)&lt;/li&gt;&#xA;&lt;li&gt;Kafka Version 0.10.1.0 - which is the latest version at the time of writing this post&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;After entering those, click &lt;em&gt;Save&lt;/em&gt;. You should be redirected to the homepage and see the cluster there:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/47b21bba-750f-45ba-acaa-6779e4af9725.png&#34; alt=&#34;Kafka Cluster on Windows in Docker&#34;&#xA;        title=&#34;Kafka Cluster on Windows in Docker&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;h3 id=&#34;creating-kafka-topic&#34;&gt;Creating Kafka Topic&lt;/h3&gt;&#xA;&lt;p&gt;Now, when the cluster is present, navigate to it&amp;rsquo;s properties and open &lt;em&gt;Create Topic&lt;/em&gt; from the menu:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/47c821c8-a4c8-47a2-8a05-a2cd50af2c79.png&#34; alt=&#34;Create Kafka Topic on Windows in Docker&#34;&#xA;        title=&#34;Create Kafka Topic on Windows in Docker&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;p&gt;Entering only &lt;strong&gt;Topic&lt;/strong&gt; name is enough. Just hit Create from there. Done! Topic is created!&lt;/p&gt;&#xA;&lt;h2 id=&#34;testing-apache-kafka-on-windows&#34;&gt;Testing Apache Kafka on Windows&lt;/h2&gt;&#xA;&lt;p&gt;It is done, environment is up and running. Let&amp;rsquo;s test it. The quickest way to do this is to use Apache-provided scripts and just launching two of them - one for the producer and one for the subscriber.&#xA;In order to get those scripts, download the folowing file (it&amp;rsquo;s the actual Apache Kafka distribution, but we only need scripts from it):&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;html&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://www.apache.org/dyn/closer.cgi?path=/kafka/0.10.2.0/kafka_2.11-0.10.2.0.tgz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;and extract it. Then follow the path to the following folder:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;kafka_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tgz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kafka_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kafka_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;This folder contains bunch of script files:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;----&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;connect-distributed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;connect-standalone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;kafka-acls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;kafka-configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;kafka-console&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-consumer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;kafka-console&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-producer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(...)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;zookeeper-server&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;zookeeper-server&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;zookeeper-shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;We are interested in &lt;code&gt;kafka-console-consumer.bat&lt;/code&gt; and &lt;code&gt;kafka-console-producer.bat&lt;/code&gt;, but before launching them, we need one more thing. In order to connect to Kafka in Docker from the Windows host, we need to map Kafka container hostname to the localhost, by editing hosts file:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;C:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;System32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;drivers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;etc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hosts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Append&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;this&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;127.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;kafkaserver&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Ok, let&amp;rsquo;s launch &lt;strong&gt;Kafka Consumer&lt;/strong&gt; first:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;K:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kafka_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.\&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;kafka-console&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-consumer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-bootstrap-server&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;localhost&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;9092&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-topic&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;kafka_test&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;_topic&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;After launching this script, PowerShell window will hang, that&amp;rsquo;s a good thing. Open second terminal and launch &lt;strong&gt;Kafka Producer&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;PS &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kafka_2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;windows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.\&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;kafka-console&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-producer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;bat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-broker-list&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;localhost&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;9092&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-topic&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;kafka_test_topi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Type any message and hit ENTER, you should see the messages flowing, like this:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/9a38f839-67a3-4856-821b-6c8d32d3e32c.gif&#34; alt=&#34;Testing Apache Kafka on Windows in PowerShell&#34;&#xA;        title=&#34;Testing Apache Kafka on Windows in PowerShell&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;h2 id=&#34;stopping-apache-kafka-docker&#34;&gt;Stopping Apache Kafka docker&lt;/h2&gt;&#xA;&lt;p&gt;When the work is done, you can easily turn off running containers by invoking:&lt;/p&gt;&#xA;&lt;figure class=&#34;codeblock on-ink&#34;&gt;&#xA;  &lt;figcaption class=&#34;codeblock__caption&#34;&gt;&#xA;    &lt;span class=&#34;codeblock__lang&#34;&gt;powershell&lt;/span&gt;&#xA;    &lt;span class=&#34;codeblock__caption-right&#34;&gt;&#xA;      &lt;button type=&#34;button&#34; class=&#34;codeblock__copy&#34; aria-label=&#34;Copy code to clipboard&#34;&gt;Copy&lt;/button&gt;&#xA;    &lt;/span&gt;&#xA;  &lt;/figcaption&gt;&#xA;  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;docker-compose&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;down&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;in the folder when you have your &lt;code&gt;docker-compose.yml&lt;/code&gt; file:&lt;/p&gt;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;   &lt;div class=&#34;column twelve&#34;&gt;&#xA;        &lt;img src=&#34;https://zablo.net/resources/151c9bae-1c9a-4ad6-8bb7-01c4b0085338.png&#34; alt=&#34;Stop Apache Kafka docker image&#34;&#xA;        title=&#34;Stop Apache Kafka docker image&#34;/&gt; &#xA;   &lt;/div&gt;&#xA;&lt;/div&gt; &#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;&#xA;&lt;p&gt;Now you have Apache Kafka with Kafka-Manger development environment up and running on your Windows machine. I hope that this short post helped you with the setup. Please share or leave a comment if you liked it!&lt;/p&gt;&#xA;&lt;h2 id=&#34;additional-links--resources&#34;&gt;Additional links &amp;amp; resources&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;full docker-compose.yml file used in this post: &lt;a target=&#39;_blank&#39; href=&#39;https://github.com/marrrcin/kafka-dockercompose&#39;&gt;docker-compose.yml&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Spotify Apache Kafka docker image: &lt;a target=&#39;_blank&#39; href=&#39;https://github.com/spotify/docker-kafka&#39;&gt;&lt;a href=&#34;https://github.com/spotify/docker-kafka&#34;&gt;https://github.com/spotify/docker-kafka&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Kafka-Manager docker image: &lt;a target=&#39;_blank&#39; href=&#39;https://hub.docker.com/r/mzagar/kafka-manager-docker/&#39;&gt;&lt;a href=&#34;https://hub.docker.com/r/mzagar/kafka-manager-docker/&#34;&gt;https://hub.docker.com/r/mzagar/kafka-manager-docker/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
  </channel>
</rss>
