<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/podman/</id>
  <link href="https://www.endpointdev.com/blog/tags/podman/"/>
  <link href="https://www.endpointdev.com/blog/tags/podman/" rel="self"/>
  <updated>2026-03-31T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Containerizing Claude Code with Podman</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2026/03/claude-code-cli-in-container/"/>
      <id>https://www.endpointdev.com/blog/2026/03/claude-code-cli-in-container/</id>
      <published>2026-03-31T00:00:00+00:00</published>
      <author>
        <name>Seth Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2026/03/claude-code-cli-in-container/train-winter.webp&#34; alt=&#34;A long freight train points to the right, slightly toward the camera. The train cars extend off the image to the left. Above the tracks is a white snow-capped mountain and a deep blue sky.&#34;&gt;&lt;br&gt;
Photo by Seth Jensen, 2026.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been experimenting with many different AI tools, and my favorite is Claude Code. It provides the impressive performance of the Opus models without forcing me to use Visual Studio Code (or a fork of it).&lt;/p&gt;
&lt;p&gt;IDEs and fancy editors like IntelliJ and VS Code are great, but I often prefer the simplicity and low memory footprint of working directly in the terminal. Claude Code works well with my tmux-centered work environment.&lt;/p&gt;
&lt;p&gt;However, I don&amp;rsquo;t like giving AI agents access to all of my files, and I &lt;em&gt;really&lt;/em&gt; don&amp;rsquo;t like letting them run arbitrary commands in my shell. I&amp;rsquo;m already pretty cautious about running unvetted code on my machine (I&amp;rsquo;m looking at you, install.sh files I&amp;rsquo;m supposed to blindly &lt;code&gt;curl | bash&lt;/code&gt;), and the nondeterministic nature of LLMs takes this to the next level. It&amp;rsquo;s not just data-sniffing closed-source code or malware you need to worry about, it&amp;rsquo;s the product itself running commands and editing files in ways that, by design, are unique and untested.&lt;/p&gt;
&lt;p&gt;Claude Code has a &lt;a href=&#34;https://code.claude.com/docs/en/sandboxing&#34;&gt;sandbox mode&lt;/a&gt; which is supposed to limit filesystem access to the folder it&amp;rsquo;s run from, but since it&amp;rsquo;s closed-source (&lt;a href=&#34;https://arstechnica.com/ai/2026/03/entire-claude-code-cli-source-code-leaks-thanks-to-exposed-map-file/&#34;&gt;in theory&lt;/a&gt;), you can&amp;rsquo;t verify this isolation. Even in this mode, it can run commands outside the sandboxed folder (in my experience, it asks first, but I wouldn&amp;rsquo;t count on this).&lt;/p&gt;
&lt;p&gt;So, I wrote a little wrapper script to run Claude Code in a Podman container with access only to Claude&amp;rsquo;s config directory and the working directory you pass to the script. I also let it run with the &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt; flag, which I would never do on my host machine (it didn&amp;rsquo;t take long to find a horror story of a typo in an &lt;code&gt;rm -rf&lt;/code&gt; command deleting half of the programs in &lt;code&gt;/Applications&lt;/code&gt; on one Redditor&amp;rsquo;s Mac).&lt;/p&gt;
&lt;h3 id=&#34;important-security-notes&#34;&gt;Important security notes&lt;/h3&gt;
&lt;p&gt;Claude has full access to the folder you pass to this script. That means it can run &lt;code&gt;rm -rf&lt;/code&gt; as much as it wants, and you won&amp;rsquo;t be prompted before it does so, especially when using the &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt; flag.&lt;/p&gt;
&lt;p&gt;You should only run this script if you don&amp;rsquo;t mind everything in that folder getting deleted — for example, in a Git repository where everything has been pushed to a remote, or in a sandbox folder — it&amp;rsquo;s easy to create a copy of your working directory for Claude to play in!&lt;/p&gt;
&lt;p&gt;There is no constraint on outward network traffic, so Claude can send data anywhere it wants. If you&amp;rsquo;re working with sensitive data, you should set up a firewall so it only has access to the necessary Anthropic servers (and perhaps an allowlist you provide). &lt;strong&gt;Think carefully about what data you give to powerful AI agents.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;using-my-claude-container-script&#34;&gt;Using my claude-container script&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Make sure you have Podman and Podman Compose installed (this would also work with Docker &amp;amp; Docker Compose, just replace &lt;code&gt;podman compose&lt;/code&gt; with &lt;code&gt;docker compose&lt;/code&gt; in the &lt;code&gt;claude-container&lt;/code&gt; script)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clone the repo from &lt;a href=&#34;https://github.com/sethjensen1/claude-container&#34;&gt;my GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From the cloned folder, run &lt;code&gt;./claude-container /path/to/working/directory&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optionally, add the script to your PATH. This is what I ran on macOS:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ln -s /Users/myuser/repos/claude-container/claude-container /Users/myuser/bin/claude-container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can then run the script from anywhere: &lt;code&gt;claude-container /my/favorite/sandbox&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s all you need to run it! Keep reading if you&amp;rsquo;re interested in the technical details.&lt;/p&gt;
&lt;h3 id=&#34;what-the-script-is-doing&#34;&gt;What the script is doing&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;claude-container&lt;/code&gt; script is a lightweight wrapper around &lt;code&gt;podman compose&lt;/code&gt;, setting a couple of environment variables so the process is as simple as running Claude in the first place.&lt;/p&gt;
&lt;p&gt;The compose setup uses &lt;a href=&#34;https://docs.docker.com/engine/storage/bind-mounts/&#34;&gt;bind mounts&lt;/a&gt; to give Claude access to the folder you pass, along with your Claude config directory. This means you don&amp;rsquo;t have to reauthenticate every time, and that session history is shared between containers/​your local Claude install.&lt;/p&gt;
&lt;p&gt;Podman compose will automatically build the image if it doesn&amp;rsquo;t exist. If you want to trigger a rebuild, you can run it with the &lt;code&gt;-b&lt;/code&gt; flag: &lt;code&gt;claude-container -b /path/to/working/directory&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The first time you run the script, it will ask you if you&amp;rsquo;re okay bypassing permissions. Because we&amp;rsquo;re only mounting two directories, this should be much safer than it normally would be (provided you&amp;rsquo;re smart about which folders you pass).&lt;/p&gt;
&lt;h3 id=&#34;the-dockerfile&#34;&gt;The Dockerfile&lt;/h3&gt;
&lt;p&gt;The Dockerfile is based on the one from Claude&amp;rsquo;s devcontainer &lt;a href=&#34;https://code.claude.com/docs/en/devcontainer&#34;&gt;docs&lt;/a&gt;. I&amp;rsquo;ve stripped out some development helpers since I&amp;rsquo;m running Claude directly in the &lt;code&gt;CMD&lt;/code&gt;, not using the shell.&lt;/p&gt;
&lt;p&gt;I previously copied the working directory into the image, but have since moved to using bind mounts only. If I want to make sure that Claude doesn&amp;rsquo;t touch any files on my machine, I just create a copy of the working directory to bind mount to the container.&lt;/p&gt;
&lt;p&gt;Another important thing I removed from Claude&amp;rsquo;s devcontainer Dockerfile is the firewall setup with init-firewall.sh. Limiting outgoing traffic is a good idea, but the repos I was working with weren&amp;rsquo;t sensitive enough for me to spend the time getting this working (especially since it seems you need to run the container with the NET_ADMIN capability, which I don&amp;rsquo;t understand well enough to be using).&lt;/p&gt;
&lt;p&gt;Running this with no firewall is dangerous, but less so than running the agent outside of a container.&lt;/p&gt;
&lt;h3 id=&#34;no-container-ception-unfortunately&#34;&gt;No container-ception, unfortunately&lt;/h3&gt;
&lt;p&gt;At some point, I wanted to give Claude access to a backend dev server (it was running a frontend dev server in the container). But the backend dev server runs in a container itself, so I couldn&amp;rsquo;t just have Claude spin up the backend dev server in its container.&lt;/p&gt;
&lt;p&gt;After trying a few things, my workaround was to connect Claude&amp;rsquo;s container to the backend container&amp;rsquo;s Podman network. Once all your containers have been started, find the relevant container network with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;podman network ls&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you&amp;rsquo;re not sure which is the right network, you can check which containers are connected to a network using &lt;code&gt;podman network inspect &amp;lt;network_name&amp;gt;&lt;/code&gt;. To connect Claude to the desired network, run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;podman network connect &amp;lt;relevant container&amp;#39;s network&amp;gt; &amp;lt;claude container&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And of course, if this container is connected to something important (like a database), this will allow Claude access to it. &lt;strong&gt;Always be careful before letting an LLM have access to data&lt;/strong&gt;. In my case, this was an empty database for development, so in terms of exposing data to Claude, it was similar to running the backend dev server within the container.&lt;/p&gt;
&lt;h3 id=&#34;a-few-notes&#34;&gt;A few notes&lt;/h3&gt;
&lt;p&gt;Claude won&amp;rsquo;t have access to some important developer tools in the container (e.g., Playwright). If you want to give it more tools, you could modify the Dockerfile to install them at build time. I tried installing Playwright at first, but found I actually prefer manually testing outside of the container &amp;amp; copying output back to Claude. I appreciate the extra time to slow down, check Claude&amp;rsquo;s decisions, and catch bugs.&lt;/p&gt;
&lt;p&gt;This setup intentionally doesn&amp;rsquo;t give your container SSH access — I don&amp;rsquo;t ever want an LLM to have access to my SSH key, and I would suggest thinking &lt;em&gt;very&lt;/em&gt; hard before giving it access to any servers. That&amp;rsquo;s one of the big reasons I don&amp;rsquo;t want to run Claude on my own machine, especially when using an SSH agent.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve enjoyed developing using Claude Code from within the confines of a single folder. I get the solid code analysis and generation without giving away an excessive amount of data.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Running Ruby in Podman (When rbenv install Fails on Apple Silicon)</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2026/01/ruby-in-podman-apple-silicon/"/>
      <id>https://www.endpointdev.com/blog/2026/01/ruby-in-podman-apple-silicon/</id>
      <published>2026-01-12T00:00:00+00:00</published>
      <author>
        <name>Seth Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2026/01/ruby-in-podman-apple-silicon/newish-ruins.webp&#34; alt=&#34;Amidst dry, leafless brush, a tall structure of dilapidated bricks stands, with a small archway at the bottom in the center of the image&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Seth Jensen, 2025 --&gt;
&lt;p&gt;I recently worked on a legacy Ruby backend app which hadn&amp;rsquo;t been changed for years. A Ruby development environment used to be provided by &lt;a href=&#34;/expertise/version-control-devcamps/&#34;&gt;DevCamps&lt;/a&gt; for this site, but over the years we stopped using Ruby other than this small backend, so we also stopped using camps.&lt;/p&gt;
&lt;p&gt;The frontend development now uses its own local dev server, so I decided to do the same for the backend by running the Unicorn server locally. I&amp;rsquo;m on a MacBook M2, so I should just be able to install &lt;code&gt;rbenv&lt;/code&gt; using Homebrew. Easy, right?&lt;/p&gt;
&lt;p&gt;Unfortunately not. I had a great deal of trouble getting any version of Ruby to run natively on my MacBook M2, so I eventually resorted to using Podman. You can &lt;a href=&#34;#third-try-podman&#34;&gt;skip to the end for my solution&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;first-try-native-rbenv&#34;&gt;First try: native rbenv&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;rbenv&lt;/code&gt; installation went just fine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install rbenv ruby-build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And after adding &lt;code&gt;eval &amp;quot;$(rbenv init -)&amp;quot;&lt;/code&gt; to my &lt;code&gt;~/.zshrc&lt;/code&gt; file, I tried to install the old version of Ruby:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rbenv install 2.4.10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, this returned a &lt;code&gt;BUILD FAILED&lt;/code&gt; message. Strangely, it also failed with a new version of Ruby (3.3.10). I tried debugging for a while before giving up — I figured this project isn&amp;rsquo;t worth multiple hours of getting a local Ruby installation to work (despite my obstinate attempts to do so).&lt;/p&gt;
&lt;h3 id=&#34;second-try-mise&#34;&gt;Second try: mise&lt;/h3&gt;
&lt;p&gt;Several people on forums &amp;amp; blogs recommended using mise, a language-agnostic version manager. After installing it with Homebrew, I ran:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mise use --global ruby@2.4.10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This failed too! There was a good explanation, though: older Ruby versions don&amp;rsquo;t run on ARM processors. Of course, that makes sense. So I just needed to install a newer version from after Apple silicon was supported:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mise use --global ruby@3.3.10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, this failed as well, just like rbenv:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mise ERROR Failed to install core:ruby@3.3.10:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   0: ~/Library/Caches/mise/ruby/ruby-build/bin/ruby-build exited with non-zero status: exit code 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;rsquo;m sure there is a way to get Ruby running through a version manager on Apple silicon; I found several &lt;a href=&#34;https://gorails.com/setup/macos/15-sequoia&#34;&gt;tutorials&lt;/a&gt; claiming you can just run these commands as normal and it&amp;rsquo;ll work. However, after spending longer than I&amp;rsquo;d like to admit, I was completely unable to do so despite trying many fixes found online.&lt;/p&gt;
&lt;p&gt;This may be a unique problem on my machine, or I may be missing something. But the fact was, I&amp;rsquo;d waited through about a dozen failed Ruby installs (which take a long time!) and I just needed the app to work now. So I moved to a third option: run Ruby in a container.&lt;/p&gt;
&lt;h3 id=&#34;third-try-podman&#34;&gt;Third try: Podman&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://podman.io/&#34;&gt;Podman&lt;/a&gt; is a fully open-source containerization system which can run Dockerfiles and docker-compose.yml files. The app is a lightweight Sinatra backend with Unicorn as a server, and I just needed to add CloudFlare Turnstile to reduce bot traffic.&lt;/p&gt;
&lt;p&gt;The app uses two main files: &lt;code&gt;unicorn.rb&lt;/code&gt; (which holds the configuration for the Unicorn server) and &lt;code&gt;config.ru&lt;/code&gt; (which defines and runs the Sinatra app). The command to start the app is pretty simple: &lt;code&gt;bundle exec unicorn -c unicorn.rb config.ru&lt;/code&gt;. I also set up two files for the container: &lt;code&gt;Containerfile&lt;/code&gt; and &lt;code&gt;container-compose.yml&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: Podman does find files named Dockerfile and docker-compose.yml, but here I&amp;rsquo;m using Podman&amp;rsquo;s convention of Containerfile and container-compose.yml, which takes precedence if both are present in the folder.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;To run this, I just needed to set up the environment in my &lt;code&gt;Containerfile&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;containerfile&#34;&gt;&lt;code&gt;Containerfile&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-containerfile&#34; data-lang=&#34;containerfile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;ruby:2.4.10&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;WORKDIR&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/usr/src/app&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;COPY&lt;/span&gt; . .&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;RUN&lt;/span&gt; mkdir -p /var/log &amp;amp;&amp;amp; &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt; gem i bundler &amp;amp;&amp;amp; &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt; bundle install&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;EXPOSE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;8080&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;CMD&lt;/span&gt; [&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;bundle&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;exec&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;unicorn&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;unicorn.rb&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;config.ru&amp;#34;&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It&amp;rsquo;s a pretty simple setup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;set the working directory&lt;/li&gt;
&lt;li&gt;copy files from the source directory into the container&lt;/li&gt;
&lt;li&gt;create the log directory defined in &lt;code&gt;unicorn.rb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;install bundler&lt;/li&gt;
&lt;li&gt;install gems from Gemfile.lock&lt;/li&gt;
&lt;li&gt;expose the port defined in &lt;code&gt;unicorn.rb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;define the server start command using a &lt;code&gt;CMD&lt;/code&gt; instruction&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;container-composeyml&#34;&gt;&lt;code&gt;container-compose.yml&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;services&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;backend&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;context&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;dockerfile&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Containerfile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- .:/usr/src/app&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;ports&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;8080:8080&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;volumes&lt;/code&gt; section means that changes on the host machine will be propogated to the container (and vice versa). This means you don&amp;rsquo;t need to rebuild the container when you change the app, instead you can use a change-watching Gem like &lt;a href=&#34;https://github.com/alexch/rerun&#34;&gt;rerun&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: You can run this without a compose file, the compose file just stores the volume &amp;amp; port information so you can run it more easily.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;podman run -d --name mybackend -v .:/usr/src/app -p 8080:8080 &amp;lt;image_id&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;h4 id=&#34;minimal-unicornrb-configuration-file&#34;&gt;Minimal &lt;code&gt;unicorn.rb&lt;/code&gt; configuration file&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rb&#34; data-lang=&#34;rb&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;listen &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0.0.0.0:8080&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;working_directory &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/usr/src/app&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;0.0.0.0&lt;/code&gt; to connect to the container&amp;rsquo;s network interface&lt;/li&gt;
&lt;li&gt;Define our listening port&lt;/li&gt;
&lt;li&gt;Set the working directory to the same value as in our &lt;code&gt;Containerfile&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: When we forward port 8080 to our Podman container, that traffic arrives on the container&amp;rsquo;s network interface, not on its internal loopback (localhost). If your app only listens on localhost, it&amp;rsquo;s essentially saying &amp;ldquo;I only accept connections from myself,&amp;rdquo; so the forwarded traffic gets rejected. By binding to 0.0.0.0, your app listens on all interfaces, which includes the one Podman uses to route external traffic into the container.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id=&#34;simple-configru&#34;&gt;Simple &lt;code&gt;config.ru&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;require &amp;#39;sinatra&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get &amp;#39;/&amp;#39; do
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;Hello from Sinatra in Podman!\n&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;run Sinatra::Application&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is also very simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;After importing sinatra, define a GET route for the &lt;code&gt;/&lt;/code&gt; location (so this will be accessed from &lt;code&gt;localhost:8080/&lt;/code&gt; on the host machine)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ podman build .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ podman run -p 8080:8080 &amp;lt;image-id&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This returned a successful response on my host machine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ curl localhost:8080
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hello from Sinatra in Podman!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When the app failed to run, it kept trying to restart until I moved a .env file into place and it worked. That shows that the volume is working correctly.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not a Ruby expert, but with this setup I was able to convert the JavaScript code for Turnstile to Ruby and get it working!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Endless OS: A Linux Distro for Kids</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2021/01/linux-distro-for-kids/"/>
      <id>https://www.endpointdev.com/blog/2021/01/linux-distro-for-kids/</id>
      <published>2021-01-20T00:00:00+00:00</published>
      <author>
        <name>Muhammad Najmi bin Ahmad Zabidi</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/kid-at-computer.jpg&#34; alt=&#34;Mom &amp;amp; daughter working at a computer&#34;&gt;
&lt;a href=&#34;https://www.pexels.com/photo/mother-helping-her-daughter-with-her-homework-4260323/&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.pexels.com/@august-de-richelieu&#34;&gt;August de Richelieu&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In 2020 some of us had to work from home while taking care of the kids ourselves, as most childcare services are temporarily closed due to the COVID-19 pandemic. In this post I won’t complain about the pandemic, but rather share my experience.&lt;/p&gt;
&lt;p&gt;I have installed several different Linux distributions for my kids’ desktop computer in the past, but have found it quite difficult to find a balance between strict parental controls and no parental controls at all. Then I came across &lt;a href=&#34;https://endlessos.com/&#34;&gt;Endless OS&lt;/a&gt;, a Linux distro based on Debian, but with heavy customizations to focus on school from home.&lt;/p&gt;
&lt;h3 id=&#34;installation&#34;&gt;Installation&lt;/h3&gt;
&lt;p&gt;The installation process was smooth and easy. The install image I chose was quite huge though, at around 16GB. But given we can just use a USB drive as the installation medium nowadays this should not be a big issue. The installer does not seem to give an option to encrypt my hard disk with LUKS during the installation phase.&lt;/p&gt;
&lt;p&gt;Endless OS is powered by &lt;a href=&#34;https://people.gnome.org/~walters/ostree/doc-onepage/&#34;&gt;OSTree&lt;/a&gt; (which is defined as “a system for versioning updates of Linux-based operating systems”) and &lt;a href=&#34;https://flatpak.org/&#34;&gt;Flatpak&lt;/a&gt;. According to the website, “Endless OS uses OSTree, a non-destructive and atomic technique to deploy operating system updates. That means updates can be installed without affecting the running state of the system, making the process safe and robust from environmental factors such as a sudden power loss.”&lt;/p&gt;
&lt;p&gt;The default window manager is a customized Gnome.&lt;/p&gt;
&lt;p&gt;According to its website, the operating system is free for individuals and non-commercial use up to 500 computers.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/desktop.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;package-installation-and-package-updates&#34;&gt;Package installation and package updates&lt;/h3&gt;
&lt;p&gt;We can choose from a couple of ways to install new packages (or update them). You can either use the Control Centre, or (if you want to install remotely) the command line. Although Endless OS is based on Debian, the &lt;code&gt;apt&lt;/code&gt; command does not work here. Instead you can use Flatpak, with commands like &lt;code&gt;flatpak install &amp;lt;package name&amp;gt;&lt;/code&gt;. Flatpak assists the user when installing a new package. For example, if you just typed the package name half correctly, it will suggest a similar name so that you can choose the correct package’s name.&lt;/p&gt;
&lt;p&gt;It’s FOSS has &lt;a href=&#34;https://itsfoss.com/flatpak-guide/&#34;&gt;a guide to using Flatpak&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/installer.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/app-centre.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/flatpak-update.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;package-control&#34;&gt;Package control&lt;/h3&gt;
&lt;p&gt;By default, the OpenSSH service for remote shell login is not enabled. The user needs to enable it through the GUI settings in &lt;code&gt;Sharing-&amp;gt;Remote Login&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/sharing-ssh.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/sharing-ssh2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;We can limit the type of applications enabled on Endless OS. For example, we could disable the web browser from the Control Centre, while maintaining use of the other apps. The default administrative level user in Endless OS is &lt;strong&gt;administrator&lt;/strong&gt;, with sudo privileges. In other words, the “administrator” user is included in the “sudo” group. However, you could just drop your SSH key in the root account if you insist on using the root login to get into the shell account. I also had to remove the “shared” user account as it does not ask for any password. The kids in the house will have to use the account that I created and assigned to them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/parental-control.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;We could disable the browser in the parental control settings, however we could not define where they could/​could not go from the settings.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/parental-control2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Although Endless OS is unlike other Linux distros, you can fortunately still do your work inside it if you need to using &lt;a href=&#34;https://support.endlessos.org/en/apps/podman&#34;&gt;Podman&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;browsing-management&#34;&gt;Browsing management&lt;/h3&gt;
&lt;p&gt;I tried to search for similar control for my network, but couldn’t find a good option. My colleague previously &lt;a href=&#34;/blog/2020/12/pihole-great-holiday-gift/&#34;&gt;wrote&lt;/a&gt; about Pi-hole, so I decided to give a try. I found a &lt;a href=&#34;https://codeopolis.com/posts/running-pi-hole-in-docker-is-remarkably-easy/&#34;&gt;tutorial&lt;/a&gt; on using Pi-hole in a container, and made minor changes from that. As Endless OS ships with podman included, we can use the docker command or adapt it to podman. So I changed the &amp;ndash;restart flag to &amp;ndash;restart=always and used podman. The rest is similar to the original post.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;podman run &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;--name=pihole &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-e &lt;span style=&#34;color:#369&#34;&gt;TZ&lt;/span&gt;=Asia/Kuala_Lumpur &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-e &lt;span style=&#34;color:#369&#34;&gt;WEBPASSWORD&lt;/span&gt;=YOURPASS &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-e &lt;span style=&#34;color:#369&#34;&gt;SERVERIP&lt;/span&gt;=YOUR.SERVER.IP &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-v pihole:/etc/pihole &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-v dnsmasq:/etc/dnsmasq.d &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-p 80:80 &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-p 53:53/tcp &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;-p 53:53/udp &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;--restart=always &lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;&lt;/span&gt;pihole/pihole&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can then browse Pi-hole’s admin page by going to &lt;code&gt;http://&amp;lt;server&amp;gt;/admin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/pi-hole-eos.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I like Endless OS for my kid’s usage, however I think the distro needs a lot of help from the community to make it appealing to working adults too. I previously found that I could not install the curl package with flatpak (and I could not use apt to install it). So I built curl with a manifest file from &lt;a href=&#34;https://community.endlessos.com/t/package-installer/9314/2&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/01/linux-distro-for-kids/curl-build.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;The things I love about this distro are browser management and flatpak for installing the latest software/​games from flathub. There may be more points I like as I use it more and more. As for now, the current offerings are already enough. Maybe what I need is a screen time management and an internal URL blocking manager rather than installing an external application.&lt;/p&gt;
&lt;p&gt;These are my main observations of Endless OS after a few weeks of usage on my kid’s computer. If you have also used it and have any useful information to add, please leave a comment below.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
