<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kakisoft</title>
    <description>The latest articles on DEV Community by kakisoft (@kakisoft).</description>
    <link>https://dev.to/kakisoft</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F492796%2Fd7eed5bc-fd18-4328-b89a-c00b32cdaa67.jpg</url>
      <title>DEV Community: kakisoft</title>
      <link>https://dev.to/kakisoft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kakisoft"/>
    <language>en</language>
    <item>
      <title>Docker - Host–Container File Sharing : Named Volumes vs Bind Mounts, Behavior Differences, and Key Pitfalls</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sun, 16 Nov 2025 15:24:19 +0000</pubDate>
      <link>https://dev.to/kakisoft/docker-host-container-file-sharing-named-volumes-vs-bind-mounts-behavior-differences-and-key-45o9</link>
      <guid>https://dev.to/kakisoft/docker-host-container-file-sharing-named-volumes-vs-bind-mounts-behavior-differences-and-key-45o9</guid>
      <description>&lt;p&gt;When sharing files between a host and a Docker container, there are two main options: "named volumes" and "bind mounts".&lt;br&gt;&lt;br&gt;
They look similar in docker-compose.yml, but their behavior is very different — and that difference can cause serious headaches if you don’t understand it.  &lt;/p&gt;

&lt;p&gt;Let’s dig into what actually happens, using a real case I ran into.  &lt;/p&gt;

&lt;p&gt;(Note: I’ll skip the basics of Docker and Docker Compose setup here.)  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt; environment &amp;gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure: AWS EC2&lt;/li&gt;
&lt;li&gt;Architecture: 64-bit ARM&lt;/li&gt;
&lt;li&gt;OS: Ubuntu Server 24.04&lt;/li&gt;
&lt;li&gt;Docker: 28.1.1&lt;/li&gt;
&lt;li&gt;Docker Compose: v2.35.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Two Ways to Share Files Between Host and Container
&lt;/h2&gt;

&lt;p&gt;Docker provides two ways to share files between the host and a container:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Named Volumes&lt;/li&gt;
&lt;li&gt;Bind Mounts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They look nearly identical in configuration, but behave differently when you start up your container.  &lt;/p&gt;

&lt;p&gt;Let’s look at both.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Named Volume
&lt;/h3&gt;

&lt;p&gt;No "./" prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shared directory is managed internally by Docker.&lt;br&gt;&lt;br&gt;
In this example, it’s stored somewhere like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/lib/docker/volumes/mediawiki_mediawiki_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That path is far from your home directory — and only accessible by root.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Bind Mount
&lt;/h3&gt;

&lt;p&gt;Has a "./" prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, the directory is managed by the host, and the path is relative to where your Dockerfile or compose.yaml exists.&lt;br&gt;&lt;br&gt;
For example, if you run this under the "ubuntu" user’s home directory, it’ll look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/home/ubuntu/MediaWiki/mediawiki_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, you might think "same thing, different path."&lt;br&gt;&lt;br&gt;
But in reality, there’s a critical difference in how Docker handles these at startup.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Real-World Case
&lt;/h2&gt;

&lt;p&gt;At work, we decided to manage our internal manuals using "MediaWiki" (the same engine used by Wikipedia).&lt;br&gt;&lt;br&gt;
We wanted to easily copy and back up uploaded files (images, PDFs, etc.) from the host side, so I configured the media directory to be shared between the host and the container.  &lt;/p&gt;

&lt;p&gt;But as the setup grew, I found myself constantly adding more directories to share in compose.yaml.&lt;br&gt;&lt;br&gt;
Eventually, I got tired of tweaking the file every time I needed another folder, and thought:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why not just share the entire "/var/www/html" directory between host and container? Then I’ll never have to touch compose.yaml again.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounded reasonable. So I did that.  &lt;/p&gt;
&lt;h2&gt;
  
  
  What Is MediaWiki?
&lt;/h2&gt;

&lt;p&gt;It’s the open-source wiki software that powers Wikipedia.&lt;br&gt;&lt;br&gt;
You can check it here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://www.mediawiki.org/wiki/MediaWiki/" rel="noopener noreferrer"&gt;MediaWiki&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;The details of MediaWiki itself aren’t important for this story — it’s just the app I was containerizing.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The First Compose File (Named Volume)
&lt;/h2&gt;

&lt;p&gt;Here’s how my initial setup looked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I forgot the "./" prefix.&lt;br&gt;&lt;br&gt;
That small mistake made Docker create the shared volume under "/var/lib/docker/volumes/mediawiki_mediawiki_data" — not in my project folder.  &lt;/p&gt;

&lt;p&gt;That meant:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All uploaded files were buried deep inside Docker’s internal path&lt;/li&gt;
&lt;li&gt;Only root could access them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I fixed the "volumes:" section.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Updated Compose File (Bind Mount)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Just added "./". Simple, right?  &lt;/p&gt;

&lt;p&gt;Since there was no existing "mediawiki_data" directory, I copied the files from the container manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; mediawiki_mediawiki_data:/data:ro &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/backup alpine sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cd /data &amp;amp;&amp;amp; tar czf /backup/mediawiki_data_backup.tgz .'&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ./mediawiki_data
&lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="nt"&gt;-xzf&lt;/span&gt; mediawiki_data_backup.tgz &lt;span class="nt"&gt;-C&lt;/span&gt; ./mediawiki_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything worked fine.&lt;br&gt;&lt;br&gt;
I updated the repo with the corrected compose.yaml, and all looked good.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem on Another Server
&lt;/h2&gt;

&lt;p&gt;Later, I needed to replicate this setup on a new server.&lt;br&gt;&lt;br&gt;
Same compose.yaml, same image — but MediaWiki wouldn’t start.  &lt;/p&gt;

&lt;p&gt;Turns out, "/var/www/html" &lt;strong&gt;inside the container was completely empty.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Every file required for the app to run was gone.  &lt;/p&gt;

&lt;p&gt;What happened?  &lt;/p&gt;
&lt;h2&gt;
  
  
  Root Cause
&lt;/h2&gt;

&lt;p&gt;Here’s the relevant section again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using a "bind mount", Docker &lt;strong&gt;always&lt;/strong&gt; treats the host’s files as the source of truth.&lt;br&gt;&lt;br&gt;
If the host folder exists (even if it’s empty), Docker will &lt;strong&gt;overwrite&lt;/strong&gt; the container directory with it.  &lt;/p&gt;

&lt;p&gt;So on a clean machine, Docker:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates an empty "./mediawiki_data" folder&lt;/li&gt;
&lt;li&gt;Then syncs it into the container&lt;/li&gt;
&lt;li&gt;Effectively deleting everything inside "/var/www/html"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Brutal. But that’s the expected behavior.  &lt;/p&gt;
&lt;h3&gt;
  
  
  What About Named Volumes?
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With a "named volume", Docker manages the directory under "/var/lib/docker/volumes/...".&lt;br&gt;&lt;br&gt;
If it doesn’t exist yet, Docker automatically creates it &lt;strong&gt;and copies the container’s existing files into it.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;So:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the first run -&amp;gt; container files are treated as the source of truth&lt;/li&gt;
&lt;li&gt;On subsequent runs -&amp;gt; host (volume) files take priority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bind mounts, on the other hand, &lt;strong&gt;always&lt;/strong&gt; trust the host side.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Difference in Behavior
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;First Run&lt;/th&gt;
&lt;th&gt;Subsequent Runs&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bind Mount&lt;/td&gt;
&lt;td&gt;Host overwrites container (empty folder = deletes container files)&lt;/td&gt;
&lt;td&gt;Host remains the source&lt;/td&gt;
&lt;td&gt;High (can delete app data)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Named Volume&lt;/td&gt;
&lt;td&gt;Container copies files into the volume&lt;/td&gt;
&lt;td&gt;Host (volume) becomes source&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So if you switch from named volume -&amp;gt; bind mount mid-project, you may end up deleting everything unintentionally.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Workaround
&lt;/h2&gt;

&lt;p&gt;Sure, you could do this the long way:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start the container with a named volume&lt;/li&gt;
&lt;li&gt;Backup the files&lt;/li&gt;
&lt;li&gt;Stop the container&lt;/li&gt;
&lt;li&gt;Switch to bind mount&lt;/li&gt;
&lt;li&gt;Restore the files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;…but it’s messy, and managing those compose file changes across environments is painful.  &lt;/p&gt;

&lt;p&gt;Here’s a cleaner approach.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Step-by-Step Fix
&lt;/h3&gt;

&lt;p&gt;Instead of starting from an empty directory, I pre-populate the host folder &lt;strong&gt;with the same files the container expects&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create target directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; ./mediawiki_data

&lt;span class="c"&gt;# Copy initial files from the container&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;/mediawiki_data"&lt;/span&gt;:/out &lt;span class="se"&gt;\&lt;/span&gt;
  mediawiki:1.43.1 &lt;span class="se"&gt;\&lt;/span&gt;
  sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cp -a /var/www/html/. /out/'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a "mediawiki_data" folder on the host&lt;/li&gt;
&lt;li&gt;Starts a short-lived container&lt;/li&gt;
&lt;li&gt;Copies "/var/www/html" from the container into the host directory&lt;/li&gt;
&lt;li&gt;Exits immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the host folder matches the container’s expected state — no accidental deletion, no surprises.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker supports two main ways to share files between host and container: "named volumes" and "bind mounts".&lt;/li&gt;
&lt;li&gt;They look similar in YAML but behave very differently.&lt;/li&gt;
&lt;li&gt;"Bind mounts" always trust the host side; an empty host folder will wipe the container’s directory.&lt;/li&gt;
&lt;li&gt;"Named volumes" trust the container at first run, then switch to the host on subsequent runs.&lt;/li&gt;
&lt;li&gt;The difference can cause subtle and destructive bugs if you’re not aware of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your shared directory is supposed to start empty and only receive files from the container, this won’t matter.&lt;br&gt;&lt;br&gt;
But if the container ships with essential files — be careful.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Which One Should You Use?
&lt;/h2&gt;

&lt;p&gt;Opinions differ.&lt;br&gt;&lt;br&gt;
The official Docker docs generally recommend "named volumes", but that’s not always the best idea.  &lt;/p&gt;

&lt;p&gt;In real projects, you often nuke your Docker environment when testing or debugging —&lt;br&gt;&lt;br&gt;
and "docker rm -v" or similar commands can easily wipe out those volumes (and all your data) in one go.  &lt;/p&gt;

&lt;p&gt;For production data or important files, I prefer &lt;strong&gt;bind mounts&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paths are visible and understandable&lt;/li&gt;
&lt;li&gt;You can clearly see what’s being deleted&lt;/li&gt;
&lt;li&gt;You don’t depend on Docker’s internal volume management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sure, Docker devs want to show that “Docker is safe and convenient,”&lt;br&gt;
but as a sysadmin, I’d rather store my data where I can see it.&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
    <item>
      <title>Docker - Host–Container File Sharing : Named Volumes vs Bind Mounts, Behavior Differences, and Key Pitfalls</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sun, 16 Nov 2025 15:24:19 +0000</pubDate>
      <link>https://dev.to/kakisoft/docker-host-container-file-sharing-named-volumes-vs-bind-mounts-behavior-differences-and-key-5750</link>
      <guid>https://dev.to/kakisoft/docker-host-container-file-sharing-named-volumes-vs-bind-mounts-behavior-differences-and-key-5750</guid>
      <description>&lt;p&gt;When sharing files between a host and a Docker container, there are two main options: "named volumes" and "bind mounts".&lt;br&gt;&lt;br&gt;
They look similar in docker-compose.yml, but their behavior is very different — and that difference can cause serious headaches if you don’t understand it.  &lt;/p&gt;

&lt;p&gt;Let’s dig into what actually happens, using a real case I ran into.  &lt;/p&gt;

&lt;p&gt;(Note: I’ll skip the basics of Docker and Docker Compose setup here.)  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt; environment &amp;gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure: AWS EC2&lt;/li&gt;
&lt;li&gt;Architecture: 64-bit ARM&lt;/li&gt;
&lt;li&gt;OS: Ubuntu Server 24.04&lt;/li&gt;
&lt;li&gt;Docker: 28.1.1&lt;/li&gt;
&lt;li&gt;Docker Compose: v2.35.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Two Ways to Share Files Between Host and Container
&lt;/h2&gt;

&lt;p&gt;Docker provides two ways to share files between the host and a container:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Named Volumes&lt;/li&gt;
&lt;li&gt;Bind Mounts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They look nearly identical in configuration, but behave differently when you start up your container.  &lt;/p&gt;

&lt;p&gt;Let’s look at both.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Named Volume
&lt;/h3&gt;

&lt;p&gt;No "./" prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shared directory is managed internally by Docker.&lt;br&gt;&lt;br&gt;
In this example, it’s stored somewhere like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/lib/docker/volumes/mediawiki_mediawiki_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That path is far from your home directory — and only accessible by root.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Bind Mount
&lt;/h3&gt;

&lt;p&gt;Has a "./" prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, the directory is managed by the host, and the path is relative to where your Dockerfile or compose.yaml exists.&lt;br&gt;&lt;br&gt;
For example, if you run this under the "ubuntu" user’s home directory, it’ll look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/home/ubuntu/MediaWiki/mediawiki_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, you might think "same thing, different path."&lt;br&gt;&lt;br&gt;
But in reality, there’s a critical difference in how Docker handles these at startup.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Real-World Case
&lt;/h2&gt;

&lt;p&gt;At work, we decided to manage our internal manuals using "MediaWiki" (the same engine used by Wikipedia).&lt;br&gt;&lt;br&gt;
We wanted to easily copy and back up uploaded files (images, PDFs, etc.) from the host side, so I configured the media directory to be shared between the host and the container.  &lt;/p&gt;

&lt;p&gt;But as the setup grew, I found myself constantly adding more directories to share in compose.yaml.&lt;br&gt;&lt;br&gt;
Eventually, I got tired of tweaking the file every time I needed another folder, and thought:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why not just share the entire "/var/www/html" directory between host and container? Then I’ll never have to touch compose.yaml again.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounded reasonable. So I did that.  &lt;/p&gt;
&lt;h2&gt;
  
  
  What Is MediaWiki?
&lt;/h2&gt;

&lt;p&gt;It’s the open-source wiki software that powers Wikipedia.&lt;br&gt;&lt;br&gt;
You can check it here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://www.mediawiki.org/wiki/MediaWiki/" rel="noopener noreferrer"&gt;MediaWiki&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;The details of MediaWiki itself aren’t important for this story — it’s just the app I was containerizing.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The First Compose File (Named Volume)
&lt;/h2&gt;

&lt;p&gt;Here’s how my initial setup looked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I forgot the "./" prefix.&lt;br&gt;&lt;br&gt;
That small mistake made Docker create the shared volume under "/var/lib/docker/volumes/mediawiki_mediawiki_data" — not in my project folder.  &lt;/p&gt;

&lt;p&gt;That meant:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All uploaded files were buried deep inside Docker’s internal path&lt;/li&gt;
&lt;li&gt;Only root could access them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I fixed the "volumes:" section.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Updated Compose File (Bind Mount)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Just added "./". Simple, right?  &lt;/p&gt;

&lt;p&gt;Since there was no existing "mediawiki_data" directory, I copied the files from the container manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; mediawiki_mediawiki_data:/data:ro &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/backup alpine sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cd /data &amp;amp;&amp;amp; tar czf /backup/mediawiki_data_backup.tgz .'&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ./mediawiki_data
&lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="nt"&gt;-xzf&lt;/span&gt; mediawiki_data_backup.tgz &lt;span class="nt"&gt;-C&lt;/span&gt; ./mediawiki_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything worked fine.&lt;br&gt;&lt;br&gt;
I updated the repo with the corrected compose.yaml, and all looked good.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem on Another Server
&lt;/h2&gt;

&lt;p&gt;Later, I needed to replicate this setup on a new server.&lt;br&gt;&lt;br&gt;
Same compose.yaml, same image — but MediaWiki wouldn’t start.  &lt;/p&gt;

&lt;p&gt;Turns out, "/var/www/html" &lt;strong&gt;inside the container was completely empty.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Every file required for the app to run was gone.  &lt;/p&gt;

&lt;p&gt;What happened?  &lt;/p&gt;
&lt;h2&gt;
  
  
  Root Cause
&lt;/h2&gt;

&lt;p&gt;Here’s the relevant section again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using a "bind mount", Docker &lt;strong&gt;always&lt;/strong&gt; treats the host’s files as the source of truth.&lt;br&gt;&lt;br&gt;
If the host folder exists (even if it’s empty), Docker will &lt;strong&gt;overwrite&lt;/strong&gt; the container directory with it.  &lt;/p&gt;

&lt;p&gt;So on a clean machine, Docker:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates an empty "./mediawiki_data" folder&lt;/li&gt;
&lt;li&gt;Then syncs it into the container&lt;/li&gt;
&lt;li&gt;Effectively deleting everything inside "/var/www/html"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Brutal. But that’s the expected behavior.  &lt;/p&gt;
&lt;h3&gt;
  
  
  What About Named Volumes?
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mediawiki_data:/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With a "named volume", Docker manages the directory under "/var/lib/docker/volumes/...".&lt;br&gt;&lt;br&gt;
If it doesn’t exist yet, Docker automatically creates it &lt;strong&gt;and copies the container’s existing files into it.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;So:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the first run -&amp;gt; container files are treated as the source of truth&lt;/li&gt;
&lt;li&gt;On subsequent runs -&amp;gt; host (volume) files take priority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bind mounts, on the other hand, &lt;strong&gt;always&lt;/strong&gt; trust the host side.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Difference in Behavior
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;First Run&lt;/th&gt;
&lt;th&gt;Subsequent Runs&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bind Mount&lt;/td&gt;
&lt;td&gt;Host overwrites container (empty folder = deletes container files)&lt;/td&gt;
&lt;td&gt;Host remains the source&lt;/td&gt;
&lt;td&gt;High (can delete app data)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Named Volume&lt;/td&gt;
&lt;td&gt;Container copies files into the volume&lt;/td&gt;
&lt;td&gt;Host (volume) becomes source&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So if you switch from named volume -&amp;gt; bind mount mid-project, you may end up deleting everything unintentionally.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Workaround
&lt;/h2&gt;

&lt;p&gt;Sure, you could do this the long way:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start the container with a named volume&lt;/li&gt;
&lt;li&gt;Backup the files&lt;/li&gt;
&lt;li&gt;Stop the container&lt;/li&gt;
&lt;li&gt;Switch to bind mount&lt;/li&gt;
&lt;li&gt;Restore the files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;…but it’s messy, and managing those compose file changes across environments is painful.  &lt;/p&gt;

&lt;p&gt;Here’s a cleaner approach.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Step-by-Step Fix
&lt;/h3&gt;

&lt;p&gt;Instead of starting from an empty directory, I pre-populate the host folder &lt;strong&gt;with the same files the container expects&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create target directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; ./mediawiki_data

&lt;span class="c"&gt;# Copy initial files from the container&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;/mediawiki_data"&lt;/span&gt;:/out &lt;span class="se"&gt;\&lt;/span&gt;
  mediawiki:1.43.1 &lt;span class="se"&gt;\&lt;/span&gt;
  sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cp -a /var/www/html/. /out/'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a "mediawiki_data" folder on the host&lt;/li&gt;
&lt;li&gt;Starts a short-lived container&lt;/li&gt;
&lt;li&gt;Copies "/var/www/html" from the container into the host directory&lt;/li&gt;
&lt;li&gt;Exits immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the host folder matches the container’s expected state — no accidental deletion, no surprises.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker supports two main ways to share files between host and container: "named volumes" and "bind mounts".&lt;/li&gt;
&lt;li&gt;They look similar in YAML but behave very differently.&lt;/li&gt;
&lt;li&gt;"Bind mounts" always trust the host side; an empty host folder will wipe the container’s directory.&lt;/li&gt;
&lt;li&gt;"Named volumes" trust the container at first run, then switch to the host on subsequent runs.&lt;/li&gt;
&lt;li&gt;The difference can cause subtle and destructive bugs if you’re not aware of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your shared directory is supposed to start empty and only receive files from the container, this won’t matter.&lt;br&gt;&lt;br&gt;
But if the container ships with essential files — be careful.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Which One Should You Use?
&lt;/h2&gt;

&lt;p&gt;Opinions differ.&lt;br&gt;&lt;br&gt;
The official Docker docs generally recommend "named volumes", but that’s not always the best idea.  &lt;/p&gt;

&lt;p&gt;In real projects, you often nuke your Docker environment when testing or debugging —&lt;br&gt;&lt;br&gt;
and "docker rm -v" or similar commands can easily wipe out those volumes (and all your data) in one go.  &lt;/p&gt;

&lt;p&gt;For production data or important files, I prefer &lt;strong&gt;bind mounts&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paths are visible and understandable&lt;/li&gt;
&lt;li&gt;You can clearly see what’s being deleted&lt;/li&gt;
&lt;li&gt;You don’t depend on Docker’s internal volume management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sure, Docker devs want to show that “Docker is safe and convenient,”&lt;br&gt;
but as a sysadmin, I’d rather store my data where I can see it.&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
    <item>
      <title>When I tried pair programming for infrastructure work, it turned out to be super effective!</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sun, 03 Nov 2024 02:24:27 +0000</pubDate>
      <link>https://dev.to/kakisoft/when-i-tried-pair-programming-for-infrastructure-work-it-turned-out-to-be-super-effective-449g</link>
      <guid>https://dev.to/kakisoft/when-i-tried-pair-programming-for-infrastructure-work-it-turned-out-to-be-super-effective-449g</guid>
      <description>&lt;p&gt;In one project, I explained infrastructure task to assign other team member, while sharing my screen. The situation ends up similar to pair programming.&lt;/p&gt;

&lt;p&gt;Surprisingly, I fount it is hugely effective. So, I thought "It is the most effective method for infrastructure tasks"&lt;br&gt;
Then I will tell you how to do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is pair programming?
&lt;/h2&gt;

&lt;p&gt;Pair programming is a method that two engineers program using only one computer.&lt;br&gt;
One acts as coder, and another acts as supporter. The role can be switched when it's needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem of pair programming (In my opinion)
&lt;/h2&gt;

&lt;p&gt;Each engineer often has different develop environment. As times go by, we have more and more variety of choices to build our develop environment.&lt;/p&gt;

&lt;p&gt;For example, hardware such as the number of the display, type of keyboard, and mouse.&lt;br&gt;
And software such as editor, the configuration of shortcut key and shell.&lt;br&gt;
There are uncountable numbers of differences.&lt;/p&gt;

&lt;p&gt;It is impossible to prepare develop environment customized for you when do pair programming, because you have to share hardware and software with your partner.&lt;/p&gt;

&lt;p&gt;I use VSCode, default shell without any customization, a few alias, a few snippets, some plugins.&lt;br&gt;
If my partner needs Vim, or heavily customized shortcut keys for their performance, we lose productivity.&lt;/p&gt;

&lt;p&gt;Fir of all, these days most of engineers work remotely, so it is not common to work at same place.&lt;/p&gt;

&lt;p&gt;Considering these points, it is difficult to prepare not only to keep their performance but also incorporate this method.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does pair programming works for infrastructure
&lt;/h2&gt;

&lt;p&gt;Unlike normal programming, it is common for engineers to have completely different infrastructure environment.&lt;/p&gt;

&lt;p&gt;Once they login to server, there is no difference of their useful command.&lt;br&gt;
Also, it is rare to have a necessity to work with many displays.&lt;/p&gt;

&lt;p&gt;So, you can make pair programming environment only by sharing engineer's display and using chat application.&lt;/p&gt;

&lt;p&gt;It is easy to prepare online as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of pair programming for infrastructure development
&lt;/h2&gt;

&lt;p&gt;I found these benefits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduce obscuring of infrastructure works
&lt;/h3&gt;

&lt;p&gt;Infrastructure works tend to be obscure, because it is common to see only one person for infrastructure work.&lt;br&gt;
And the number of infrastructure engineers is often reduced due to budget.&lt;/p&gt;

&lt;p&gt;Also, many issues are left out with excuse of "we will follow up".&lt;br&gt;
Some cases, the project have many kludges to work around unnecessarily complicated infrastructure.&lt;br&gt;
These information and knowledge are not officially documented and shared with team members.&lt;/p&gt;

&lt;p&gt;These knowledge tends to be exposed when other engineer take over from resigning engineer.&lt;/p&gt;

&lt;p&gt;But, you can find out inside of closed box in pair programming, because when you work for infrastructure with sharing display, the partner can ask "What is that for?".&lt;br&gt;
Also, the team can make sure what should be documented after the task.&lt;/p&gt;

&lt;h2&gt;
  
  
  It is possible to take over without formal documents
&lt;/h2&gt;

&lt;p&gt;Infrastructure engineers often have to do ineffective task because of unoptimized infrastructure.&lt;br&gt;
And, documenting those takes away the time and effort.&lt;br&gt;
(ex. Previous assigned engineer did inappropriate job, which is confusing and complicated. The deadline was close, so the team did last minutes job, thinking to redo it. But that last minutes job stayed for a long time.)&lt;/p&gt;

&lt;p&gt;It is not rare to get stuck in a negative cycle like putting off documentation later because it requires a lot of effort, not being able to find other engineer to manage infrastructure, taking forever to educate other engineer because of how complicated to explain.&lt;/p&gt;

&lt;p&gt;But, if you work infrastructure task using pair programming method, you can explain about complex issue when the partner ask you "Why do you use this operation?".&lt;/p&gt;

&lt;p&gt;Many infrastructure task and documents are not reviewed unlike source code.&lt;br&gt;
Pair programming can solve this problem.&lt;/p&gt;

&lt;p&gt;It has the same effect as code review by pair programming. You can find more effective approach from your partner.&lt;/p&gt;

&lt;p&gt;All infrastructure work can't be done by code even though IaC exists.&lt;br&gt;
So, pair programming let you work productively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Notice commend mistake
&lt;/h3&gt;

&lt;p&gt;There are a lot of infrastructure task that you need to pay attention.&lt;/p&gt;

&lt;p&gt;Some tasks are nerve wrecking because one small mistake on command often lead to critical problem.&lt;/p&gt;

&lt;p&gt;But, when you write a command with shared screen, you can ask your partner to check.&lt;/p&gt;

&lt;p&gt;If you made a mistake, your partner can warn you, and reduce your mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Share useful commands
&lt;/h3&gt;

&lt;p&gt;You will use many variety of commands at infrastructure works.&lt;/p&gt;

&lt;p&gt;Some commands that you use on a daily basis make an impression to other engineers like "I didn't know that command." or "This is new way to use this command for me."&lt;/p&gt;

&lt;p&gt;Also, you can share some information like "I should use this command when I want to check it"&lt;/p&gt;

&lt;h2&gt;
  
  
  Collaborate to solve the errors
&lt;/h2&gt;

&lt;p&gt;If you face unknown error, you can divide the task to investigate.&lt;/p&gt;

&lt;p&gt;For example, a engineer check the logs from the web server such as nginx, the other engineer check the logs from application such as Laravel.&lt;/p&gt;

&lt;p&gt;You can get an advantage by using same server. Because it doesn't mean you both checking different local data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good for your mental health
&lt;/h2&gt;

&lt;p&gt;Personally, it is the most effective point.&lt;/p&gt;

&lt;p&gt;Since our infrastructure tasks have a significant impact on project, you get ill if you get unknown errors and you have no idea how to solve it.&lt;/p&gt;

&lt;p&gt;For example, you might face a situation like,&lt;br&gt;
"Shit... I just deployed as usual. But why am I getting this errors?? I have to solve this before the demo tomorrow morning."&lt;br&gt;
"Are you serious? It is already 4:00 AM!?"&lt;/p&gt;

&lt;p&gt;In this case, by researching with your partner, you can reduce your stress and get more effective.&lt;/p&gt;

&lt;p&gt;I highly recommend this to engineer like you who have got stomachache by infrastructure task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our actual conversations
&lt;/h2&gt;

&lt;p&gt;It is not easy to imagine these advantages by only reading. So, I wrote down our actual conversations.&lt;/p&gt;

&lt;p&gt;I changed some phrases to make them easier to understand, but the general outline is almost same as actual one.&lt;/p&gt;

&lt;h3&gt;
  
  
  case 1．
&lt;/h3&gt;

&lt;p&gt;Me: "Oh! I got an error in npm install. Why? Have you added some new libraries?"&lt;/p&gt;

&lt;p&gt;My colleague: "Yes. I have added some of them. They might be the problem."&lt;/p&gt;

&lt;p&gt;Me: "OK. I'll check the error message. I found it. Oh! The problem comes from Node.js v17."&lt;/p&gt;

&lt;p&gt;My colleague: "Why do you use v17? The development environment uses v18."&lt;/p&gt;

&lt;p&gt;Me: "Amazon Linux 2 is not supporting v18. So, I installed v17 unwillingly."&lt;/p&gt;

&lt;p&gt;My colleague: "Really? Is it impossible to install v18?"&lt;/p&gt;

&lt;p&gt;Me: "Yes. We need to prepare Amazon Linux 3 to use v18.  At first I was using Amazon Linux 3. 3 is too deferent from 2. So, I changed 2."&lt;/p&gt;

&lt;p&gt;My colleague: "Is is so different?"&lt;/p&gt;

&lt;p&gt;Me: "Definitely. We can't use scripts and commands from Amazon Linux 2 in Amazon Linux 3. We had to relearn so many commands.&lt;br&gt;
I can't understand why it is necessary to change drastically. I swear to god not to use Amazon Linux any more.&lt;br&gt;
The deadline for demo environment was just around the corner. I didn't have enough time to relearn them. So I discarded 3. Then I tried to install v18, but I couldn't."&lt;/p&gt;

&lt;p&gt;My colleague: "Then, we got this shit."&lt;/p&gt;

&lt;p&gt;Me: "Oh, but v16 might work. Let's install nvm and change the version."&lt;/p&gt;

&lt;h3&gt;
  
  
  case 2．
&lt;/h3&gt;

&lt;p&gt;Me: "Oh! Now, I got a different error in npm install! Why? What's wrong?"&lt;/p&gt;

&lt;p&gt;My colleague: "I have no idea. I'll check it now."&lt;/p&gt;

&lt;p&gt;Me: "Thank you. I'll check it too."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;investigating -&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My colleague: "We get this error when the Computer doesn't have enough memory, maybe this is the problem."&lt;/p&gt;

&lt;p&gt;Me: "Really? micro is not enough. I remember we were using most of memory in previous project."&lt;/p&gt;

&lt;p&gt;My colleague: "We can't think of other reason. Let's change the setting and try it again."&lt;/p&gt;

&lt;p&gt;Me: "OK! I'll try."&lt;/p&gt;

&lt;p&gt;My colleague: "By the way, have you change the EC2 setting? I am scared because I have never done it."&lt;/p&gt;

&lt;p&gt;Me: "Don't worry. I have done it before. It was not complicated and quick. You can only stop the instance and change the setting."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working -&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Me: "Oh. It's not working."&lt;/p&gt;

&lt;p&gt;My colleague: "We got same error. Let's upgrade instance size more."&lt;/p&gt;

&lt;p&gt;Me: "Sure. Let's try medium."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working -&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Me: "Yeah! It's working now!"&lt;/p&gt;

&lt;p&gt;My colleague: "We finally fix it."&lt;br&gt;
f&lt;br&gt;
Me: "I avoid unstable version of Node.js. I think it is best to use latest version in case of Laravel, but Node.js is not like that.&lt;br&gt;
I will only use Node.js LTS version. Also, I will stop being stingy for memory and use medium for EC2 "&lt;/p&gt;

&lt;h3&gt;
  
  
  case 3．
&lt;/h3&gt;

&lt;p&gt;Me: "Shit! I got seeder error!? What's wrong??"&lt;/p&gt;

&lt;p&gt;My colleague: "It works in local."&lt;/p&gt;

&lt;p&gt;Me: "I execute it after refreshing tables, so it is not possible existing data causing this. And it works in our local environment. What's wrong?? I have no idea!"&lt;/p&gt;

&lt;p&gt;My colleague: "I'll check that."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;researching -&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Me: "I might find it! Look!"&lt;/p&gt;

&lt;p&gt;My colleague: "Oh, you found it? ... what the fuck is this!?"&lt;/p&gt;

&lt;p&gt;Me: "There are 2 seeders! One of the seeder is "Out*&lt;em&gt;D&lt;/em&gt;&lt;em&gt;oorUnitGroupSeeder", and other one is "Out&lt;/em&gt;&lt;em&gt;d&lt;/em&gt;*oorUnitGroupSeeder".&lt;br&gt;
The one has uppercase "D", other one has lower case "d"."&lt;/p&gt;

&lt;p&gt;My colleague: "Why do these files exist in a same directory??"&lt;/p&gt;

&lt;p&gt;Me: "I have no idea. Maybe, a developer pushed a file with wrong name. He realized his mistake and re-pushed it with correct name.&lt;br&gt;
If this assumption is right, it is my bad, I should have checked better."&lt;/p&gt;

&lt;p&gt;My colleague: "Which is correct?"&lt;/p&gt;

&lt;p&gt;Me: "Upper case is right. It is enough with that."&lt;/p&gt;

&lt;p&gt;My colleague:  "What is going on.? There is only 1 file in local machine."&lt;/p&gt;

&lt;p&gt;Me: "Maybe, we both use Windows. Widows can't distinguish upper case and lower case of file name.&lt;br&gt;
Then, when we run git clone, Windows controls it.&lt;br&gt;
So, we have only 1 file, and we can execute without errors."&lt;/p&gt;

&lt;p&gt;My colleague: "I see.&lt;br&gt;
....By the way, how to fix it? Windows only have 1 file, so we can't fix it."&lt;/p&gt;

&lt;p&gt;Me: "I'll use Mac and push it. Give me a second.&lt;br&gt;
We could edit the source code directory in EC2. But, it might cause annoying task at next deploy.&lt;br&gt;
It is not difficult task, I'll do it."&lt;/p&gt;

&lt;h3&gt;
  
  
  case 4．
&lt;/h3&gt;

&lt;p&gt;Me: "CORS error never disappear! What's wrong!?"&lt;/p&gt;

&lt;p&gt;My colleague: "We have investigated everything we could come up with. Why?"&lt;/p&gt;

&lt;p&gt;Me: "We have demo for the client tomorrow. Why we face such so many errors only today!"&lt;/p&gt;

&lt;p&gt;My colleague: "What do we do with it?"&lt;/p&gt;

&lt;p&gt;Me: OK! Let's disable CORS."&lt;/p&gt;

&lt;p&gt;My colleague: "Are you sure?"&lt;/p&gt;

&lt;p&gt;Me: "Yes. I am sure. No problem. I fix it immediately after demo. It is too late, we have to focus on making it work rather than investigating."&lt;/p&gt;

&lt;p&gt;My colleague: "How do we disable CORS?"&lt;/p&gt;

&lt;p&gt;Me: "We can only comment out this middleware. we gotta pull through."&lt;/p&gt;

&lt;p&gt;My colleague: "Really? you edit the source code directly?"&lt;/p&gt;

&lt;p&gt;Me: "We can't include this. I'll write down we must execute revert before deploy."&lt;/p&gt;

&lt;p&gt;My colleague: "It is too late. We don't have much more options."&lt;/p&gt;

&lt;p&gt;Me: "...OK! Maybe it will work."&lt;/p&gt;

&lt;p&gt;My colleague: "Hey! I found an another error!"&lt;/p&gt;

&lt;h3&gt;
  
  
  case 5．
&lt;/h3&gt;

&lt;p&gt;My colleague: "I can't log in! What's wrong!?"&lt;/p&gt;

&lt;p&gt;Me: No idea. I found that user is registered.&lt;/p&gt;

&lt;p&gt;My colleague: "Let me see... Oh! I found the error."&lt;/p&gt;

&lt;p&gt;Me: It looks like some backend errors.&lt;/p&gt;

&lt;p&gt;My colleague: "OK! Let's investigate together. I will check nginx logs. Please check Laravel logs."&lt;/p&gt;

&lt;p&gt;Me: "Sure!"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;investigating -&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Me: "I got it! It is a permission problem. It couldn't write laravel.log."&lt;/p&gt;

&lt;p&gt;My colleague: "Great. Please fix it."&lt;/p&gt;

&lt;p&gt;Me: "OK! ...Yeah! I could log in!"&lt;/p&gt;

&lt;h3&gt;
  
  
  case 6．
&lt;/h3&gt;

&lt;p&gt;Me: "Phew. We finally finished the deploy. The frontend app works with PM2, and it is stable now.&lt;br&gt;
Hey! Look at what time we started talk. It has been 4 hours."&lt;/p&gt;

&lt;p&gt;My colleague: "I'm exhausted."&lt;/p&gt;

&lt;p&gt;Me: "Thank you for implementing PM2. I did't tell you, I needed to run this using "npm run dev"."&lt;/p&gt;

&lt;p&gt;My colleague: "Are you kidding?"&lt;/p&gt;

&lt;p&gt;Me: "No. While the demo app running, I restarted it manually when some errors happened. I had my console on side screen."&lt;/p&gt;

&lt;p&gt;My colleague: "What were you doing? lol"&lt;/p&gt;

&lt;p&gt;Me: "I didn't have other options. Complain to your frontend leader if you have any. I didn't have time to care about it.&lt;br&gt;
He is always on unimportant tasks, and run away from critical issues. Every single time he found tiny error and insist that "it it serious problem".&lt;br&gt;
I'm struggling to get his progress."&lt;/p&gt;

&lt;p&gt;My colleague: "I have heard about it. I don't know the details because I joined the project recently."&lt;/p&gt;

&lt;p&gt;Me: "He dump all frontend technical issues on me. Actually, it didn't even build until last week.&lt;br&gt;
I told him that we have demo soon, but he let it cooked."&lt;/p&gt;

&lt;p&gt;(It was a total chaos. I wrote why this happens in this article. To sum up, we had an engineer who might fake his CV.  )&lt;br&gt;
&lt;a href="https://kaki-engine.com/bad-agent/" rel="noopener noreferrer"&gt;【システム開発】タチの悪いエージェントの地雷を踏んだ時、被害を最小限に抑える方法を考えてみた&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summery
&lt;/h2&gt;

&lt;p&gt;It seems we are having extremely pointless conversations, but if you have worked as an infrastructure engineer, you have faced similar situation without letting other members know.&lt;br&gt;
Right? I know you have.&lt;/p&gt;

&lt;p&gt;Like that, I believe it is very effective to use pair programming in infrastructure jobs.&lt;br&gt;
When I take over this kind of job, I will ask them "I want you to explain it with sharing screen, because of these reasons. "&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The most effective Schema-Driven Development using OpenAPI for Logistic Engineer</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sat, 09 Dec 2023 16:15:09 +0000</pubDate>
      <link>https://dev.to/kakisoft/the-most-effective-schema-driven-development-using-openapi-for-logistic-engineer-3603</link>
      <guid>https://dev.to/kakisoft/the-most-effective-schema-driven-development-using-openapi-for-logistic-engineer-3603</guid>
      <description>&lt;p&gt;In web application development, your team use OpenAPI document in many cases when you separate backend and frontend.&lt;/p&gt;

&lt;p&gt;But, the API specification document based on OpenAPI is written in yaml or json format. Then it is a very stressful task.&lt;/p&gt;

&lt;p&gt;Also, writing up the API document doesn't mean completing by nature. It is a very tiresome task to keep updating document as a project progress.&lt;br&gt;
(Or rather, it is common not to update at all after it is first created because of maintenance costs. And there is a big difference between actual API behavior and API document.)&lt;/p&gt;

&lt;p&gt;There are some services to help you write API specification and visualize it graphically, but there are no standard services&lt;br&gt;
So, many developers struggle to decide what is the best approach for this project.&lt;/p&gt;

&lt;p&gt;I had a hard time in my current project too. &lt;br&gt;
After researching a lot of different services and applications, I finally found an effective service.&lt;/p&gt;

&lt;p&gt;In fact, I introduced it to my clients and my friends, then I received their good replies.&lt;/p&gt;

&lt;p&gt;Let me get straight to the point.&lt;br&gt;
We decided to proceed as below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the service called "Stoplight" that helps writing OpenAPI document based on GUI. We can import/export yaml files.&lt;/li&gt;
&lt;li&gt;Use "Prism" as a mock server. We can use yaml file as it is and launch using only one command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the details to decide to use services above.&lt;/p&gt;
&lt;h2&gt;
  
  
  Development Environment
&lt;/h2&gt;

&lt;p&gt;For frontend, We hired a software vendor that specializes in drawing complicated map.&lt;/p&gt;

&lt;p&gt;Our team is in charge of backend.&lt;/p&gt;

&lt;p&gt;Main function of backend is done, but API for the vendor has not been touched, neither API design.&lt;/p&gt;

&lt;p&gt;In short, backend anf frontend has not been started yet.&lt;br&gt;
The rough requirement is already specified. Our team will decide the details.&lt;/p&gt;

&lt;p&gt;We will make new function from scratch, so there are no mock server neither infrastructure ready.&lt;/p&gt;

&lt;p&gt;It is required to show a lot of information on the map.&lt;br&gt;
But, we have no idea what data is necessary, what is the suited data format.&lt;br&gt;
It means, we should collaborate with the vendor.&lt;/p&gt;

&lt;p&gt;Therefore, we should't give tasks without specification document. &lt;/p&gt;
&lt;h2&gt;
  
  
  About the adapted services
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1．Stoplight
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://stoplight.io/" rel="noopener noreferrer"&gt;https://stoplight.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It helps writing OpenAPI document based on GUI.&lt;/p&gt;

&lt;p&gt;You would understand better with images rather than reading explanations.&lt;br&gt;
*It is sample API document of pet store from OpenAPI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2etvpq5kqq96s1neleo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2etvpq5kqq96s1neleo.png" alt=" " width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd59ox59esoprq9s2v6am.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd59ox59esoprq9s2v6am.png" alt=" " width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those familiar with API, you can intuitively understand it.&lt;/p&gt;

&lt;p&gt;As you can see, you can edit endpoints, HTTP methods, query parameters, and response parameters based on GUI.&lt;/p&gt;

&lt;p&gt;As an additional outstanding feature, you can use it as yaml file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh49tksnxhbajwbxu6wv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh49tksnxhbajwbxu6wv2.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The generated yaml file can be executed with other OpenAPI plugins.&lt;br&gt;
(This image is when using VSCope plugin "&lt;a href="https://marketplace.visualstudio.com/items?itemName=42Crunch.vscode-openapi" rel="noopener noreferrer"&gt;OpenAPI (Swagger) Editor&lt;/a&gt;")&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmv43otut0zqwci8zq73t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmv43otut0zqwci8zq73t.png" alt=" " width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kvxaghrl66mw0mibg5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kvxaghrl66mw0mibg5k.png" alt=" " width="390" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is possible to not only export yaml file but also import yaml file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8giw6esppv5d0xdfg19g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8giw6esppv5d0xdfg19g.png" alt=" " width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is free to use by yourself, but you can also share with other developers by subscribing paid plan &lt;/p&gt;
&lt;h3&gt;
  
  
  2．Prism
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://stoplight.io/open-source/prism" rel="noopener noreferrer"&gt;https://stoplight.io/open-source/prism&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In short, "The application that let user use yaml file as a mock server."&lt;/p&gt;

&lt;p&gt;You can intuitively understand it with an image too.&lt;/p&gt;

&lt;p&gt;As below, by specifying yaml file in command line and executing, the mock server will be launched. ( "-p" is port number)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jxym6t4aqiaeavf2s4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jxym6t4aqiaeavf2s4h.png" alt=" " width="800" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the result of executing with curl command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45m4jewzux0l51a6xyak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45m4jewzux0l51a6xyak.png" alt=" " width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As above, you can easily launch mock server without preparing source code and execution environment.&lt;/p&gt;

&lt;p&gt;It is incredibly fantastic application, and even more, you can install it very easily with "npm install" command.&lt;/p&gt;

&lt;p&gt;The sample command is here.&lt;br&gt;
(Please refer to the official document for details.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// install
npm install -g @stoplight/prism-cli

// Start mock server from yaml file
prism mock swagger-petstore.yaml -p 4010
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I install it globally in my local machine, because it doesn't clutter your environment and doesn't required strict node version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation of the process
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create API speciation in yaml file using Stoplight based on GUI.&lt;/li&gt;
&lt;li&gt;Share it with the vendor in GitHub repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The API document generated by Stoplight is based on OpenAPI standard, so there is no strict requirement to use Stoplight as viewer.&lt;br&gt;
The vendor can use their preferred applications.&lt;/p&gt;

&lt;p&gt;About launching mock server, write README file that "Use the application 'Prism'. Here is how to install and execute."&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback from the client
&lt;/h2&gt;

&lt;p&gt;I proposed these applications and this approach. The client repose was favorable and told me "It's a good idea! Let's introduce it to other members!".&lt;br&gt;
So, I presented to other development team.&lt;/p&gt;

&lt;p&gt;I got positive feedback too, we decided to use it for other projects.&lt;/p&gt;

&lt;p&gt;It is not necessary to use Stoplight, but the feature of Prism where "let user use yaml file as a mock server" is truly remarkable.&lt;br&gt;
It is worth considering its adaption.&lt;/p&gt;

&lt;p&gt;We haven't started development with the vendor yet, so we will get the result later.&lt;br&gt;
I will update the information.&lt;/p&gt;

</description>
      <category>api</category>
      <category>openapi</category>
      <category>schemedrivendevelopment</category>
      <category>sdd</category>
    </item>
    <item>
      <title>Docker/PHP - What is the most prioritized timezone setting?</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sun, 09 Apr 2023 16:03:36 +0000</pubDate>
      <link>https://dev.to/kakisoft/dockerphp-what-is-the-most-prioritized-timezone-setting-4bk6</link>
      <guid>https://dev.to/kakisoft/dockerphp-what-is-the-most-prioritized-timezone-setting-4bk6</guid>
      <description>&lt;p&gt;When you use Docker &amp;amp; PHP, you can set timezone to many places.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;php.ini&lt;/strong&gt;&lt;br&gt;
example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Date]&lt;/span&gt;
&lt;span class="py"&gt;date.timezone&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Europe/Madrid"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;br&gt;
example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM php:8.1.12-fpm

ENV TZ=America/Los_Angeles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;br&gt;
example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  php:
    container_name: php
    build: ./containers/php
    volumes:
      - ./src:/var/www/src:cached
    working_dir: /var/www/src
    environment:
      TZ: Asia/Tokyo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It depends on project where the value is set.&lt;/p&gt;

&lt;p&gt;I wondered what is the most prioritized timezone setting if I set all of places differently.&lt;/p&gt;

&lt;p&gt;Here is a source code that I used to research.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="nv"&gt;$defaultTimezone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;date_default_timezone_get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$defaultTimezone&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. define 3 places, php.ini, Dockerfile and docker-compose.yml
&lt;/h2&gt;

&lt;p&gt;Result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string(13) "Europe/Madrid"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dockerfile and docker-compose.yml definitions were ignored and php.ini definition was reflected.&lt;br&gt;
It seems like php.ini definition is the most prioritized.&lt;/p&gt;

&lt;p&gt;Next, remove php.ini definition and execute.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. define 2 places Dockerfile and docker-compose.yml
&lt;/h2&gt;

&lt;p&gt;Result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string(3) "UTC"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? UTC appeared which is not defined anywhere.&lt;/p&gt;

&lt;p&gt;So, I checked OS timezone setting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ timedatect
bash: timedatect: command not found

$ echo $TZ
Asia/Tokyo

$ cat /etc/timezone
Etc/UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each command showed different result such as "Asia/Tokyo" and "Etc/UTC". It is a bit confusing.&lt;/p&gt;

&lt;p&gt;After researching I found out that timezone setting will not be reflected to PHP setting only by defining environment valuable "TZ" in Dockerfile.&lt;br&gt;
If you want to use OS timezone, you have to define in tzone.ini.&lt;/p&gt;

&lt;p&gt;So, I edited Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &amp;amp;&amp;amp; echo $TZ &amp;gt; /etc/timezone
RUN printf '[Date]\ndate.timezone="%s"\n', $TZ &amp;gt; /usr/local/etc/php/conf.d/tzone.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the result of PHP code execution, timezone setting in Dockerfile is reflected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string(19) "America/Los_Angeles"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/etc/timezone will be updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat /etc/timezone
America/Los_Angeles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. define 1 places docker-compose.yml
&lt;/h2&gt;

&lt;p&gt;Result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string(3) "UTC"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is same as I expected because tzone.ini is not set.&lt;/p&gt;

&lt;p&gt;Just in case, check OS timezone setting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ timedatect
bash: timedatect: command not found

$ echo $TZ
Asia/Tokyo

$ cat /etc/timezone
Etc/UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not practical to define the setting in docker-compose.yml as section "2", so, if you need to set timezone, you should set in other places.&lt;/p&gt;

&lt;p&gt;Sometimes I found timezone setting as "TZ: UTC" in docker-compose.yml, this setting may not be working, but actually default timezone setting is working.&lt;/p&gt;

&lt;p&gt;However, you can reflect timezone setting of docker-compose.yml by stating as below in php.ini.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Date]
date.timezone = ${TZ}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(note) It is necessary to set php.ini in the container.&lt;/p&gt;

&lt;p&gt;Then, the timezone setting of docker-compose.yml is reflected.&lt;br&gt;
Here is the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string(10) "Asia/Tokyo"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Timezone of Dockerfile reflects to only OS but not to PHP. It is necessary to set tzone.ini.&lt;/li&gt;
&lt;li&gt;It is too much work, I personally recommend to set timezone in php.ini.&lt;/li&gt;
&lt;li&gt;If you want timezone as variable, set docker-compose.yml and pass to php.ini.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you face to such a situation "Where is the timezone set in this project?", I recommend check "php.ini" first, after that "docker-compose.yml" lastly "Dockerfile".&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra
&lt;/h2&gt;

&lt;p&gt;You can overwrite timezone using "date_default_timezone_set".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="nb"&gt;date_default_timezone_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Australia/Sydney'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$defaultTimezone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;date_default_timezone_get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$defaultTimezone&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string(16) "Australia/Sydney"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>docker</category>
      <category>php</category>
    </item>
    <item>
      <title>Docker/Alpine - Why you should avoid alpine linux</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Wed, 05 Apr 2023 11:16:59 +0000</pubDate>
      <link>https://dev.to/kakisoft/dockeralpine-why-you-should-avoid-alpine-linux-44he</link>
      <guid>https://dev.to/kakisoft/dockeralpine-why-you-should-avoid-alpine-linux-44he</guid>
      <description>&lt;p&gt;Have you ever heard OS called Alpine Linux?&lt;/p&gt;

&lt;p&gt;It is very light weight, and not Debian or RedHat distribution.&lt;/p&gt;

&lt;p&gt;The official website is here.&lt;br&gt;
&lt;a href="https://www.alpinelinux.org/" rel="noopener noreferrer"&gt;https://www.alpinelinux.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because of this characteristic, it can be adapted docker container base image.&lt;/p&gt;

&lt;p&gt;You can check out the container from Docker Hub, here.&lt;br&gt;
&lt;a href="https://hub.docker.com/_/alpine" rel="noopener noreferrer"&gt;https://hub.docker.com/_/alpine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have adapted it in some projects at work and personal project.&lt;br&gt;
We found too many disadvantages, I would like propose to reconsider adapting Alpine for actual product.&lt;/p&gt;

&lt;p&gt;As far as I am concerned, the cases where you can take advantage of Alpine are very limited, and many projects will find more disadvantages rather than the benefits.&lt;/p&gt;

&lt;p&gt;Here is the list of reasons why you should avoid alpine linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  It uses unpopular package manager "apk"
&lt;/h2&gt;

&lt;p&gt;It is common to use "yum" or "apt" as Linux package manager, or "Composer" or "pecl" as PHP package manager.&lt;/p&gt;

&lt;p&gt;We often finish it after many struggles like reconfiguring package reference to install preferred version of libraries for the project, and adding other package managers such as "remi", "EPEL" and "pickle" over and over again.&lt;/p&gt;

&lt;p&gt;It is important that "the problem can be solve easily" because you have to manage many package managers and set different configurations.&lt;/p&gt;

&lt;p&gt;In particular, how easy we can find the solution is the key for development.&lt;/p&gt;

&lt;p&gt;apk is not popular at all compared with yum and apt as package manager, it means there are few information on the internet.&lt;br&gt;
So, it makes complicated to solve the problem.&lt;/p&gt;

&lt;p&gt;There are some cases that you face difficult problems with yum, apk spur difficulty on to solve errors.&lt;/p&gt;

&lt;p&gt;It doesn't matter for the quality of product how difficult to build development environment, it is the best way to simplify.&lt;/p&gt;

&lt;p&gt;In addition, file extension of Android app is "apk" as well, so you will get more search result about Android app.&lt;br&gt;
Then you will be struggling with filtering these result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some library versions are not updated
&lt;/h2&gt;

&lt;p&gt;If you install some libraries using apk, there is high possibility that you can't install latest version(they may not be supported by apk).&lt;/p&gt;

&lt;p&gt;In this case, you may need to get and compile source code.&lt;/p&gt;

&lt;p&gt;This task will absorb your motivation.&lt;/p&gt;

&lt;p&gt;This is totally waste of your time to have a headache for issue that is easily solved by other package manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  It uses unpopular shell "ash"
&lt;/h2&gt;

&lt;p&gt;Alpine adapts unpopular shell "ash", it makes difficult to create development environment.&lt;/p&gt;

&lt;p&gt;By the way, I use default OS shell without any customization.(Well, I set some alias.)&lt;/p&gt;

&lt;p&gt;I want to avoid to make it even more difficult to create development environment by adding some customization to the shell.&lt;/p&gt;

&lt;p&gt;There was a period a shell called "fish" got attention, however, I completely ignore that trend and kept using default shell.&lt;br&gt;
Because, I believe that "The number of disadvantages by customizing the shell &amp;gt; The number of advantages by customizing the shell" in most cases.&lt;/p&gt;

&lt;p&gt;I do understand the advantages by customizing the shell, but sometimes it might make confusing issue when you create development environment.&lt;/p&gt;

&lt;p&gt;It is okay if you use customized shell that you perfectly understand all parameters and behaviors. However, if you use the shell that other developer customized, you might face some extra unexpected issues.&lt;/p&gt;

&lt;p&gt;Using unpopular shell means you will face similar issues.&lt;/p&gt;

&lt;p&gt;In addition, "ash" has low google-ability such as "apk". So, when you face unexpected issues, you will be struggling.&lt;/p&gt;

&lt;h2&gt;
  
  
  It uses unpopular distribution.
&lt;/h2&gt;

&lt;p&gt;First of all, if you use unpopular distribution, you often face unexpected tough issues.&lt;/p&gt;

&lt;p&gt;This article is about some unpopular distributions which I gave a try.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kakistamp.com/entry/2017/06/05/013635" rel="noopener noreferrer"&gt;Linux - The report of unpopular distributions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I finally decided to go with Ubuntu.&lt;/p&gt;

&lt;p&gt;It is better to use popular distribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Dockerfile tend to depend on each engineer's skill
&lt;/h2&gt;

&lt;p&gt;It can be difficult to create Dockerfile because of reasons above.&lt;/p&gt;

&lt;p&gt;It uses unpopular package manager and unpopular shell, and sometimes it is required stressful knowledge that you think it is a waste.&lt;br&gt;
Technical debt increase when we use Alpine rather than Debian or RedHat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The performance is low compared with other distributions.(it can be happened)
&lt;/h2&gt;

&lt;p&gt;I found this interesting article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.inductor.me/entry/alpine-not-recommended" rel="noopener noreferrer"&gt;軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話(You shouldn't use Alpine for lightweight Docker image without particular reason)&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;libcに一般的な互換性が不足しているからです。Ruby、Python、Node.jsなどでNativeモジュールをバンドルしているアプリケーションの場合、パフォーマンスの劣化や互換性の問題にぶち当たる場合があります。&lt;br&gt;
(libc is lacking general compatibility. When application uses native module bundle such as Ruby, Python, and Node.js, you might face the problem of performance or compatibility.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have made a React development environment in Alpine Docker image, however, the command "npm run watch" and "watch-poll" are too heavy and slow, which makes inconvenient to develop.&lt;br&gt;
(But, the problem might be caused by the way I build. Fortunately it was only my personal project, so I left it like that.)&lt;/p&gt;

&lt;p&gt;I used the development environment which had node-slims(node:16-slims) base image, the performance was OK.&lt;/p&gt;

&lt;p&gt;To calculate these performance precisely, I have to prepare two exactly same environment with Alpine and node-slims.&lt;br&gt;
But I'm not going to do it. I wait for the engineers who recommend Alpine prove Alpine has high performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  There will be chaotic incident research after production.
&lt;/h2&gt;

&lt;p&gt;When you use AWS service such as Fargate or ECS, you can deploy the containers without installing some applications and libraries in EC2.&lt;/p&gt;

&lt;p&gt;But, it is common to face some problems that occurs in production or staging environment, but not local one.&lt;br&gt;
In this case you will want to login the container directly to find out.&lt;br&gt;
(Sometimes, you find some article state "When you use container, there are no difference between local and production environment, so, you don't worry about difference of these". Truth be told, while local environment doesn't use AWS resources, production environment use it such as RDS, ElastiCache, SQS and SES. if any kind of error has been produced in the connection or configuration, your application will not work properly.)&lt;/p&gt;

&lt;p&gt;But, when you use Fargate, you will not be able to login like EC2 SSH.&lt;br&gt;
(Internally, Fargate is managed by AWS dominant EC2. So, it is highly restricted for user access.)&lt;/p&gt;

&lt;p&gt;If you use the AWS service "ECS Exec", you can login the uploaded container in Fargate, but it is required to install the application called SSM Agent.&lt;/p&gt;

&lt;p&gt;But, Alpine has not and will not support SSM Agent. So, you have to do in an unofficial way.&lt;/p&gt;

&lt;p&gt;I found this article.&lt;br&gt;
&lt;a href="https://enomotodev.hatenablog.com/entry/2020/05/23/160731" rel="noopener noreferrer"&gt;Alpine Linux に amazon-ssm-agent をインストールする(How to install amazon-ssm-agent in Alpine Linux)&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;amazon-ssm-agent は Alpine Linux をサポートする予定はないとのこと。&lt;br&gt;
(Alpine has not and will not support amazon-ssm-agent.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is possible installed, but the author do in an unofficial way.&lt;/p&gt;

&lt;p&gt;I couldn't install it this way.&lt;/p&gt;

&lt;p&gt;It often happens to get different result from the author's one since we have different environment, so, we have to solve these issue depending on the error messages.&lt;br&gt;
But, it is complicated to fix some unexpected problems, because it is not easy to find right information.&lt;/p&gt;

&lt;p&gt;When the application is launched in AWS, it is very important to have access to container, there is no other way to implement output log and deploy each time.&lt;/p&gt;

&lt;p&gt;If it takes more than 20 minutes to deploy an application, we are risking engineer's motivation.&lt;/p&gt;

&lt;p&gt;If you use AWS Fargate, you have to avoid Alpine, because container login function is not supported officially.&lt;/p&gt;

&lt;h2&gt;
  
  
  It is recommended Debian image in Dockerfile best practice in official Docker documentation.
&lt;/h2&gt;

&lt;p&gt;Here is the reference from official documentation.&lt;br&gt;
&lt;a href="http://docs.docker.jp/engine/userguide/eng-image/dockerfile_best-practices.html" rel="noopener noreferrer"&gt;http://docs.docker.jp/engine/userguide/eng-image/dockerfile_best-practices.html&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In terms of base image, use the official repository for the best possible result.&lt;/p&gt;

&lt;p&gt;We recommend Debian image. It is well maintained and compact despite full-featured distribution.(Only under 150MB)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I suggest to follow best practice unless there are specific reasons to use Alpine, because official documentation said.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment time is not reduced as much as you expected.
&lt;/h2&gt;

&lt;p&gt;Truth be told, deployment time is not reduced even if you use Alpine.&lt;/p&gt;

&lt;p&gt;It is common to think it will take less to deploy because it is light weight.&lt;br&gt;
But, there are many processes to complete deployment. There is only 1 step of container upload time which get benefit from weight saving.&lt;/p&gt;

&lt;p&gt;Also, when you upload some containers to AWS, they don't upload each one of them, but upload like broadcast delivery. It seems like process in parallel, so it will not produce difference of processing time.&lt;/p&gt;

&lt;p&gt;To be specific, it doesn't mean "Deploying 100 containers takes 100 times longer than deploying 1". However both take almost same time.&lt;/p&gt;

&lt;p&gt;Therefore, the benefit from weight saving of container is only the amount when you compare each container.&lt;br&gt;
(I asked AWS specialist.)&lt;/p&gt;

&lt;p&gt;I would rather find some disadvantages which sacrifices performance instead of weight saving. &lt;/p&gt;

&lt;p&gt;Start-up time of the container might be faster, however ,most of engineers would choose&lt;br&gt;
"the container which takes 5 minutes to start up, but 1 second for 'npm run watch' command"&lt;br&gt;
over&lt;br&gt;
"the one which takes 1 minute to start up, but 1 minute for 'npm run watch' command"&lt;/p&gt;

&lt;h2&gt;
  
  
  based on these disadvantages
&lt;/h2&gt;

&lt;p&gt;I ended up writing a lot of disadvantages of Alpine unexpectedly.&lt;/p&gt;

&lt;p&gt;But, these problems can be avoided easily by not using Alpine.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you should use Alpine?
&lt;/h2&gt;

&lt;p&gt;In my opinion, development and maintenance cost will increase just by adapting Alpine.&lt;br&gt;
It is too stressful and exhausting job if there isn't infrastructure team with specialists of containers and deployment.&lt;/p&gt;

&lt;p&gt;Sometimes it is required stressful knowledge that you think it is a waste, so, it is a quite tough work for backend engineers to do at the same time.&lt;/p&gt;

&lt;p&gt;I really recommend to reconsider adapting Alpine even if you have external infrastructure specialists.&lt;br&gt;
In many case, these wasteful knowledge will not be taken over unless you notice and ask for these information.&lt;br&gt;
to keep facing technical debt is bad for your health because it is difficult to solve these issues&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;One day, I talked about Docker and building environment with an engineer. We both had a tough time using Alpine, so, we hit it off.&lt;br&gt;
Then I decided to write about it.&lt;/p&gt;

&lt;p&gt;If I have a opportunity to join a technical selection and someone propose using Alpine for container base image, I will definitely propose "NOOOO!!!! Use Debian or Debian Slim. NOT Alpine".&lt;br&gt;
The objective of article is that.&lt;/p&gt;

&lt;p&gt;You might feel this is debateable, however if you really want to use Alpine, you have to explain advantages outweigh the disadvantages listed above.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>alpine</category>
    </item>
    <item>
      <title>Docker/DB - Isn't it better to set share directory between host and db container?</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sat, 04 Feb 2023 14:38:48 +0000</pubDate>
      <link>https://dev.to/kakisoft/dockerdb-isnt-it-better-to-set-share-directory-between-host-and-db-container-1kcj</link>
      <guid>https://dev.to/kakisoft/dockerdb-isnt-it-better-to-set-share-directory-between-host-and-db-container-1kcj</guid>
      <description>&lt;p&gt;After development, I came up with an idea during application maintenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;"Isn't it better to set share directory between host and db container?"&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;mysql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:8.0.29&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp01&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3306:3306"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mysql-data:/var/lib/mysql&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./shared_db:/shared_db&lt;/span&gt;  &lt;span class="c1"&gt;# set share directory between host and db container&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason is &lt;strong&gt;After lunching the service, make it easy to import dump file in local environment from production environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, there are many case you want to test out with same environment data as production, because the error could not be reproduced in local environment, but in the specific occasion.&lt;/p&gt;

&lt;p&gt;In this case, you have to import dump file which has been exported from production environment or periodical batch.&lt;/p&gt;

&lt;p&gt;But, sometimes this task can be very annoying and complicated.&lt;/p&gt;

&lt;p&gt;These day, It is common to allow user to use many variety of OS such as Mac, Windows or Linux without specifying machine for development.&lt;br&gt;
Also, the virtual machine technology like docker helps us achieve it.&lt;/p&gt;

&lt;p&gt;In this case, to execute import command in the container(MySQL, PostgresSQL or other DB), it is necessary to store dump file somewhere you can refer from the container.&lt;br&gt;
(There might be better approach that specify dump file in the host, I couldn't find it.)&lt;/p&gt;

&lt;p&gt;If you share the file between host and container, you need to prepare some protocols or use shared storage that both can refer.&lt;/p&gt;

&lt;p&gt;Other approach is executing import command in the host, but shell in the host will drive you crazy.&lt;/p&gt;

&lt;p&gt;Especially, PowerShell is special in many ways. For example you can't use the character "&amp;lt;" because it is the reserved word.&lt;br&gt;
So, you have find the way to avoid this problem.&lt;br&gt;
(When I solve the problem, it is necessary to store the file in the container to refer. It was a waste of time.)&lt;/p&gt;

&lt;p&gt;Other way is using DB client application such as MySQL Workbench. But, there are differences in each OS, also operation is different even in same application. Then it is annoying to share this information with your team.&lt;/p&gt;

&lt;p&gt;From the beginning, even thought we are using virtualization software such as Docker which let us ignore host environment of each developers, it is not a efficient way to have different operations depending on the OS of each developers.&lt;/p&gt;

&lt;p&gt;Also, if you successfully execute import command, after you will be struggle with error related to character code.&lt;/p&gt;

&lt;p&gt;I wrote about research including failed example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kakisoft/mysqlwindowsdocker-how-to-import-a-dump-file-to-mysql-container-16p9"&gt;MySQL/Windows/Docker - How to import a dump file to MySQL container&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The clear solution is &lt;strong&gt;&lt;em&gt;"Set share directory between host and db container"&lt;/em&gt;&lt;/strong&gt; which I suggested in the beginning.&lt;/p&gt;

&lt;p&gt;This makes your explanation clearly and shorter when you need to teach developers how to import dump file in their local environment.&lt;br&gt;
You can only tell them "Store the file in the shared directory between the DB container and the host, and execute the import command from inside the container."&lt;/p&gt;

&lt;p&gt;I believe this is the best way. It doesn't get affected by shell differences or host OS.&lt;/p&gt;

&lt;p&gt;In addition, no matter how much developers edit docker-compose.yml ,it affects only their local environment.&lt;br&gt;
It can be resolved without any negative impact on the production or staging environment.&lt;/p&gt;

&lt;p&gt;However, I have never seen anyone claiming something like mine, and if I put the above setting in docker-compose.yml, I would be asked, "What is this setting for?" ,&lt;br&gt;
so I decided to post it on this blog because I wanted to explain how it is useful and how much problems I faced when I didn't include these settings.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>announcement</category>
      <category>community</category>
    </item>
    <item>
      <title>MySQL/Windows/Docker - How to import a dump file to MySQL container</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Thu, 02 Feb 2023 19:18:37 +0000</pubDate>
      <link>https://dev.to/kakisoft/mysqlwindowsdocker-how-to-import-a-dump-file-to-mysql-container-16p9</link>
      <guid>https://dev.to/kakisoft/mysqlwindowsdocker-how-to-import-a-dump-file-to-mysql-container-16p9</guid>
      <description>&lt;p&gt;&lt;strong&gt;&amp;lt; environment &amp;gt;&lt;/strong&gt;&lt;br&gt;
OS : Windows&lt;br&gt;
DB : MySQL&lt;br&gt;
virtualization software ： Docker&lt;br&gt;
shell ： PowerShell / git bash / command prompt&lt;/p&gt;

&lt;p&gt;I tried import to MySQL container on Windows using dump file, it was a really tough job.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to export dump file using PowerShell command (execute from outside of container)
&lt;/h2&gt;

&lt;p&gt;When you get MySQL dump file from outside of container, the command is like this.&lt;/p&gt;

&lt;p&gt;I have a MySQL container named "mysql".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose exec mysql mysqldump --user=root --password=password myapp01 &amp;gt; dump_file_20221119.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To execute, replace "--user" and "--password" in your environment.&lt;br&gt;
And the scheme is "myapp01".&lt;/p&gt;

&lt;p&gt;After executing this command, dump_file_20221119.sql will be created.&lt;br&gt;
There is no problem so far.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to import dump file
&lt;/h2&gt;
&lt;h3&gt;
  
  
  PowerShell (execute from outside of container) [failed]
&lt;/h3&gt;

&lt;p&gt;I tried the most basic import command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\kaki\work&amp;gt; docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
発生場所 行:1 文字:90
+ ... ql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_fi ...
+                                                                 ~
演算子 '&amp;lt;' は、今後の使用のために予約されています。
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RedirectionNotSupported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can't use the character '&lt;code&gt;&amp;lt;&lt;/code&gt;' in PowerShell.&lt;/p&gt;

&lt;p&gt;I looked up how do I make the character escape, but there is no way to do that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Reference)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-7.3" rel="noopener noreferrer"&gt;about Special Characters - PowerShell | Microsoft Learn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I tried "&amp;lt;" and "&amp;lt;", it didn't work.&lt;/p&gt;
&lt;h3&gt;
  
  
  PowerShell (execute from outside of container - other command) [failed]
&lt;/h3&gt;

&lt;p&gt;When you execute import command, you can use '-e' option instead of the character '&lt;code&gt;&amp;lt;&lt;/code&gt;'.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Reference)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.mysql.com/doc/refman/5.6/en/mysqldump.html" rel="noopener noreferrer"&gt;MySQL :: MySQL 5.6 Reference Manual :: 4.5.4 mysqldump — A Database Backup Program&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(example)&lt;br&gt;
shell&amp;gt; mysql -e "source /path-to-backup/backup-file.sql" db_name&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, I tried :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose exec mysql mysql --user=root --password=password -e "source dump_file_20221119.sql" myapp01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR at line 1: Failed to open file 'dump_file_20221119.sql'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found out that the "-e" option only target files inside the container.&lt;/p&gt;

&lt;p&gt;I tried store the dump file in the container and execute the command, it recognized the file.&lt;/p&gt;

&lt;p&gt;Although, the error occurred.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR: ASCII '\0' appeared in the statement, but this is not allowed unless option --binary-mode is enabled and mysql is run in non-interactive mode. Set --binary-mode to 1 if ASCII '\0' is expected. Query: '��m'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cause is that PowerShell default character code is CP932(SJIS).&lt;/p&gt;

&lt;p&gt;(Note)&lt;br&gt;
The writer is Japanese.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Reference)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://qiita.com/hideshis/items/38f48c56a6353cfa8a67" rel="noopener noreferrer"&gt;How to export dump file on Windows, import it to Ubuntu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I thought if "binary-mode" was set "1", it would work.&lt;br&gt;
But, it didn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Reference)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.mysql.com/doc/refman/5.6/en/mysql-command-options.html" rel="noopener noreferrer"&gt;mysql Client Options&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Execute command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose exec mysql mysql --user=root --password=password -e "source dump_file_20221119.sql" myapp01 --binary-mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'source dump_file_20221119.sql' at line 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I google the word "binary-mode" option, I found "--binary-mode=1" and "binary-mode 0".&lt;br&gt;
But, I did't understand quite well. (I tried them, but I got errors)&lt;/p&gt;

&lt;p&gt;I'm not sure why there are so many different statement. Anyway, I refer the one from official website.&lt;/p&gt;

&lt;p&gt;But, if I solve the problem, I have to set the file in the container. So, it is not an efficient approach.&lt;/p&gt;

&lt;p&gt;When I export using MySQL Workbench appended command, I could successfully import without mentioned errors.&lt;/p&gt;

&lt;p&gt;The command is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;export using MySQL Workbench appended command&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;amp; "C:\Program Files\MySQL\MySQL Workbench 8.0 CE\mysqldump.exe" --result-file=dump_file_20221119.sql myapp01 --user=root --password=password --host=127.0.0.1 --port=3306 --set-gtid-purged=OFF --skip-lock-tables --skip-add-locks --skip-column-statistics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shell is Powershell.&lt;br&gt;
When you execute Powershell command that contains space, the error occurred.&lt;br&gt;
So, you have to do other approach.&lt;/p&gt;

&lt;p&gt;You need to put the dump file in MySQL container.&lt;/p&gt;
&lt;h3&gt;
  
  
  Execute PowerShell script [failed]
&lt;/h3&gt;

&lt;p&gt;I thought it would work if I created PowerShell script file and executed.&lt;br&gt;
So, I tried.&lt;/p&gt;

&lt;p&gt;I created the file "dump-import.ps1".&lt;br&gt;
The file contents is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dump-import.ps1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write-Host "dump importing..."

# docker-compose exec mysql bash
docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PowerShell -ExecutionPolicy RemoteSigned .\dump-import.ps1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\kaki\work\tmp&amp;gt; PowerShell -ExecutionPolicy RemoteSigned .\dump-import.ps1
発生場所 C:\kaki\work\dump-import.ps1:4 文字:90
+ ... ql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_fi ...
+                                                                 ~
演算子 '&amp;lt;' は、今後の使用のために予約されています。
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I got exactly same error.&lt;/p&gt;

&lt;p&gt;It works the command "docker-compose exec mysql bash" correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  use git bash [failed]
&lt;/h3&gt;

&lt;p&gt;I gave up using PowerShell, so I experimented with git bash.&lt;/p&gt;

&lt;p&gt;The result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error message says use "winpty".&lt;/p&gt;

&lt;p&gt;Anyway, add "winpty" on the head of the command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Reference)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/vercel/hyper/issues/2888" rel="noopener noreferrer"&gt;the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty' · Issue #2888 · vercel/hyper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, re-execute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ winpty docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
stdin is not a tty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error message says "stdin is not a tty".&lt;/p&gt;

&lt;p&gt;I found the page after researching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rprichard/winpty/issues/166" rel="noopener noreferrer"&gt;docker-compose on wsl: stdin is not a tty · Issue #166 · rprichard/winpty&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's a long standing issue with Docker.&lt;br&gt;
The way it does terminal detection only works with cmd.exe and powershell.exe at the moment. Any third-party terminal breaks that detection and gives the message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It seems impossible to add "winpty" on the head of docker command, it is necessary to use directly powershell or cmd. (If you use Windows)&lt;/p&gt;

&lt;p&gt;As a side note, you can check out about "winpty" here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mseeeen.msen.jp/what-does-winpty-command-do/" rel="noopener noreferrer"&gt;[Git Bash] winpty コマンドについて調べてみた([Git Bash] About winpty)&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"winpty" command is interface to interact between Windows console program and UNIX virtual terminal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  use command prompt [failed]
&lt;/h3&gt;

&lt;p&gt;So, I used cmd.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\kaki\work&amp;gt;docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I re-execute the command with "winpty" on the head.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\kaki\work\ryuki-prd&amp;gt;winpty docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 &amp;lt; dump_file_20221119.sql
'winpty' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It didn't work.&lt;/p&gt;

&lt;h3&gt;
  
  
  execute the command inside container [success(But, inefficient)]
&lt;/h3&gt;

&lt;p&gt;I tried to execute import command after entering the container.&lt;/p&gt;

&lt;p&gt;It is necessary to set share directory between host and container.&lt;br&gt;
The example is here :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;mysql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:5.7&lt;/span&gt;

&lt;span class="c1"&gt;# (omission)&lt;/span&gt;

    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db-data:/var/lib/mysql&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./shared_db:/shared_db&lt;/span&gt;  &lt;span class="c1"&gt;# set share directory between host and container&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store exported dump file in "shared_db" directory, after login mysql container.&lt;/p&gt;

&lt;p&gt;And execute import command in "shared_db" directory inside of the container.&lt;/p&gt;

&lt;p&gt;Drawback : Need to rebuild container. annoying.&lt;/p&gt;

&lt;p&gt;Also, it is not suitable at all to edit docker-compose.yml and rebuild container only to import dump file.&lt;/p&gt;

&lt;h2&gt;
  
  
  use MySQL Workbench. [success]
&lt;/h2&gt;

&lt;p&gt;After this long research, I recommend using MySQL Workbench to import dump file to MySQL container on Windows.&lt;/p&gt;

&lt;p&gt;There is a annoying error about character encoding when I import the dump file with the command above.&lt;br&gt;
So, it is better to use MySQL Workbench to export.&lt;/p&gt;

&lt;h3&gt;
  
  
  MySQL Workbench：export
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Server -&amp;gt; Data Export
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnz4sbnjmqv7p0iyqxwmv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnz4sbnjmqv7p0iyqxwmv.png" alt="sqlworkbench01" width="513" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2．Start Export
&lt;/h4&gt;

&lt;p&gt;Select the schema to export. ("myapp01" in the image.)&lt;/p&gt;

&lt;p&gt;Select Export Self-Contained File.&lt;br&gt;
(If you don't check the option, the dump files will be created for each tables, which create disaster in your file system.)&lt;/p&gt;

&lt;p&gt;Set export file name.&lt;/p&gt;

&lt;p&gt;After click "Start Export" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vi4413ggqh0gsnn518k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vi4413ggqh0gsnn518k.png" alt="sqlworkbench02" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Data export complete
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2yn7kdil2pg814sqibp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2yn7kdil2pg814sqibp.png" alt="sqlworkbench03" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MySQL Workbench：import
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1．Delete existing schema
&lt;/h4&gt;

&lt;p&gt;delete the schema to import "myapp01".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpa7x7c079mks2tanri5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpa7x7c079mks2tanri5.png" alt="sqlworkbench04" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create schema
&lt;/h4&gt;

&lt;p&gt;Recreate deleted schema.(myapp01)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzrkap3nej5e40lnfpo7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzrkap3nej5e40lnfpo7.png" alt="sqlworkbench05" width="463" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set the name, and click "Apply".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9kswncwsrib9s0gaxv0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9kswncwsrib9s0gaxv0t.png" alt="sqlworkbench06" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can leave Algorithm and Lock Type as default.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkv4yjif56nk3id8uof64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkv4yjif56nk3id8uof64.png" alt="sqlworkbench07" width="783" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scheme will be created.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldse0t9ext2pyy7uj4y7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldse0t9ext2pyy7uj4y7.png" alt="sqlworkbench08" width="543" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Server -&amp;gt; Data Import
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft1m62jjqssr3zfmm100w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft1m62jjqssr3zfmm100w.png" alt="sqlworkbench09" width="662" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4．Start Import
&lt;/h4&gt;

&lt;p&gt;Select "Import from Self-Contained File", and set export file.&lt;/p&gt;

&lt;p&gt;Set target scheme.&lt;/p&gt;

&lt;p&gt;Then, click "Start Import".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d0zsqmc8w49glat9fcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d0zsqmc8w49glat9fcl.png" alt="sqlworkbench10" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5．Import Completed
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa730z00gp8bufxq2bpb7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa730z00gp8bufxq2bpb7.png" alt="sqlworkbench11" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  observation
&lt;/h2&gt;

&lt;p&gt;I hope Powershell accepts the character "&amp;lt;".&lt;/p&gt;

</description>
      <category>docker</category>
      <category>mysql</category>
      <category>windows</category>
      <category>powershell</category>
    </item>
    <item>
      <title>Amazing Documents Converter Application 'Docurain'</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sat, 07 Jan 2023 15:34:38 +0000</pubDate>
      <link>https://dev.to/kakisoft/amazing-documents-converter-application-docurain-156d</link>
      <guid>https://dev.to/kakisoft/amazing-documents-converter-application-docurain-156d</guid>
      <description>&lt;p&gt;I would like to introduce the service document converter service 'Docurain' which I was impressed.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;(Note)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I would like to introduce one impressive service in this slide.&lt;/p&gt;

&lt;p&gt;It may seems like a sales presentation.&lt;br&gt;&lt;br&gt;
But, I just love this service. I'm not working for this company.&lt;/p&gt;

&lt;p&gt;Have you, as engineers, ever had difficult time making some documents?&lt;/p&gt;




&lt;p&gt;Today, I would introduce amazing documents converter application 'Docurain'&lt;/p&gt;

&lt;p&gt;Estimate, invoice and purchase order ...&lt;/p&gt;

&lt;p&gt;Some system is required to print these documents.&lt;/p&gt;

&lt;p&gt;It is not easy to create these functions.&lt;/p&gt;

&lt;p&gt;Every single document has totally different and unique format.&lt;/p&gt;

&lt;p&gt;Also, we have to choose an appropriate library among many others.&lt;/p&gt;

&lt;p&gt;We face many challenges to make some documents download functions.&lt;/p&gt;

&lt;p&gt;But, there is a simple solution.&lt;/p&gt;

&lt;p&gt;It is "Docurain".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo50wtdcexam2xv61k9ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo50wtdcexam2xv61k9ht.png" alt=" " width="489" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you use this service, you can be liberated from the annoying document creation tasks.&lt;/p&gt;

&lt;p&gt;There are only 2 steps to create a function for document creation using Docurain.&lt;/p&gt;

&lt;p&gt;Firstly, create the document template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5t967uhg4j187k3x8lz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5t967uhg4j187k3x8lz.png" alt=" " width="114" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is incredibly simple.&lt;br&gt;&lt;br&gt;
Only tool that you need is Excel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup6tb2prmml52ahzqfsj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup6tb2prmml52ahzqfsj.png" alt=" " width="546" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You have full control to create a complex template.&lt;/p&gt;

&lt;p&gt;There is no need of complex operation.&lt;/p&gt;

&lt;p&gt;Lastly, call the API.&lt;/p&gt;

&lt;p&gt;Specify the template, and set the parameters you want to print, and call.&lt;/p&gt;

&lt;p&gt;Of course, you can use with any computer languages.&lt;/p&gt;

&lt;p&gt;There is no need to install some specific libraries.&lt;/p&gt;

&lt;p&gt;And, there are no initial costs, monthly costs, or support costs.&lt;/p&gt;

&lt;p&gt;It costs only 5 yen per document.&lt;/p&gt;

&lt;p&gt;So, let me show you how to create documents using Docurain.&lt;/p&gt;

&lt;p&gt;First, prepare your Excel template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgp0dtco8lfwzi0qdawly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgp0dtco8lfwzi0qdawly.png" alt=" " width="397" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like this, fill with specific code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbn40jss1o1f6z5oep1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbn40jss1o1f6z5oep1e.png" alt=" " width="717" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, upload this file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3syec0xc2gfazh43ds0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3syec0xc2gfazh43ds0.png" alt=" " width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, call the API.&lt;/p&gt;

&lt;p&gt;Choose the template, and set the parameter as json object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjaynidl903upog8a93ru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjaynidl903upog8a93ru.png" alt=" " width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click execute button, document will be downloaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf8q6bgdn664p8h0qkeh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf8q6bgdn664p8h0qkeh.png" alt=" " width="745" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can create such document.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffbsbk7na3obvgian9no.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffbsbk7na3obvgian9no.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Needless to say, you can call the API from source code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7pwt56p14xm3mvmnqln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7pwt56p14xm3mvmnqln.png" alt=" " width="521" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, you can easily create document function.&lt;/p&gt;

&lt;p&gt;Why don't you make your work easy?&lt;/p&gt;

&lt;p&gt;If you want to get more information, please visit official website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docurain.jp/" rel="noopener noreferrer"&gt;https://docurain.jp/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are looking forward to hearing from the companies that find document creation frustrating.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;!!!Caution!!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me repeat that, I'm not from Docurain company neither this slide is production advertizement.&lt;/p&gt;

&lt;p&gt;It is truly truly for this event for IT engineers.&lt;/p&gt;







&lt;p&gt;Actually, I talked about this in the presentation at engineer's event.&lt;/p&gt;

&lt;p&gt;The presentation material is here.&lt;br&gt;
&lt;a href="https://kakisoft.github.io/slides/amazing-documents-converter-application-docurain-en/export/index.html" rel="noopener noreferrer"&gt;https://kakisoft.github.io/slides/amazing-documents-converter-application-docurain-en/export/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, the event website is here.&lt;br&gt;
&lt;a href="https://try-english-lt.connpass.com/event/267720/" rel="noopener noreferrer"&gt;https://try-english-lt.connpass.com/event/267720/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: This service hasn't been translated in English yet.&lt;/p&gt;

</description>
      <category>gratitude</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Laravel - PhpRedis is recommended by Redis library, but aren't there a lot of situations where it's better to use Predis?</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Sun, 23 Oct 2022 14:51:57 +0000</pubDate>
      <link>https://dev.to/kakisoft/laravel-phpredis-is-recommended-by-redis-library-but-arent-there-a-lot-of-situations-where-its-better-to-use-predis-50ea</link>
      <guid>https://dev.to/kakisoft/laravel-phpredis-is-recommended-by-redis-library-but-arent-there-a-lot-of-situations-where-its-better-to-use-predis-50ea</guid>
      <description>&lt;p&gt;&lt;strong&gt;Environment&lt;/strong&gt;&lt;br&gt;
MySQL version : 5.7&lt;br&gt;
Laravel version : 8.16.1&lt;br&gt;
PHP version : 7.4.7&lt;/p&gt;
&lt;h2&gt;
  
  
  The library when you use Redis with Laravel
&lt;/h2&gt;

&lt;p&gt;There are 2 PHP libraries when you use Redis in Laravel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/predis/predis" rel="noopener noreferrer"&gt;Predis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/phpredis/phpredis" rel="noopener noreferrer"&gt;PhpRedis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By default, composer.lock contains "predis".&lt;/p&gt;
&lt;h3&gt;
  
  
  composer.lock
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="s2"&gt;"packages"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"require-dev"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"predis/predis"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"^1.1.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"symfony/cache"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"^5.1.4"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  config\database.php
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="s1"&gt;'redis'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'client'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'REDIS_CLIENT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'phpredis'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;"predis" is not used which is contained in composer.lock.(By default config)&lt;/p&gt;

&lt;p&gt;It is necessary to install "phpredis" separately, which is contained in database.php.&lt;/p&gt;

&lt;p&gt;cf.&lt;br&gt;
phpredis couldn't be installed by composer.&lt;/p&gt;

&lt;p&gt;What is this contradiction?&lt;/p&gt;

&lt;p&gt;I wondered about it and looked it up.&lt;br&gt;
It seems like predis was supposed to be removed from the default, but it has been reconsider.&lt;br&gt;
However, they would like to suggest to use phpredis...&lt;/p&gt;

&lt;p&gt;It seems that they are still in confusion.(maybe)&lt;/p&gt;
&lt;h2&gt;
  
  
  Which should we adapt?
&lt;/h2&gt;

&lt;p&gt;There seems to be a lot of debate about which one to use, and here's what I found.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://yoshinorin.net/2019/08/28/predis-not-maintain/" rel="noopener noreferrer"&gt;PHP向けRedisクライアントのpredisを使うのは止めた方がいいです(You should not use predis, the Redis client for PHP)&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;predisはPHP向けのRedisクライアントです。&lt;br&gt;
predis is a Redis client for PHP.&lt;/p&gt;

&lt;p&gt;リポジトリを見て察しのいい方は気づいたと思うのですが、2年ぐらいメンテ（コミットすら）されていません。&lt;br&gt;
If you have a good guess and check their repository, you'll notice that it hasn't been updated (even committed) for about two years.&lt;/p&gt;

&lt;p&gt;すでにPHP7.3周りで問題が出てます。これが「どういった事情でメンテされていないのか？」「されないのではなく、できないのか？」などは誰もわからないと思いますし、もしかしたら将来的に再度メンテされる可能性はありえます。&lt;br&gt;
There is already a problem from PHP7.3. I don't think anyone knows "Why is this not being updated?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I looked up current situation, and as of September 2022, development has resumed and is active.&lt;br&gt;
&lt;a href="https://github.com/predis/predis/pulse" rel="noopener noreferrer"&gt;https://github.com/predis/predis/pulse&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, there is no concern due to development stoppage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Laravelのドキュメントにも書いてありますが、phpredis使えばいいと思います。&lt;br&gt;
It is also stated in the Laravel documentation, but I think you should use phpredis.&lt;/p&gt;

&lt;p&gt;こちらはcomposerでインストールできない（PHP拡張モジュールなので）のでpeclでインストールします。&lt;br&gt;
This can not be installed with composer (because it is a PHP extension module), so install it with pecl.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nooooooo!!!!!&lt;br&gt;
Are you serious? We're not in the Stone Age now!&lt;/p&gt;

&lt;p&gt;As expected, I thought that it was fixed now, so I looked at the official PhpRedis installation guide on the official website.&lt;br&gt;
But, there is a message without a dream or hope to use pecl.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown" rel="noopener noreferrer"&gt;https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I found also this.&lt;br&gt;
&lt;a href="https://github.com/phpredis/phpredis/issues/745" rel="noopener noreferrer"&gt;How to install phpredis using composer?&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I need to install phpredis using composer on windows server running IIS. What is the package name for this?&lt;/p&gt;

&lt;p&gt;You cannot.&lt;br&gt;
Composer is for pure-PHP library not for C extension (pickle will do it later)&lt;/p&gt;

&lt;p&gt;You need to compile it! See more information here: &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apparently it is impossible to install with composer, and the possibility of being able to do it in the future seems to be close to zero.&lt;/p&gt;

&lt;p&gt;Just in case, I checked other articles as well.&lt;br&gt;
&lt;a href="https://tdomy.com/2020/11/redis-client-comparison/" rel="noopener noreferrer"&gt;Laravel 8のRedisクライアントのパフォーマンスの比較(Laravel 8 Redis client performance comparison)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seems that PhpRedis was better in performance comparison.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;上記のコマンドをそれぞれ50回実行し、平均（±標準偏差）を算出しました。&lt;br&gt;
I executed each command 50 times, and calculate average and standard deviation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PhpRedis … 1.317 ± 0.03 (秒) *secs&lt;/li&gt;
&lt;li&gt;Predis … 1.509 ± 0.026 (秒)*secs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Predisを使用した場合の処理時間はPhpRedisの場合の約1割増しと、明らかに差がでました&lt;/p&gt;

&lt;p&gt;Laravel 8 でPhpRedisとPredisを比較しました。PhpRedisの方が普通に速いので、導入できる環境であれば、Laravelの推奨に従ってPhpRedisで良さそうです。&lt;br&gt;
I compared PhpRedis and Predis in Laravel 8. PhpRedis is usually faster, so if it is an environment that can be introduced, PhpRedis seems to be good according to Laravel's recommendation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But I hate not being able to manage it with composer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://akalongman.medium.com/phpredis-vs-predis-comparison-on-real-production-data-a819b48cbadb" rel="noopener noreferrer"&gt;PhpRedis vs Predis: Comparison on real production data&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PhpRedis is faster about x6 times. Using igbinary serializer reduces stored data size about 3x times.&lt;/p&gt;

&lt;p&gt;If Redis installed on separate machines, reducing network traffic is a very significant speedup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PhpRedis is also praised here.&lt;/p&gt;

&lt;p&gt;Here is Laravel official statement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://readouble.com/laravel/8.x/en/redis.html" rel="noopener noreferrer"&gt;Redis 8.x Laravel&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before using Redis with Laravel, we encourage you to install and use the phpredis PHP extension via PECL. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many developers highly recommended phpredis.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to install PhpRedis
&lt;/h2&gt;
&lt;h3&gt;
  
  
  install command
&lt;/h3&gt;

&lt;p&gt;I have tried Debian and Alpine distributions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pecl install redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get an error as below, try the following commands before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/application # pecl install redis
downloading redis-5.3.4.tgz ...
Starting to download redis-5.3.4.tgz (268,154 bytes)
........................................................done: 268,154 bytes
29 source files, building
running: phpize
Configuring for:
PHP Api Version:         20190902
Zend Module Api No:      20190902
Zend Extension Api No:   320190902
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

ERROR: `phpize' failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Command to run when the above error occurs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apk add --no-cache \
        $PHPIZE_DEPS \
        openssl-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When writing in Dockerfile
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; php:7.4.11-fpm&lt;/span&gt;

&lt;span class="c"&gt;# omission&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;git clone https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis
&lt;span class="k"&gt;RUN &lt;/span&gt;docker-php-ext-install redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installation check
&lt;/h3&gt;

&lt;p&gt;You can check whether PhpRedis is installed correctly with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -m | grep redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see the following message, PhpRedis has been successfully installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Redis container configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  docker-compose.yml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="c1"&gt;# omission&lt;/span&gt;

  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redis:6.0"&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;6379:6379"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./data/redis:/data"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Laravel configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  .env
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CACHE_DRIVER=redis

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  config\database.php
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="s1"&gt;'redis'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

        &lt;span class="s1"&gt;'client'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'REDIS_CLIENT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'phpredis'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before running the app, clear the cache with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan config:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sample sources
&lt;/h2&gt;

&lt;p&gt;I have written the following code to try it.&lt;/p&gt;

&lt;h3&gt;
  
  
  routes\web.php
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Cache&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//============================================================================================&lt;/span&gt;
&lt;span class="c1"&gt;//                                       Cache&lt;/span&gt;
&lt;span class="c1"&gt;//============================================================================================&lt;/span&gt;
&lt;span class="c1"&gt;// http://localhost:8000/cache/put&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/cache/put'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"put"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// store value in cache&lt;/span&gt;
    &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'value01'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// http://localhost:8000/cache/remember&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/cache/remember'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"remember"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// store value permanently&lt;/span&gt;
    &lt;span class="nv"&gt;$cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;\Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key02'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"value02_remember"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cache&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// http://localhost:8000/cache/get&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/cache/get'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// get one value from cache&lt;/span&gt;
    &lt;span class="nv"&gt;$cache01&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key01'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$cache02&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key02'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cache01&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cache02&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// http://localhost:8000/cache/forget&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/cache/forget'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"forget"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// remove value from cache&lt;/span&gt;
    &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key01'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key02'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was able to successfully get Redis to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  caution
&lt;/h2&gt;

&lt;p&gt;After installing with command pecl install redis, the following message was displayed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should add "extension=redis.so" to&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, it worked without adding it.&lt;br&gt;
I have no idea about the details, but I guess Laravel take care of it and read it on its own.&lt;/p&gt;

&lt;p&gt;As I thought, I also found this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qiita.com/miriwo/items/d6ad9e0edc422e8a363a" rel="noopener noreferrer"&gt;Laravel Redisのライブラリをインストールしたらエラーが発生した(An error occurred when installing laravel redis library)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The content says,&lt;br&gt;
"I got an error, but I fixed it by commenting out php.ini "extension="redis.so". 』&lt;/p&gt;

&lt;p&gt;So, when you use Laravel, this setting may not be necessary.&lt;/p&gt;

&lt;p&gt;However, there seems to be a case where an error occurs when uploading to another environment.&lt;br&gt;
&lt;a href="https://qiita.com/freeneer/items/8162c562337e304b4417" rel="noopener noreferrer"&gt;AWSにLaravelをデプロイしたらエラーが出たときの対応方法(How to solve an error when deploying Laravel to AWS)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seems that extension=redis.so is added to php.ini to make it work in EC2.&lt;/p&gt;

&lt;p&gt;It seems better to keep in mind that there are cases where such an error occurs, just in case "It does not work in the production environment!"&lt;/p&gt;

&lt;p&gt;Maybe, using Amazon Linux(RedHat distribution) is one of the causes.&lt;br&gt;
I tried it later and it worked just fine on Debian.&lt;/p&gt;
&lt;h3&gt;
  
  
  How to add "extension=redis.so" to php.ini
&lt;/h3&gt;

&lt;p&gt;First, check the path of php.ini.&lt;br&gt;
Below is the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -i | grep php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execution result example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/application $ php -i | grep php.ini
Configuration File (php.ini) Path =&amp;gt; /usr/local/etc/php
Loaded Configuration File =&amp;gt; /usr/local/etc/php/php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above, the saved path was "/usr/local/etc/php/php.ini", so the additional path is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "extension=redis.so" &amp;gt;&amp;gt; /usr/local/etc/php/php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding it, check the contents of php.ini.&lt;/p&gt;

&lt;p&gt;Then reboot.&lt;/p&gt;

&lt;h2&gt;
  
  
  case of Predis
&lt;/h2&gt;

&lt;p&gt;I also tried it.&lt;/p&gt;

&lt;p&gt;It can be installed with composer, so it's much easier than PhpRedis.&lt;/p&gt;

&lt;p&gt;For more details, read the official website.&lt;br&gt;
&lt;a href="https://readouble.com/laravel/8.x/ja/redis.html" rel="noopener noreferrer"&gt;https://readouble.com/laravel/8.x/ja/redis.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Execution command is here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require predis/predis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If .env and config are set correctly, I think it works without any problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  config\database.php
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="s1"&gt;'redis'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

        &lt;span class="s1"&gt;'client'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'REDIS_CLIENT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'predis'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other settings and the code used in the experiment are the same as above.&lt;/p&gt;

&lt;p&gt;Since there is no difference due to distribution, you will not encounter unexpected issue, and you will have peace in your mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  perspective of library selection
&lt;/h2&gt;

&lt;p&gt;Same engineers say that "PhpRedis is fast! PhpRedis is the best! You should definitely use PhpRedis!"&lt;br&gt;
But, it cannot be managed by a package manager, and since it is necessary to modify parts close to hardware, there are many things to take account.&lt;/p&gt;

&lt;p&gt;At the end of time, the difficulty of the building an environment may be complicated, it increases the possibility of unexpected errors during regular work.&lt;br&gt;
In my opinion, then Predis is a good choice.&lt;/p&gt;

&lt;p&gt;I found an article talking about the concern which Predis development had been suspended, but now development has resumed.&lt;br&gt;
It can be managed by composer and has many advantages.&lt;/p&gt;

&lt;p&gt;PhpRedis has better performance, but depending on system, there are cases where access to the cache does not happen so frequently.&lt;br&gt;
If you don't need such a strict access speed performance, I think one of the selection criteria is to choose a library that can reduce management costs.&lt;/p&gt;

&lt;p&gt;By the way, I am not agree with such an idea.&lt;br&gt;
"Faster and lighter is always right! (Even if the application does not require high front-end performance. It should be implemented even if you have technical debt!)&lt;/p&gt;

&lt;p&gt;Since you can't manage it with composer, you need to recreate the Docker image.&lt;br&gt;
And also, If you are planning to use it in virtual server such as EC2, it will be necessary to prepare an installation command for each distribution, and the number of complicated works will increase.&lt;/p&gt;
&lt;h2&gt;
  
  
  summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When using Redis in Laravel, you will need to adopt one of two types of libraries. "Predis" or "PhpRedis"&lt;/li&gt;
&lt;li&gt;Previously, Predis was commonly used, but now PhpRedis is recommended. (even in official website)&lt;/li&gt;
&lt;li&gt;PhpRedis cannot be managed by composer and must be installed by pecl.&lt;/li&gt;
&lt;li&gt;Therefore, if you are using containers, you need to rebuild the image.&lt;/li&gt;
&lt;li&gt;You may need to add "extension=redis.so" to php.ini, but it may work without it depend on the environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you think that "Why am I having such a hard time just using the cache driver...?The front end is not important in this system",&lt;br&gt;
I recommend consider adopting Predis.&lt;/p&gt;
&lt;h2&gt;
  
  
  Extra
&lt;/h2&gt;

&lt;p&gt;One day, I got a "500 error" no matter what I did.&lt;br&gt;
So I looked in laravel.log and found such a message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local.ERROR: Please make sure the PHP Redis extension is installed and enabled. 
{"exception":"[object] (LogicException(code: 0): Please make sure the PHP Redis extension is installed and enabled. 
at /var/www/html/my-laravel-app/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php:77)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? I didn't edit about redis configuration?&lt;br&gt;
I wondered and looked into it, and it was caused by an error in reading the environment setting file due to editing .env.(The Parts that have nothing to do with Redis)&lt;/p&gt;

&lt;p&gt;It's quite assertive that redis error is prioritized from all other errors and come to front...&lt;/p&gt;

</description>
      <category>larave</category>
      <category>redis</category>
      <category>phpredis</category>
      <category>predis</category>
    </item>
    <item>
      <title>Laravel, MySQL - column_type is set to "int (11)" even though the size of int was specified.</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Tue, 24 May 2022 21:55:58 +0000</pubDate>
      <link>https://dev.to/kakisoft/laravel-mysql-columntype-is-set-to-int-11-even-though-the-size-of-int-was-specified-59pj</link>
      <guid>https://dev.to/kakisoft/laravel-mysql-columntype-is-set-to-int-11-even-though-the-size-of-int-was-specified-59pj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Environment&lt;/strong&gt;&lt;br&gt;
MySQL version : 5.7&lt;br&gt;
Laravel version : 8.16.1&lt;br&gt;
PHP version : 7.4.7&lt;/p&gt;

&lt;p&gt;When adding table columns in the migration file in Laravel, int size can be specified like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'projects'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'category_code'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, looking at the actual generated MySQL schema, column_type is "int (11)".&lt;br&gt;
What's going on? Did I make a mistake?&lt;/p&gt;

&lt;p&gt;So, I looked it up, and found something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/25772759/schema-builder-length-of-an-integer" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/25772759/schema-builder-length-of-an-integer&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're using MySQL, you can't specify the length of an integer column.&lt;br&gt;
You can only choose between one of the available integer types, described at &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/integer-types.html" rel="noopener noreferrer"&gt;http://dev.mysql.com/doc/refman/5.1/en/integer-types.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, apparently "if you are using MySQL, you cannot specify the length".&lt;/p&gt;

&lt;p&gt;This means that for some of the MySQL types, the size is already predetermined, and it cannot be changed as you like.&lt;br&gt;
The table is here.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Storage (Bytes)&lt;/th&gt;
&lt;th&gt;Minimum Value Signed&lt;/th&gt;
&lt;th&gt;Minimum Value Unsigned&lt;/th&gt;
&lt;th&gt;Maximum Value Signed&lt;/th&gt;
&lt;th&gt;Maximum Value Unsigned&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TINYINT&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;-128&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;127&lt;/td&gt;
&lt;td&gt;255&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMALLINT&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;-32768&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;32767&lt;/td&gt;
&lt;td&gt;65535&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEDIUMINT&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;-8388608&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;8388607&lt;/td&gt;
&lt;td&gt;16777215&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;-2147483648&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2147483647&lt;/td&gt;
&lt;td&gt;4294967295&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BIGINT&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;-263&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;263-1&lt;/td&gt;
&lt;td&gt;264-1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;"If you use int in MySQL, it will always be" int (11) ", but that's just the way MySQL works, so please bear that in mind.&lt;/p&gt;

&lt;p&gt;So what about tinyint?&lt;br&gt;
When I looked it up, I found something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://laravel.com/docs/8.x/migrations" rel="noopener noreferrer"&gt;Database: Migrations - Laravel - The PHP Framework For Web Artisans&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The following column types can be modified: bigInteger, binary, boolean, date, dateTime, dateTimeTz, decimal, integer, json, longText, mediumText, smallInteger, string, text, time, unsignedBigInteger, unsignedInteger, unsignedSmallInteger, and uuid. To modify a timestamp column type a Doctrine type must be registered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, it says&lt;br&gt;
"Cannot change from int to tinyint"&lt;br&gt;
(The opposite is possible)&lt;/p&gt;

&lt;p&gt;If you can't do the opposite, it means that the rollback doesn't work properly, so you should avoid it.&lt;/p&gt;

&lt;p&gt;In fact, I also suffered from unnecessary errors.&lt;/p&gt;

&lt;p&gt;So, if you use int or bigint, it is OK to default length.&lt;br&gt;
(Rather, there is no other way.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Note
&lt;/h2&gt;

&lt;p&gt;If you want to change from int to tinyint, it is possible to do so without Laravel syntax, but using alter table.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"alter table projects modify category_code tinyint;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>laravel</category>
      <category>mysql</category>
      <category>rdb</category>
    </item>
    <item>
      <title>PHP, Docker - How to enable PCNTL(Process Control Extensions)</title>
      <dc:creator>kakisoft</dc:creator>
      <pubDate>Tue, 03 May 2022 22:55:05 +0000</pubDate>
      <link>https://dev.to/kakisoft/php-docker-how-to-enable-pcntlprocess-control-extensions-1afk</link>
      <guid>https://dev.to/kakisoft/php-docker-how-to-enable-pcntlprocess-control-extensions-1afk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Environment&lt;/strong&gt;&lt;br&gt;
Laravel version : 8.16.1&lt;br&gt;
PHP version : 7.4.7&lt;/p&gt;

&lt;p&gt;Sometimes PCNTL(Process Control Extensions) is required to use specific features in Laravel.&lt;/p&gt;

&lt;p&gt;(PHP: PCNTL - Manual)&lt;br&gt;
&lt;a href="https://www.php.net/manual/en/book.pcntl.php" rel="noopener noreferrer"&gt;https://www.php.net/manual/en/book.pcntl.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, if you want to specify the job execution timeout period in Laravel, this function must be enabled.&lt;/p&gt;

&lt;p&gt;The following configuration and source code shows that timeout period has been set.&lt;br&gt;
(You can set the job to terminate as an error after X seconds.)&lt;/p&gt;

&lt;p&gt;There are two ways.&lt;br&gt;
one is to specify it from the artisan command when executing the job, and the other is to write it in the source code.&lt;/p&gt;

&lt;p&gt;When using the artisan command, it is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;artisan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When writing in source code, it is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Jobs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProcessPodcast&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ShouldQueue&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * The number of second that the job can execute until timeout period.
     *
     * @var int
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an aside, when these are used both, the source code value takes priority.&lt;/p&gt;

&lt;p&gt;It means, in the case of the above example, it will time out in 120 seconds.&lt;/p&gt;

&lt;p&gt;But, to use this feature, PCNTL(Process Control Extensions) must be enabled as described above, otherwise the timeout period will be 60 seconds by default.&lt;/p&gt;

&lt;p&gt;For more information, please refer to the link.&lt;br&gt;
&lt;a href="https://laravel.com/docs/8.x/queues#timeout" rel="noopener noreferrer"&gt;https://laravel.com/docs/8.x/queues#timeout&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do I enable that feature? when you look into that, you will find "Please compile PHP".&lt;br&gt;
It will discourage you.&lt;br&gt;
&lt;a href="https://www.php.net/manual/en/pcntl.installation.php" rel="noopener noreferrer"&gt;https://www.php.net/manual/en/pcntl.installation.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP Official&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Process Control support in PHP is not enabled by default. You have to compile the CGI or CLI version of PHP with --enable-pcntl configuration option when compiling PHP to enable Process Control support.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Stack Overflow&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/33036773/how-to-enable-pcntl-in-php-while-using-a-framework-like-symfony2" rel="noopener noreferrer"&gt;How to enable pcntl in php ( while using a framework like Symfony2 )&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/40408152/how-to-enable-pcntl-on-ubuntu-server-16-04" rel="noopener noreferrer"&gt;How to enable PCNTL on Ubuntu server 16.04 - Stack Overflow&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;It's a daunting task for Docker developers.&lt;/p&gt;

&lt;p&gt;However, it is possible to enable PCNTL(process control function) by editing the Dockerfile without recompiling PHP.&lt;/p&gt;

&lt;p&gt;To be specific, add the following syntax.&lt;/p&gt;

&lt;p&gt;Docker image was designed to use the official php-fpm distribution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;docker-php-ext-configure pcntl &lt;span class="nt"&gt;--enable-pcntl&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-php-ext-install &lt;span class="se"&gt;\
&lt;/span&gt;    pcntl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example of editing the Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; php:7.4.11-fpm&lt;/span&gt;

&lt;span class="c"&gt;# install composer&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/bin &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://getcomposer.org/installer | php &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /usr/bin/composer.phar /usr/bin/composer
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;zip &lt;span class="se"&gt;\
&lt;/span&gt;unzip &lt;span class="se"&gt;\
&lt;/span&gt;vim

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; libpq-dev &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-php-ext-install pdo_mysql pdo_pgsql

&lt;span class="k"&gt;RUN &lt;/span&gt;docker-php-ext-configure pcntl &lt;span class="nt"&gt;--enable-pcntl&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-php-ext-install &lt;span class="se"&gt;\
&lt;/span&gt;    pcntl

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using Docker-composer, rebuild it with a command such as "docker-compose up -d --build".&lt;/p&gt;

&lt;p&gt;To check if pcntl is enabled use the following command after login to the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -i | grep pcntl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see the following message, pcntl is enabled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pcntl support =&amp;gt; enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See below for php command options.&lt;br&gt;
&lt;a href="https://www.php.net/manual/en/features.commandline.options.php" rel="noopener noreferrer"&gt;PHP: Options - Manual&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>docker</category>
      <category>laravel</category>
      <category>pcntl</category>
    </item>
  </channel>
</rss>
