<?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: Diego Carrasco Gubernatis</title>
    <description>The latest articles on DEV Community by Diego Carrasco Gubernatis (@dacog).</description>
    <link>https://dev.to/dacog</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%2F310736%2F179a6021-7719-4ffb-b03a-a03073ec0136.jpeg</url>
      <title>DEV Community: Diego Carrasco Gubernatis</title>
      <link>https://dev.to/dacog</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dacog"/>
    <language>en</language>
    <item>
      <title>Thinking Out Loud - The Power of Metrics</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Tue, 01 Apr 2025 20:35:45 +0000</pubDate>
      <link>https://dev.to/dacog/thinking-out-loud-the-power-of-metrics-51kh</link>
      <guid>https://dev.to/dacog/thinking-out-loud-the-power-of-metrics-51kh</guid>
      <description>&lt;p&gt;Table of Contents&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_numbers_vs_metrics" rel="noopener noreferrer"&gt;Numbers vs. Metrics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_context_matters" rel="noopener noreferrer"&gt;Context Matters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_technology_changes_our_metrics" rel="noopener noreferrer"&gt;Technology Changes Our Metrics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_the_e_bike_example" rel="noopener noreferrer"&gt;The E-bike Example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_choosing_better_metrics" rel="noopener noreferrer"&gt;Choosing Better Metrics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_numbers_reveal_what_we_miss" rel="noopener noreferrer"&gt;Numbers Reveal What We Miss&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Numbers have power and meaning - and I’m not talking about math here, just numbers themselves. Math is a whole different beast.&lt;/p&gt;

&lt;p&gt;Ok, maybe it is not "just" numbers, but I’m talking about numbers as metrics. 100 is just a number, but it means completely different things if we’re talking about kilos or euros. The same number carries different weight and meaning for men versus women, for heavyweight lifters versus runners versus doctors. Numbers gain their power when they have context and information. They help us make plans ("I’ll save 100 euros monthly"), they can discourage us ("How did I reach 180 kilos? I was 80 just two months ago"), they show our progress ("We’ve grown our customer base by 20%"), and they can bring satisfaction ("Finally reached my goal weight of 75kg!").&lt;/p&gt;

&lt;h3&gt;
  
  
  Numbers vs. Metrics
&lt;/h3&gt;

&lt;p&gt;Numbers by themselves don’t help us as much as numbers with units. And numbers with units are less useful when isolated. When we can compare numbers (against our history or others), that’s when they really shine. They provide a sense of progress and status. If the number moves, depending on the direction and what it measures, we feel better or worse than before - we become happy or frustrated.&lt;/p&gt;

&lt;p&gt;If our numbers are better or worse than those of other people, we develop a sense of status, achievement, or belonging ("I’m now a runner because I managed to run X km in Y minutes").&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Matters
&lt;/h3&gt;

&lt;p&gt;Metrics are great, but only if we understand them. And for that, we need information and context. Is 100 kg body weight good or bad? It depends on your muscles, your stature, your body composition, your gender, your physical activity, your health, and many other factors. Many studies[&lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_footnotedef_1" rel="noopener noreferrer"&gt;1&lt;/a&gt;] show that focusing solely on weight can be misleading. The same applies to everything else. Is saving 100€ good? Sure! Unless you’ve stopped eating to save that money.&lt;/p&gt;

&lt;p&gt;There are countless examples of how numbers help us when we understand them in context with sufficient information. I want to emphasize the words "context" and "information" again. &lt;a href="https://diegocarrasco.com/reflections-information-access-evolution" rel="noopener noreferrer"&gt;In my last reflection&lt;/a&gt;, I wrote about information access, and before that about [the power of defaults](/the-power-of-defaults).&lt;/p&gt;

&lt;p&gt;We now have access to abundant information (in much of the world, at least), but it’s so easy to avoid engaging with it thoughtfully (by relying on AI or treating social media posts as gospel). Even with access to vast data and numbers (and I’m sometimes guilty of this too), truly using and understanding them requires effort and time. And putting in work isn’t something everyone enjoys. Even if we frame it as "playing with numbers," it still takes focus and time to understand them properly. Once you do, you’ll be steps ahead of where you were. You’ll likely make better decisions and understand more of the big picture. But it takes time and effort - something we often take for granted or that prefer dedicate to something else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology Changes Our Metrics
&lt;/h3&gt;

&lt;p&gt;Technological advances help us in many ways, but they sometimes make us less capable (AKA dumber and lazier). It’s so easy to skip the work and still get by (at least temporarily) that we don’t notice how this erodes abilities we once had that got us where we are. And please don’t read that as if I were against technology…​ all the contrary. But I would say we need to be aware of how it influences and changes us, for good or bad.&lt;/p&gt;

&lt;h3&gt;
  
  
  The E-bike Example
&lt;/h3&gt;

&lt;p&gt;A basic example is comparing an e-bike and a regular bike. I have both. For a specific route, my regular bike took me 30 minutes. Then I got an e-bike (a cargo bike) that took just 25 minutes and required less effort. Great! I arrived faster and sweated less.&lt;/p&gt;

&lt;p&gt;Meanwhile, I got a smartwatch that calculates a PAI score[&lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_footnotedef_2" rel="noopener noreferrer"&gt;2&lt;/a&gt;] (a numeric value) and learned how it worked. After almost 2 years, my e-bike broke down, so I returned to my regular bike. Suddenly, my PAI jumped by 140 points in a single day!&lt;/p&gt;

&lt;p&gt;That number means nothing if you don’t know what PAI is (again: numbers, context, and information). It’s a metric that quantifies your physical activity - like an index where higher is better. It calibrates according to your heart rate, meaning that as you get fitter, you need to work harder to earn the same points. With the e-bike, I was getting fewer than 10 points daily, sometimes none. Now I’m earning 140 points for essentially the same journey. Same distance, different tool, vastly different health impact.&lt;/p&gt;

&lt;p&gt;E-bikes offer substantial health benefits, with research confirming that riding an electric bicycle provides significant health advantages &lt;em&gt;compared to remaining sedentary&lt;/em&gt;.[&lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_footnotedef_3" rel="noopener noreferrer"&gt;3&lt;/a&gt;]&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing Better Metrics
&lt;/h3&gt;

&lt;p&gt;So let’s extrapolate. If there’s such an enormous difference in health impact just from my choice of bike, what might happen if I change the metrics I use to optimize other aspects of life?&lt;/p&gt;

&lt;p&gt;What if I coded with the metric of "write once, well-commented and documented" instead of "fast and under the make-it-work mentality"?&lt;/p&gt;

&lt;p&gt;What if you read with a note-taking, explain-to-others approach? You’ll take longer, certainly, but you’ll also gain more from the same activity! Instead of reading a book 4 times and quickly forgetting the material, you’d have notes you understand and perhaps even a blog post explaining your understanding that you can share with others. When your memory gets foggy, you can refer back to these resources. The information gets embedded in your brain because you dedicated time, discussed topics with yourself, reflected on them, and made meaningful notes. It wasn’t wasted time - but this requires measuring success by different metrics, not just time and money.&lt;/p&gt;

&lt;h3&gt;
  
  
  Numbers Reveal What We Miss
&lt;/h3&gt;

&lt;p&gt;Sometimes metrics help us understand things we wouldn’t otherwise grasp, like my PAI score. I noticed I was more out of breath covering the same distance on the regular bike, but I wouldn’t have thought the difference was so huge without seeing the numbers.&lt;/p&gt;

&lt;p&gt;The same applies to habits. If you track time spent (automatically, like with screen time and app usage features), you’ll likely discover you don’t have a time problem but a priority and planning problem. It’s not that you don’t have time (though some genuinely don’t, and they should ignore this part), but that you haven’t set goals or metrics to follow. Three hours daily for a year adds up to 1000+ hours! That’s quite a lot and makes you (hopefully) reconsider the impact of certain decisions.&lt;/p&gt;

&lt;p&gt;But ultimately, this reflection is about numbers as metrics and their power.&lt;/p&gt;

&lt;p&gt;What do you think? Do they impact your life?&lt;/p&gt;




&lt;p&gt;&lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_footnoteref_1" rel="noopener noreferrer"&gt;1&lt;/a&gt;. &lt;a href="https://www.researchgate.net/publication/292990630_Misclassification_of_cardiometabolic_health_when_using_body_mass_index_categories_in_NHANES_2005-2012" rel="noopener noreferrer"&gt;Misclassification of cardiometabolic health when using body mass index categories in NHANES 2005-2012&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_footnoteref_2" rel="noopener noreferrer"&gt;2&lt;/a&gt;. &lt;a href="https://www.ntnu.edu/cerg/personal-activity-intelligence" rel="noopener noreferrer"&gt;https://www.ntnu.edu/cerg/personal-activity-intelligence&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://diegocarrasco.com/the-power-of-metrics/#_footnoteref_3" rel="noopener noreferrer"&gt;3&lt;/a&gt;. There are may studies about this. Here are a couple: &lt;a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC9546252/" rel="noopener noreferrer"&gt;Systematic review and meta‐analysis evaluating the effects electric bikes have on physiological parameters&lt;/a&gt;, &lt;a href="https://doi.org/10.1097/jsm.0000000000000438" rel="noopener noreferrer"&gt;Effect of E-Bike Versus Bike Commuting on Cardiorespiratory Fitness in Overweight Adults: A 4-Week Randomized Pilot Study&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Power of Defaults: How Unconscious Choices Shape Our Lives</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Mon, 03 Mar 2025 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/the-power-of-defaults-how-unconscious-choices-shape-our-lives-2dof</link>
      <guid>https://dev.to/dacog/the-power-of-defaults-how-unconscious-choices-shape-our-lives-2dof</guid>
      <description>&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%2Fahtbloli7x60k6e7pe0k.jpg" 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%2Fahtbloli7x60k6e7pe0k.jpg" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've been thinking a lot about "defaults" lately: default settings, default prices, default processes, default habits, default choices. I find myself defaulting to original behaviors more often than I'd like to admit.&lt;/p&gt;

&lt;p&gt;Take food, for example. I can try to eat healthy by avoiding junk food, eating on schedule, and consuming more fruits and vegetables. But if I don't have the proper snacks or ingredients at the right time, I default to eating cookies (if there are any at home) or buying bread with whatever toppings are available when I'm hungry.&lt;/p&gt;

&lt;p&gt;This pattern applies to almost anything: when adding extra effort or thinking becomes necessary, I revert to the default. The worst part? The default isn't always mine—it could be a family default, a school default, or a friends default. &lt;strong&gt;A default is whatever doesn't require extra effort&lt;/strong&gt;. It's what we do almost without thinking, what comes naturally. It isn't necessarily good or bad; it's simply what has always been there.&lt;/p&gt;

&lt;p&gt;When we try to change our defaults, at least two significant efforts are required:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Plan the new default&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make it so that doing the new default is easier than doing the old one&lt;/strong&gt;. This also means maintaining the new default.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For healthy eating, if fruit is already washed and portioned, while cookies are either absent or difficult to reach, you'll naturally eat more fruit.&lt;/p&gt;

&lt;p&gt;This concept is elaborated in the book "&lt;a href="https://a.co/d/afi8p7X" rel="noopener noreferrer"&gt;Nudge&lt;/a&gt;", which includes a school experiment where placing healthy snacks at eye level and junk food above resulted in children eating more fruits. Something as simple as positioning can make a tremendous difference. Imagine what you could accomplish if you deliberately designed your default choices!&lt;/p&gt;

&lt;p&gt;But there's a catch (there's always a catch): &lt;strong&gt;you need to plan and maintain the change, the new default&lt;/strong&gt;. The latter is most challenging. Planning is difficult but not as hard as maintaining. You might go to the gym daily for the first two weeks when motivation runs high, but after that it requires a conscious choice. If your gym bag isn't ready, if you forgot to prepare snacks, if you didn't block time in your calendar—you won't follow through. It is easier to default to the old choice, the old decision.&lt;/p&gt;

&lt;p&gt;Maintenance is hard, and there are already many books that elaborate on techniques to create habits (similar to creating new defaults) such as "&lt;a href="https://jamesclear.com/atomic-habits" rel="noopener noreferrer"&gt;Atomic Habits&lt;/a&gt;" by James Clear and "&lt;a href="https://charlesduhigg.com/the-power-of-habit/" rel="noopener noreferrer"&gt;The power of habit&lt;/a&gt;" by Charles Duhigg.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note to self: I should re-read those books.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But what if we simply think about defaults and eliminate other options? What if we remove cookies from the shopping list, buy multiple sets of gym clothes, and purchase ready-to-serve healthy snacks? Would we still face the same issues?&lt;/p&gt;

&lt;p&gt;What if we set everything up to make what we want easier to achieve?&lt;/p&gt;

&lt;p&gt;Consider learning guitar: If my guitar is hidden in the closet, and starting lessons requires booting a computer that takes 10 minutes, I won't play. But if the friction is reduced to seconds, I'll have no excuse, and playing for 5 minutes becomes easier than not playing. Imagine if my computer powers on automatically at 5 PM, loads my learning website, and my guitar sits right beside it. Even if I wanted to play a game instead, starting the lesson would be easier because everything is already prepared (playing the game would still require more clicks and effort).&lt;/p&gt;

&lt;p&gt;What about zombie scrolling versus learning something new? I recently reinstalled Instagram on my phone (because of reasons) and quickly realized it would consume significant time. So I adjusted the settings to block the app after 30 minutes. After that time expires, Instagram becomes inaccessible. That's helpful! (Although I'm contemplating removing it entirely again.)&lt;/p&gt;

&lt;p&gt;I've been thinking extensively about defaults—ultimately, I'm thinking about my choices. Each default, each choice, conscious or not, has consequences that build upon each other. Eating unhealthily, remaining sedentary, and scrolling mindlessly all day negatively impact health and life. And the time wasted is unimaginable. I get angry just thinking about it.&lt;/p&gt;

&lt;p&gt;After publishing my &lt;a href="https://dmplaybook.cc/" rel="noopener noreferrer"&gt;latest book&lt;/a&gt;, some people asked how I managed it with family, kids, and work responsibilities (it's a long book after all). It all comes down to choices, I said, after giving some thought (and I still need to improve my health-related choices a lot, btw). I'm almost certain that if you redirect the time spent on social media and TV toward writing a book or learning something new, you'd be amazed by what you could achieve in just a few months.&lt;/p&gt;

&lt;p&gt;What defaults are shaping your life? Which ones could you redesign?&lt;/p&gt;

</description>
      <category>behaviorchange</category>
      <category>defaults</category>
      <category>habits</category>
      <category>personalinsights</category>
    </item>
    <item>
      <title>How to Install Tailscale in a Proxmox CE 8.2 LXC Container (AlmaLinux 9)</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Sat, 16 Nov 2024 08:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/how-to-install-tailscale-in-a-proxmox-ce-82-lxc-container-almalinux-9-23m</link>
      <guid>https://dev.to/dacog/how-to-install-tailscale-in-a-proxmox-ce-82-lxc-container-almalinux-9-23m</guid>
      <description>&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%2Ffdz7vejb8cnatxqpyzqj.jpg" 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%2Ffdz7vejb8cnatxqpyzqj.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#context" rel="noopener noreferrer"&gt;Context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#the-initial-problem" rel="noopener noreferrer"&gt;The Initial Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#what-didnt-work" rel="noopener noreferrer"&gt;What Didn't Work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#what-actually-worked" rel="noopener noreferrer"&gt;What Actually Worked&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#1-configure-tun-support" rel="noopener noreferrer"&gt;1. Configure TUN Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#2-create-tun-device-on-host" rel="noopener noreferrer"&gt;2. Create TUN Device on Host&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#3-restart-container" rel="noopener noreferrer"&gt;3. Restart Container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#4-install-tailscale" rel="noopener noreferrer"&gt;4. Install Tailscale&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#verifying-everything-works" rel="noopener noreferrer"&gt;Verifying Everything Works&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#what-is-tun-anyway" rel="noopener noreferrer"&gt;What is tun anyway?&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/#references" rel="noopener noreferrer"&gt;References&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I recently needed to set up Tailscale in an AlmaLinux 9 LXC container running on my Proxmox 8.2 server. Following the official instructions from &lt;a href="https://tailscale.com/kb/1198/install-rhel-9" rel="noopener noreferrer"&gt;Tailscale's RHEL 9 guide&lt;/a&gt; and even trying their &lt;a href="https://tailscale.com/kb/1031/install-linux" rel="noopener noreferrer"&gt;Linux install script&lt;/a&gt;, I ran into some issues. The main problem turned out to be missing TUN device support in the LXC container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; : this is actually documented &lt;a href="https://tailscale.com/kb/1130/lxc-unprivileged" rel="noopener noreferrer"&gt;here&lt;/a&gt; under unprivileged lxc. Thanks to &lt;a href="https://www.reddit.com/r/Tailscale/s/29TZtFomEX" rel="noopener noreferrer"&gt;@echobot in Reddit&lt;/a&gt; for the info.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Initial Problem
&lt;/h2&gt;

&lt;p&gt;After following the installation steps, when I tried to start Tailscale, I got this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;failed to connect to local tailscaled; it doesn't appear to be running (sudo systemctl start tailscaled ?)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checking the logs with &lt;code&gt;journalctl -u tailscaled -n 50 --no-pager&lt;/code&gt;, I found:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;is CONFIG_TUN enabled in your kernel? `modprobe tun` failed with: modprobe: FATAL: Module tun not found in directory /lib/modules/6.8.8-4-pve

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Didn't Work
&lt;/h2&gt;

&lt;p&gt;My first attempt was to use the older Proxmox method of enabling TUN support by adding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features: nesting=1,tun=1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to the container configuration. This resulted in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TASK ERROR: format error tun: property is not defined in schema and the schema does not allow additional properties

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This didn't work because Proxmox 8.x handles TUN/TAP support differently than previous versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Worked
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Configure TUN Support
&lt;/h3&gt;

&lt;p&gt;I had to edit the LXC container configuration on the Proxmox host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /etc/pve/lxc/&amp;lt;container-id&amp;gt;.conf

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create TUN Device on Host
&lt;/h3&gt;

&lt;p&gt;In my case my system already had &lt;code&gt;dev/net/tun&lt;/code&gt;. I checked this with &lt;code&gt;ls -l /dev/net/tun&lt;/code&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;gt; ls -l /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Jul 27 23:02 /dev/net/tun

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your system does not have it, then create it the TUN device exists on the Proxmox host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p /dev/net
mknod /dev/net/tun c 10 200
chmod 666 /dev/net/tun

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Restart Container
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pct restart &amp;lt;container-id&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or use the WebUI for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Install Tailscale
&lt;/h3&gt;

&lt;p&gt;After fixing the TUN support, I could properly install Tailscale in the container (i must say I always could install it, I could just not run it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add Tailscale repository
dnf config-manager --add-repo https://pkgs.tailscale.com/stable/almalinux/9/tailscale.repo

# Install Tailscale
dnf install tailscale

# Start and enable the service
systemctl enable --now tailscaled

# Connect to Tailscale network
tailscale up

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verifying Everything Works
&lt;/h2&gt;

&lt;p&gt;To make sure everything was working correctly, I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check service status
systemctl status tailscaled

# Activating tailscape asks for auth and provides a link. Just follow the instructions.
tailscale up

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is &lt;code&gt;tun&lt;/code&gt; anyway?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;TUN/TAP provides packet reception and transmission for user space programs. It can be seen as a simple Point-to-Point or Ethernet device, which, instead of receiving packets from physical media, receives them from user space program and instead of sending packets via physical media writes them to the user space program. -- &lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/" rel="noopener noreferrer"&gt;https://docs.kernel.org/networking/tuntap.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;TUN, short for "network &lt;strong&gt;TUN&lt;/strong&gt; nel," is a virtual network device that operates at the IP level. It acts like a virtual network card, allowing software to send and receive network packets as if it were a physical network interface. TUN is needed for creating virtual private networks (VPNs) and other network tunneling applications, as it provides a way for programs to interact directly with network traffic at a low level.&lt;/p&gt;

&lt;p&gt;In the context of running Tailscale in an LXC container, TUN is required because Tailscale uses it to create its secure network tunnel. LXC containers, by default, don't have access to create these virtual network devices. To run Tailscale successfully, the LXC container needs to be configured to allow the creation and use of TUN devices. This involves modifying the container's configuration to grant it the necessary permissions to access and manipulate TUN devices, enabling Tailscale to establish its encrypted network connections and route traffic securely.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tailscale.com/kb/1198/install-rhel-9" rel="noopener noreferrer"&gt;Tailscale RHEL 9 Installation Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailscale.com/kb/1031/install-linux" rel="noopener noreferrer"&gt;Tailscale Linux Installation Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forum.proxmox.com/threads/lxc-tun-vpn-device-on-more-container.119727/" rel="noopener noreferrer"&gt;Proxmox VForum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/TUN/TAP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/" rel="noopener noreferrer"&gt;https://docs.kernel.org/networking/tuntap.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/install-tailscale-proxmox-lxc-container-almalinux-9/" rel="noopener noreferrer"&gt;https://cloudspinx.com/install-tailscale-in-lxc-container-on-proxmox-ve/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>almalinux</category>
      <category>container</category>
      <category>howto</category>
      <category>lxc</category>
    </item>
    <item>
      <title>How to recover and update Proxmox 8 firewall configuration in SQLite when you locked yourself out</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Fri, 27 Sep 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/how-to-recover-and-update-proxmox-8-firewall-configuration-in-sqlite-when-you-locked-yourself-out-513</link>
      <guid>https://dev.to/dacog/how-to-recover-and-update-proxmox-8-firewall-configuration-in-sqlite-when-you-locked-yourself-out-513</guid>
      <description>&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%2F52kk1ok85shv8v9u1w39.jpg" 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%2F52kk1ok85shv8v9u1w39.jpg" alt="social banner Proxmox firewall misconfiguration" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;The firewall config is not in &lt;code&gt;/etc/pve/firewall/cluster.fw&lt;/code&gt; but in a SQLite Database in &lt;code&gt;/var/lib/pve-cluster/config.db&lt;/code&gt;. You need to reboot your system into rescue mode, edit the value &lt;code&gt;enable: 1&lt;/code&gt; to &lt;code&gt;enable: 0&lt;/code&gt; and reboot into Proxmox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I made a noob mistake and locked myself out of my server. Luckily Hetzner allows me to reboot into rescue mode. This is what happened and how I managed to get my access back.&lt;/p&gt;

&lt;p&gt;In other words, this tutorial is for situations where you've accidentally locked yourself out of your Proxmox server due to a firewall misconfiguration (like I did). In my case, I enabled the firewall (&lt;code&gt;enable: 1&lt;/code&gt;) with an incorrect configuration, preventing access to the server. The solution involves booting into a rescue system, mounting the Proxmox partition, and manually editing the firewall configuration in the SQLite database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Access to a rescue system (e.g., Hetzner Rescue System)&lt;/li&gt;
&lt;li&gt;Basic knowledge of Linux commands and SQLite, although you can copy and paste these commands and it should work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt; : I am not responsible for data loss or anything else for that matter. The following commands worked for me and nothing bad happened. I out them here in case they help someone else, as I had to research a few hour before solving this (specially the issue of not finding the config).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Boot into Rescue System
&lt;/h3&gt;

&lt;p&gt;Boot your server into the rescue system provided by your hosting provider (e.g., Hetzner Rescue System).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Identify the Proxmox Partition
&lt;/h3&gt;

&lt;p&gt;Use the &lt;code&gt;lsblk&lt;/code&gt; command to list all block devices:&lt;br&gt;
&lt;/p&gt;

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identify the partition where Proxmox is installed. It's often part of a RAID array or LVM setup.&lt;/p&gt;

&lt;p&gt;In my case the output was like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;loop07:003.1G1 loop
nvme1n1259:00 476.9G0 disk
├─nvme1n1p1259:10256M0 part
│ └─md09:00 255.9M0 raid1 
├─nvme1n1p2259:201G0 part
│ └─md19:101022M0 raid1 
└─nvme1n1p3259:30 475.7G0 part
└─md29:20 475.6G0 raid1 
├─vg0-root 253:0064G0 lvm
├─vg0-swap 253:108G0 lvm
└─vg0-data 253:20402G0 lvm
nvme0n1259:40 476.9G0 disk
├─nvme0n1p1259:50256M0 part
│ └─md09:00 255.9M0 raid1 
├─nvme0n1p2259:601G0 part
│ └─md19:101022M0 raid1 
└─nvme0n1p3259:70 475.7G0 part
└─md29:20 475.6G0 raid1 
├─vg0-root 253:0064G0 lvm
├─vg0-swap 253:108G0 lvm
└─vg0-data 253:20402G0 lvm

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There I saw that I should mount &lt;code&gt;vg0&lt;/code&gt;, and that is was in a raid &lt;code&gt;md2&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Assemble RAID Array (if applicable)
&lt;/h3&gt;

&lt;p&gt;If your Proxmox partition is part of a RAID array, assemble it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mdadm --assemble --scan

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Activate Volume Group
&lt;/h3&gt;

&lt;p&gt;Activate the volume group (usually named &lt;code&gt;vg0&lt;/code&gt; in Proxmox):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vgchange -ay vg0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Mount the Proxmox Partition
&lt;/h3&gt;

&lt;p&gt;Create a mount point and mount the Proxmox root partition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir /mnt/proxmox
mount /dev/vg0/root /mnt/proxmox

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the mount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls /mnt/proxmox/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you should see some files and directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Locate the Configuration Database
&lt;/h3&gt;

&lt;p&gt;The Proxmox configuration is stored in an SQLite database. Locate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -la /mnt/proxmox/var/lib/pve-cluster

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a file named &lt;code&gt;config.db&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Access the SQLite Database
&lt;/h3&gt;

&lt;p&gt;Open the SQLite database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sqlite3 /mnt/proxmox/var/lib/pve-cluster/config.db

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sqlite3&lt;/code&gt; is already installed in the rescue system of Hetzner. You need to install it if it's not available in your system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Check the Current Firewall Configuration
&lt;/h3&gt;

&lt;p&gt;View the current firewall configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT \* FROM tree WHERE name = 'cluster.fw';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : Initially I didn't know where this was, so I used the following to find where the entry was and if there was any.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT \* FROM tree WHERE name = 'cluster.fw';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 9: Update the &lt;code&gt;enable&lt;/code&gt; Option
&lt;/h3&gt;

&lt;p&gt;Change the &lt;code&gt;enable&lt;/code&gt; option from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt; to disable the firewall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UPDATE tree 
SET data = replace(data, 'enable: 1', 'enable: 0') 
WHERE name = 'cluster.fw';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 10: Verify the Change
&lt;/h3&gt;

&lt;p&gt;Confirm that the change was made successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT \* FROM tree WHERE name = 'cluster.fw';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 11: Exit SQLite
&lt;/h3&gt;

&lt;p&gt;Exit the SQLite prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.quit

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 12: Unmount and Reboot
&lt;/h3&gt;

&lt;p&gt;Unmount the Proxmox partition and reboot the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;umount /mnt/proxmox
reboot

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important Notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disabling the Firewall:&lt;/strong&gt; This process disables the firewall cluster-wide. Re-enable it after properly configuring it once you regain access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Risks:&lt;/strong&gt; A disabled firewall may expose your system to security risks. You have been warned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup:&lt;/strong&gt; Always create backups before making significant changes. I have my proxmox configs in a git repository for reference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alternative Methods:&lt;/strong&gt; When possible, use the Proxmox web interface or CLI tools for configuration changes. At least that's what I've read. I like to use config files, but I also locked myself out of my server. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Several sites, but I cannot longer remember all of them.&lt;/p&gt;

&lt;p&gt;Some of the sites I visited are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://forum.proxmox.com/threads/ssh-connection-no-web-interface.110702/" rel="noopener noreferrer"&gt;https://forum.proxmox.com/threads/ssh-connection-no-web-interface.110702/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/Proxmox/comments/13hyn0y/how%5C_to%5C_secure%5C_proxmox%5C_web%5C_ui/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/Proxmox/comments/13hyn0y/how\_to\_secure\_proxmox\_web\_ui/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eulenfunk.readthedocs.io/en/stable/supernode01.html" rel="noopener noreferrer"&gt;https://eulenfunk.readthedocs.io/en/stable/supernode01.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and many more ...&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>firewall</category>
      <category>linux</category>
      <category>lvm</category>
      <category>proxmox</category>
    </item>
    <item>
      <title>How to manage multiple AsciiDoc Chapter Files: Copy, Merge, and Customize</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Wed, 25 Sep 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/how-to-manage-multiple-asciidoc-chapter-files-copy-merge-and-customize-47h9</link>
      <guid>https://dev.to/dacog/how-to-manage-multiple-asciidoc-chapter-files-copy-merge-and-customize-47h9</guid>
      <description>&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%2Fw8r81tyu7tkkrh4g6szl.jpg" 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%2Fw8r81tyu7tkkrh4g6szl.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Manage multiple AsciiDoc chapter files efficiently with a customizable bash script that supports copying and merging chapters in different languages. This script allows you to concatenate, copy, or merge chapter files with flexible options for language codes, prefixes, output destinations and with recursive file search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;I work a lot with AsciiDoc files. I write documentation, books and even part of this site with it. Sometimes I need to merge some files or copy their content to a new file. This is the case with the new novel I'm writing.&lt;/p&gt;

&lt;p&gt;Because of reasons, I decided to write it in 3 languages in parallel: spanish, german and english.&lt;/p&gt;

&lt;p&gt;I use &lt;code&gt;include::file.adoc[]&lt;/code&gt; to manage multiple files and merge them into a final version. This way I can write each chapter in each language in different files, and then include them in a final file 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;= title of the book
:author: Diego Carrasco
// here comes more metadata and config stuff.

include::chapter_00.adoc[]

include::chapter_01.adoc[]

include::chapter_02.adoc[]

include::chapter_03.adoc[]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm already by chapter 15, which means I have 45 files plus the main ones. (15 files per language).&lt;/p&gt;

&lt;p&gt;Again, because of reasons, I needed to copy the content of all the chapter from a specific language to my clipboard - or at least to a new file.&lt;/p&gt;

&lt;p&gt;To streamline this, I made a bash script that helps me automate the process of concatenating, merging, or copying chapter files. This script is designed to handle these tasks while providing support for different languages, prefixes, and output formats.&lt;/p&gt;

&lt;p&gt;As I tend to forget these stuff, I make a note here.&lt;/p&gt;

&lt;p&gt;NOTE: This script does actually work on any kind of text file, just change the prefix 😁&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. The Bash Script
&lt;/h4&gt;

&lt;p&gt;Create a new file &lt;code&gt;manage_chapters.sh&lt;/code&gt; and paste the following:&lt;/p&gt;

&lt;p&gt;DISCLAIMER: I am in no way responsible for any damage to your files. This script is provided as is. Always read the script before using it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

usage() {
echo "Usage: $0 [-c xx] [-l yy] [-p prefix] [-o output\_file] [-r]"
echo " -c xx : Specify chapter numbers (e.g., '01 02 03' or '\*' for all)"
echo " -l yy : Specify language code (e.g., 'es' for Spanish)"
echo " -p prefix : Specify file prefix (default: 'chapter\_')"
echo " -o output\_file : Merge into a file instead of copying to clipboard"
echo " -r : Search recursively in subdirectories"
exit 1
}

chapters=""
language=""
prefix="chapter\_"
output\_file=""
recursive=""

while getopts "c:l:p:o:r" opt; do
case $opt in
c) chapters="$OPTARG" ;;
l) language="$OPTARG" ;;
p) prefix="$OPTARG" ;;
o) output\_file="$OPTARG" ;;
r) recursive="-r" ;;
*) usage ;;
esac
done

if [-z "$chapters"]; then
usage
fi

if ["$chapters" = "\*"]; then
pattern="${prefix}\*.adoc"
else
pattern="${prefix}@(${chapters// /|}).adoc"
fi

if [-n "$language"]; then
pattern="${pattern%.adoc}.${language}.adoc"
fi

if [-n "$recursive"]; then
find\_cmd="find . -type f -name"
else
find\_cmd="find . -maxdepth 1 -type f -name"
fi

content=$(eval "$find\_cmd \"$pattern\"" | sort | xargs cat)

if [-z "$content"]; then
echo "No matching files found."
exit 1
fi

if [-n "$output\_file"]; then
echo "$content" &amp;gt; "$output\_file"
echo "All matching chapter contents merged into '$output\_file'"
else
# Check if xclip is available (Linux)
if command -v xclip &amp;amp;&amp;gt; /dev/null; then
echo "$content" | xclip -selection clipboard
echo "All matching chapter contents copied to clipboard as a single text using xclip."
# Check if pbcopy is available (macOS)
elif command -v pbcopy &amp;amp;&amp;gt; /dev/null; then
echo "$content" | pbcopy
echo "All matching chapter contents copied to clipboard as a single text using pbcopy."
else
echo "No clipboard utility found. Please install xclip (Linux) or use pbcopy (macOS)."
exit 1
fi
fi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. How It Works
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Command-line options&lt;/strong&gt; : You can specify chapters (&lt;code&gt;-c&lt;/code&gt;), a language code (&lt;code&gt;-l&lt;/code&gt;), a custom file prefix (&lt;code&gt;-p&lt;/code&gt;), and an output file (&lt;code&gt;-o&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern construction&lt;/strong&gt; : The script dynamically generates a filename pattern based on the options provided.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finding matching files&lt;/strong&gt; : It uses the &lt;code&gt;find&lt;/code&gt; command to locate all matching files within the current directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File concatenation&lt;/strong&gt; : The &lt;code&gt;xargs cat&lt;/code&gt; command is used to concatenate the contents of the found files into one string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clipboard support&lt;/strong&gt; : If no output file is provided, the script copies the concatenated content to the clipboard using either &lt;code&gt;xclip&lt;/code&gt; (Linux) or &lt;code&gt;pbcopy&lt;/code&gt; (macOS).&lt;/li&gt;
&lt;li&gt;Option -r to enable recursive searching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Usage Examples
&lt;/h4&gt;

&lt;p&gt;Here are a few example scenarios where this script can be helpful:&lt;/p&gt;

&lt;h5&gt;
  
  
  Example 1: Copy all chapters to clipboard (default behavior)
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "\*"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example 2: Merge specific chapters into a file
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "01 02 03" -o merged_chapters.adoc

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example 3: Copy chapters with a different prefix
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "\*" -p "section\_"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example 4: Merge language-specific chapters into a file
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "\*" -l es -o spanish_chapters.adoc

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example 5: Copy chapters with a custom prefix and specific language
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "01 02" -p "part\_" -l de

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example 6: Recursive search in all subdirectories:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "\*" -r

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example 7: Recursive search for specific chapters and language
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage_chapters.sh -c "01 02" -l es -r

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Key Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexible Chapter Selection&lt;/strong&gt; : Select specific chapters or use wildcards to include all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language Support&lt;/strong&gt; : Handle different language versions of chapters easily by specifying the language code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable File Prefix&lt;/strong&gt; : The ability to change file prefixes allows the script to adapt to different project structures or naming conventions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clipboard or File Output&lt;/strong&gt; : Depending on your needs, choose to merge chapters into a file or copy the concatenated content directly to the clipboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this helps you in your AsciiDoc adventures :)&lt;/p&gt;

</description>
      <category>asciidoc</category>
      <category>bash</category>
    </item>
    <item>
      <title>(Quick-note) Troubleshooting Dual Monitor Issues on KDE on Ubuntu/ Linux Mint</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Thu, 25 Jul 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/quick-note-troubleshooting-dual-monitor-issues-on-kde-on-ubuntu-linux-mint-28p1</link>
      <guid>https://dev.to/dacog/quick-note-troubleshooting-dual-monitor-issues-on-kde-on-ubuntu-linux-mint-28p1</guid>
      <description>&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%2F6kulp27ym00k6u0sq0ug.jpg" 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%2F6kulp27ym00k6u0sq0ug.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TLDR
&lt;/h3&gt;

&lt;p&gt;Learn how to troubleshoot and resolve issues with dual monitors on KDE, especially when one monitor stops working or remains off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;By default, KDE handles dual monitors well on a new installation. However, sometimes one monitor might stop working and stay off. This happened to me, and I had to fix it using xrandr and KDE's display settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;p&gt;Here is how I resolved my issue:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run xrandr Query&lt;/strong&gt; :
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xrandr --query

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This showed two activated displays.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Copy Display Names&lt;/strong&gt; : I identified display names from the xrandr output.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ xrandr --query
Screen 0: minimum 320 x 200, current 5120 x 1440, maximum 16384 x 16384
HDMI-A-0 connected 2560x1440+0+0 (normal left inverted right x axis y axis) 597mm x 336mm
2560x1440144.00*+ 120.0099.9559.95
3840x216030.0025.0024.0029.9723.98
1920x1200144.00
1920x1080120.00119.8860.0060.0050.0059.94
1600x1200144.00
1680x105059.88
1280x102475.0260.02
1440x90059.90
1280x96060.00
1280x80059.91
1152x86475.00
1280x72060.0050.0059.94
1024x76875.0370.0760.00
832x62474.55
800x60072.1975.0060.3256.25
720x57650.00
720x48060.0059.94
640x48075.0072.8166.6760.0059.94
720x40070.08
DisplayPort-0 connected primary 2560x1440+2560+0 (normal left inverted right x axis y axis) 597mm x 336mm
2560x144059.95*+
1920x120059.95
1920x108060.0050.0059.9430.0025.0024.0029.9723.98
1600x120059.95
1680x105059.95
1280x102475.0260.02
1440x90059.89
1280x96060.00
1280x80059.81
1152x86475.00
1280x72060.0050.0059.94
1024x76875.0370.0760.00
832x62474.55
800x60072.1975.0060.3256.25
720x57650.00
720x48060.0059.94
640x48075.0072.8166.6760.0059.94
720x40070.08
DisplayPort-1 disconnected (normal left inverted right x axis y axis)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Execute Command&lt;/strong&gt; :
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xrandr --output HDMI-A-0 --mode 1920x1080 --right-of DisplayPort-0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I set &lt;code&gt;HDMI-A-0&lt;/code&gt; as the main display, right of &lt;code&gt;DisplayPort-0&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adjust in KDE Preferences&lt;/strong&gt; : I went to &lt;strong&gt;Preferences &amp;gt; Display Configuration&lt;/strong&gt;. I set the desired resolutions and applied the changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fix Overlap&lt;/strong&gt; : When there was overlap, I changed both monitors to a lower resolution, applied changes, then set the preferred resolution again.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Following these steps fixed my issue, and both monitors worked correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://userbase.kde.org/System_Settings/Display_Configuration" rel="noopener noreferrer"&gt;KDE Display Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.x.org/wiki/Projects/XRandR/" rel="noopener noreferrer"&gt;xrandr Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>commandline</category>
      <category>kde</category>
      <category>kdeneon</category>
      <category>linux</category>
    </item>
    <item>
      <title>Introducing the FlexSearch Plugin for Nikola</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Thu, 18 Jul 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/introducing-the-flexsearch-plugin-for-nikola-cm3</link>
      <guid>https://dev.to/dacog/introducing-the-flexsearch-plugin-for-nikola-cm3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xf8kqhTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/introducing-the-flexsearch-plugin-for-nikola.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xf8kqhTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/introducing-the-flexsearch-plugin-for-nikola.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;I wanted to have search functionality in this site, which is powered by &lt;a href="https://getnikola.com/" rel="noopener noreferrer"&gt;Nikola SSG&lt;/a&gt;. After some research I decided to create a new plugin using &lt;a href="https://github.com/nextapps-de/flexsearch" rel="noopener noreferrer"&gt;Flexsearch&lt;/a&gt; and the plugin is not available in &lt;a href="https://plugins.getnikola.com/v8/flexsearch_plugin/" rel="noopener noreferrer"&gt;Nikola Plugin&lt;/a&gt; repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I use this site a lot as personal repository of stuff I forget. This means I refer to it when I have to do something and I no longer remember what command it was. I also refer people here when they ask something I´ve already answered here. My usual workflow was to go through my articles and use the search feature from the browser, but that was not that efficient because sometimes I only remember that one phrase of that one post.&lt;/p&gt;

&lt;p&gt;Well, this is no longer necessary because now this site has full-text search functionality, courtesy of yours truly. This is a new Nikola Plugin, under MIT License (so that you can just use it as you want) and the &lt;a href="https://github.com/nextapps-de/flexsearch" rel="noopener noreferrer"&gt;FlexSearch Library&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does this work?
&lt;/h2&gt;

&lt;p&gt;Great that you ask. This is a static site. That means that whenever I post a new article I have to rebuild the site to generate HTML from my source (markdown, rst, asciidoc and others) from my git repository. In other words, this site does not use any database. The search functionality has 3 steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When the site is build, a search:index.json is build. This index contains all the titles, slugs and body of all my articles.&lt;/li&gt;
&lt;li&gt;There is a search box now in th main menu. This does nothing else than calling a javascript snippet, which in turn uses the FlexSearch Library, to use that search_index as input and return a list of post that matches your search query.&lt;/li&gt;
&lt;li&gt;The small javascript snippet renders the search results in a div for you to browse.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That´s all. It is completely offline, no Google, Databases, third party services or whatever. Pretty cool, isn´t it?&lt;/p&gt;

&lt;p&gt;Of course, I´m not the first one to think about this. There are many examples out there. These are some of them&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.stephanmiller.com/static-site-search/" rel="noopener noreferrer"&gt;https://www.stephanmiller.com/static-site-search/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://snipcart.com/blog/static-site-search" rel="noopener noreferrer"&gt;https://snipcart.com/blog/static-site-search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://plugins.getnikola.com/v7/localsearch/" rel="noopener noreferrer"&gt;https://plugins.getnikola.com/v7/localsearch/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are using Nikola for your site, you are welcome to give it a try.&lt;/p&gt;

&lt;p&gt;To install the plugin just run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nikola plugin -i flexsearch_plugin

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and follow the instructions.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://getnikola.com/" rel="noopener noreferrer"&gt;Nikola Static Site Generator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nextapps-de/flexsearch" rel="noopener noreferrer"&gt;FlexSearch GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://plugins.getnikola.com/v8/flexsearch_plugin/" rel="noopener noreferrer"&gt;FlexSearch Plugin for Nikola&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flexsearch</category>
      <category>fulltextsearch</category>
      <category>javascript</category>
      <category>nikola</category>
    </item>
    <item>
      <title>How to fix incrementing mount names on reboot in Ubuntu/Linux Mint</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Thu, 11 Jul 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/how-to-fix-incrementing-mount-names-on-reboot-in-ubuntulinux-mint-3al</link>
      <guid>https://dev.to/dacog/how-to-fix-incrementing-mount-names-on-reboot-in-ubuntulinux-mint-3al</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d2JhGCOX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/fix-incrementing-mount-names-ubuntu-linux-mint.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d2JhGCOX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/fix-incrementing-mount-names-ubuntu-linux-mint.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;To prevent your internet disks from being mounted with incrementing names (e.g., name1, name2) on each reboot, configure static mount points using the &lt;code&gt;/etc/fstab&lt;/code&gt; file. This avoids conflicts with services like Docker that use bind volumes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;Each time I restarted my computer running Ubuntu/Linux Mint, my additional disks were mounted with incrementing names. This breaks all symbolic links and history because another service, Docker in my case, uses the path before it is mounted.&lt;/p&gt;

&lt;p&gt;Why was this happening? I did not care to check how were the additional internal disks being mounted. I just connected them and started to use them. To be fair, I don't restart my computer that often (around once a year, see the image below), so it took me almost a year to find this situation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4I2tGWet--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/uptime-titan-2024-06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4I2tGWet--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/uptime-titan-2024-06.png" alt="uptime" width="607" height="43"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Long story short, I restarted my computer and many thing did not work anymore, and the mount points were the cause of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps to Fix the Issue
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Find the UUID of the Disk
&lt;/h4&gt;

&lt;p&gt;Use the &lt;code&gt;lsblk&lt;/code&gt; command to list all block devices and their UUIDs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lsblk -o NAME,FSTYPE,UUID

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use the disk manager in your desktop environment to find the UUID. In my case, KDE, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NEaZb2uk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/disc-manager-kde-uuid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NEaZb2uk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/disc-manager-kde-uuid.png" alt="disk manager kde uuid" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note down the UUID of the disk you want to mount.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Edit &lt;code&gt;/etc/fstab&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Open the &lt;code&gt;/etc/fstab&lt;/code&gt; file with a text editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/fstab

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Add an Entry for Your Disk
&lt;/h4&gt;

&lt;p&gt;Add an entry for your disk using its UUID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UUID=&amp;lt;your-uuid&amp;gt; /mnt/your-mount-point ext4 defaults 0 2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;your-uuid&amp;gt;&lt;/code&gt; with the actual UUID and &lt;code&gt;/mnt/your-mount-point&lt;/code&gt; with your desired mount point.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Understand the &lt;code&gt;fstab&lt;/code&gt; Options (optional, most of the time the defaults will work)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;defaults&lt;/code&gt; option&lt;/strong&gt; : A shorthand for standard mount options, including:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rw&lt;/code&gt; (read-write)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;suid&lt;/code&gt; (allow setuid bits)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dev&lt;/code&gt; (interpret device files)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exec&lt;/code&gt; (allow execution of binaries)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto&lt;/code&gt; (can be mounted with &lt;code&gt;mount -a&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nouser&lt;/code&gt; (only root can mount)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;async&lt;/code&gt; (asynchronous I/O)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt; (dump)&lt;/strong&gt;: This field is used by the dump utility to decide if the filesystem needs to be dumped. &lt;code&gt;0&lt;/code&gt; means ignore.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;2&lt;/code&gt; (pass)&lt;/strong&gt;: The order in which &lt;code&gt;fsck&lt;/code&gt; checks the filesystem for errors during boot. &lt;code&gt;0&lt;/code&gt; means don't check, &lt;code&gt;1&lt;/code&gt; is reserved for the root filesystem, and &lt;code&gt;2&lt;/code&gt; is for all other filesystems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Create Mount Points
&lt;/h4&gt;

&lt;p&gt;If you don't have the mount points already, create them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /mnt/your-mount-point

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case I did already have them.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Mount the Drives
&lt;/h4&gt;

&lt;p&gt;Restart your computer or run the following command to mount the drives immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mount -a

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case I had to restart the system, as that was the easiest way to get everything normal again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side notes
&lt;/h2&gt;

&lt;p&gt;As sidenote, some of the issues I had were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nextcloud Desktop could not sync anymore, as it did not find the destination folder.&lt;/li&gt;
&lt;li&gt;The quick accesses on doplhin file manager were no longer correct.&lt;/li&gt;
&lt;li&gt;all my zoxide paths were broken.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was enough for me to fix this, as I couldn't take it anymore. :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Some References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://askubuntu.com/questions/164926/how-to-make-partitions-mount-at-startup" rel="noopener noreferrer"&gt;How to Make Partitions Mount at Startup - Ask Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/storage/bind-mounts/" rel="noopener noreferrer"&gt;Bind Mounts - Docker Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://superuser.com/questions/1828141/default-mount-options-differ" rel="noopener noreferrer"&gt;Understanding Default Mount Options - Super User&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unix.stackexchange.com/questions/386412/how-does-mount-determine-the-default-mounting-options-for-newly-attached-filesys" rel="noopener noreferrer"&gt;Mounting Filesystems - Unix Stack Exchange&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.alibabacloud.com/help/en/ecs/use-cases/to-mount-an-ext4-file-system-using-the-mount-command" rel="noopener noreferrer"&gt;Mounting an ext4 File System - Alibaba Cloud&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>bindvolumes</category>
      <category>fstab</category>
      <category>linuxmint</category>
      <category>mountpoints</category>
    </item>
    <item>
      <title>Introducing the GitHub Widget Plugin for Nikola</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Thu, 04 Jul 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/introducing-the-github-widget-plugin-for-nikola-1cl3</link>
      <guid>https://dev.to/dacog/introducing-the-github-widget-plugin-for-nikola-1cl3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nx5fzbTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/introducing-github-widget-plugin.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nx5fzbTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/introducing-github-widget-plugin.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#tldr"&gt;TL;DR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#context"&gt;Context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#how-it-works"&gt;How It Works&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#installation"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#optional-configuration"&gt;Optional Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#using-the-shortcode"&gt;Using the Shortcode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#customization"&gt;Customization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#visual-examples"&gt;Visual Examples&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#css-customization"&gt;CSS Customization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/introducing-github-widget-plugin/#references"&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;The GitHub Widget Shortcode Plugin for Nikola lets you embed a customizable widget showcasing a GitHub repository's details in your site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;Today, I'm excited to announce that my GitHub Widget Plugin for Nikola has been merged! This plugin allows you to embed a GitHub repository widget directly into your Nikola-generated site, displaying key details of the repository.&lt;/p&gt;

&lt;p&gt;Nikola is a static site generator that offers great flexibility. I've already written about it [a few times](&lt;a href="https://diegocarrasco.com/categories/nikola/"&gt;https://diegocarrasco.com/categories/nikola/&lt;/a&gt;, and it's what's powers this site. However, embedding GitHub repository details required custom solutions—until now. My new plugin provides an easy way to integrate this functionality using a simple shortcode.&lt;/p&gt;

&lt;p&gt;Why is this important? Because somehow I've been using GitHub more for public code, such as my &lt;a href="https://espanso.org/"&gt;espanso&lt;/a&gt;-compatible &lt;a href="https://github.com/dacog/textexpander_android"&gt;TextExpander Android App&lt;/a&gt;. Thus, I plan to have a section on this site to list such projects, and I was missing a way to show updated information from each repository.&lt;/p&gt;

&lt;p&gt;With this shortcode I can just do this &lt;a href="https://diegocarrasco.com/listings/listing-github-widget-example.md.html"&gt;listing-github-widget-example.md&lt;/a&gt;&lt;a href="https://diegocarrasco.com/listings/listing-github-widget-example.md"&gt;(Source)&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{% github_widget %}}dacog/textexpander_android {{%/github_widget %}}`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and I get the following&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dacog/textexpander_android"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BkzXFfVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" alt="NamedUser(login=" width="560" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;h4&gt;
  
  
  textexpander_android
&lt;/h4&gt;

&lt;p&gt;](&lt;a href="https://github.com/dacog/textexpander_android"&gt;https://github.com/dacog/textexpander_android&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This is a basic text expander app for android. Use it as a espanso companion app, as it parses the yaml files in espanso/match&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Languages:&lt;/strong&gt; Kotlin&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Stars: 9&lt;/li&gt;
&lt;li&gt;

 Forks: 1&lt;/li&gt;
&lt;li&gt;👁 Watchers: 2&lt;/li&gt;
&lt;li&gt;❗ Open Issues: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This looks a lot better than just a link 😁&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;It was a bit trial and error, as I had not used the GitHub API before.&lt;/p&gt;

&lt;p&gt;The first approach was to use &lt;code&gt;requests&lt;/code&gt; to call the api endpoints (such as &lt;code&gt;https://api.github.com/repos/{repo}/commits&lt;/code&gt;) to get the json response and use that. But after that I also wanted to get the latest commits and the latest release, if available. And then I got an api rate limit error, with a nice message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
"message": "API rate limit exceeded for 2.206.40.62. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
"documentation\_url": "https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That meant, of course, that I now had to get a token to avoid the error. I tried following the GitHub API Documentation for AUTH, but without success. And then it got me... there should already be a library for this... and there was.&lt;/p&gt;

&lt;p&gt;I installed &lt;a href="https://github.com/PyGithub/PyGithub"&gt;PyGithub&lt;/a&gt; and refactored my code to use it. That meant I removed most of my code, as I no longer had to call each endpoint on my own.&lt;/p&gt;

&lt;p&gt;Authentication worked instantly and I no longer had the api rate limit error.&lt;/p&gt;

&lt;p&gt;That's the short story. Now let's explain how to use this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Installation
&lt;/h4&gt;

&lt;p&gt;You need to have a working nikola setup. If you dont have one, you can check this article: link://slug/nikola-blog-setup&lt;/p&gt;

&lt;p&gt;To install the plugin, run 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;nikola plugin -i github_widget

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Optional Configuration
&lt;/h4&gt;

&lt;p&gt;For enhanced API usage, add your GitHub API token to &lt;code&gt;conf.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add your GitHub API token here
GITHUB\_API\_TOKEN = 'your\_github\_api\_token\_here'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step is optional but recommended to avoid API rate limit issues.&lt;/p&gt;

&lt;p&gt;Your personal token should allow access to the repositories and its contents. Read-only permission is enough.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using the Shortcode
&lt;/h4&gt;

&lt;p&gt;Here are some examples of how to use the shortcode in your markdown files:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://diegocarrasco.com/listings/listing-github-widget-examples.md.html"&gt;listing-github-widget-examples.md&lt;/a&gt;&lt;a href="https://diegocarrasco.com/listings/listing-github-widget-examples.md"&gt;(Source)&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Basic Example
{{% github_widget %}}user/repo{{% /github_widget %}}

// Example with Avatar and Custom Width
{{% github_widget avatar=true max_width=400px %}}user/repo{{% /github_widget %}}

// Example with Latest Release and Commit Info
{{% github_widget avatar=true latest_release=true latest_commit=true max_width=400px %}}user/repo{{% /github_widget %}}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Customization
&lt;/h4&gt;

&lt;p&gt;You can customize the widget to display various details such as the repository owner's avatar, the latest release, and the latest commit. Adjust the &lt;code&gt;max_width&lt;/code&gt; parameter to fit the widget into your site's layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual Examples
&lt;/h3&gt;

&lt;p&gt;Here's what the widgets look like with the example shortcodes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cbAES3Aw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/github-widget/example-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cbAES3Aw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/github-widget/example-1.png" alt="Basic Example" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Avatar and Custom Width&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R1kqVmU6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/github-widget/example-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R1kqVmU6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/github-widget/example-2.png" alt="With Avatar" width="400" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Latest Release and Commit Info&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fkc22574--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/github-widget/example-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fkc22574--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/github-widget/example-3.png" alt="With Latest Info" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  CSS Customization
&lt;/h4&gt;

&lt;p&gt;To style the widget, you can use the following CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/\* github shortcode \*/
.github-widget {
display: flex;
align-items: center;
border: 1px solid #ddd;
padding: 10px;
margin: 10px 0;
border-radius: 5px;
background-color: #f9f9f9;
}

.github-widget-image {
margin-right: 10px;
}

.github-widget img {
border-radius: 50%;
}

.github-widget .repo-info {
display: flex;
flex-direction: column;
}

.github-widget .repo-info h3 {
margin: 0;
font-size: 1.2em;
}

.github-widget .repo-info p {
margin: 5px 0;
font-size: 0.9em;
color: #555;
}

.github-widget .repo-info ul {
list-style: none;
padding: 0;
display: flex;
gap: 10px;
}

.github-widget .repo-info ul li {
font-size: 0.8em;
color: #333;
}

.github-widget h4 {
color: black;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The GitHub Widget Plugin for Nikola makes it easy to display detailed information about any GitHub repository on your site. With simple configuration and usage, it's a great addition for any developer's blog or project page.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://getnikola.com/extending.html"&gt;Nikola Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/rest"&gt;GitHub API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/PyGithub/PyGithub"&gt;PyGithub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nikola</category>
      <category>nikolagithubwidget</category>
      <category>opensource</category>
      <category>projects</category>
    </item>
    <item>
      <title>How to Optimize and Free Up Disk Space on Debian/Ubuntu Servers with Docker Containers</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Thu, 27 Jun 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/how-to-optimize-and-free-up-disk-space-on-debianubuntu-servers-with-docker-containers-3h2c</link>
      <guid>https://dev.to/dacog/how-to-optimize-and-free-up-disk-space-on-debianubuntu-servers-with-docker-containers-3h2c</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tNQqEhX8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/optimize-free-up-disk-space-debian-ubuntu-docker.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tNQqEhX8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/optimize-free-up-disk-space-debian-ubuntu-docker.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;Manage disk space on Debian/Ubuntu servers and Docker containers by removing unnecessary packages, cleaning up caches, and pruning Docker objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I needed to free up space as I had a small VPS with full storage, and my notebook and desktop computers had also a really high disk usage, although I did not have that many files, but I do use a lot of docker.&lt;/p&gt;

&lt;p&gt;After researching I did not find a guide with everything I needed (explanations included), thus here it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Package Manager (&lt;code&gt;apt&lt;/code&gt;)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Remove packages that are no longer required
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get autoremove

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Clean Up APT Cache
&lt;/h4&gt;

&lt;p&gt;Check the space used by the APT cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo du -sh /var/cache/apt

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean up the APT cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get autoclean
sudo apt autoclean

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete cache files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get clean
sudo apt clean

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clear Systemd Journal Logs
&lt;/h3&gt;

&lt;p&gt;Check the disk usage of systemd journal logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;journalctl --disk-usage

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean logs older than 3 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo journalctl --vacuum-time=3d

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Docker
&lt;/h3&gt;

&lt;p&gt;Docker takes a lot of space compared to vanilla servers. Check link:/slug/change-docker-data-directory-vps-optimization for a related post on the overlay2 and how to move docker data root to another volume/ drive.&lt;/p&gt;

&lt;h4&gt;
  
  
  Check system usage
&lt;/h4&gt;

&lt;p&gt;Check overall system usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker system df

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more detailed information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker system df -v

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use docker system prune
&lt;/h3&gt;

&lt;p&gt;(from &lt;a href="https://docs.docker.com/engine/reference/commandline/system_prune/"&gt;documentation&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;WARNING! This will remove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all stopped containers&lt;/li&gt;
&lt;li&gt;all networks not used by at least one container&lt;/li&gt;
&lt;li&gt;all dangling images&lt;/li&gt;
&lt;li&gt;all build cache
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker system prune

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Use Docker Container Prune
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; This will remove all stopped containers. Refer to the &lt;a href="https://docs.docker.com/engine/reference/commandline/container_prune/"&gt;documentation&lt;/a&gt; for more details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker container prune # Remove all stopped containers

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Use Docker Image Prune
&lt;/h5&gt;

&lt;p&gt;Remove unused images (Remove all dangling images. If &lt;code&gt;-a&lt;/code&gt; is specified, will also remove all images not referenced by any container.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick note:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What are Docker Dangling Images?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Images that have no tag and are not referenced by any container &lt;a href="https://www.howtogeek.com/devops/what-are-dangling-docker-images/"&gt;source&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Untagged layers that serve no purpose but still consume disk space.&lt;/li&gt;
&lt;li&gt;Not automatically removed by Docker and need to be cleaned up manually. &lt;a href="https://www.baeldung.com/ops/docker-remove-dangling-unused-images"&gt;source&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker image prune

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Use docker volume prune
&lt;/h4&gt;

&lt;p&gt;Remove all unused local volumes. Unused local volumes are those which are not referenced by any containers. By default, it only removes anonymous volumes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker volume prune # remove only anonymous (unnamed) volumes

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This command removes only anonymous (unnamed) volumes by default.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To remove all unused volumes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker volume prune -a # remove all unused volumes

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://itsfoss.com/free-up-space-ubuntu-linux/"&gt;How to Free Up Space on Ubuntu Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/reference/commandline/system_df/"&gt;Docker System DF Command Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Related tools I found interesting during my search
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/stepchowfun/docuum"&gt;Docuum Tool for Docker Garbage Collection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>debian</category>
      <category>diskusage</category>
      <category>docker</category>
      <category>servermaintenance</category>
    </item>
    <item>
      <title>Exciting News: My Upcoming Book "The Digital Marketer’s Playbook" is about to launch</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Wed, 26 Jun 2024 07:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/exciting-news-my-upcoming-book-the-digital-marketers-playbook-is-about-to-launch-49in</link>
      <guid>https://dev.to/dacog/exciting-news-my-upcoming-book-the-digital-marketers-playbook-is-about-to-launch-49in</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SkjsemyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/digital-marketers-playbook-launch.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SkjsemyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/digital-marketers-playbook-launch.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am thrilled to share some exciting news about my forthcoming book &lt;strong&gt;"The Digital Marketer’s Playbook: How to Effectively Collaborate with Agencies, Freelancers, and Digital Marketing Experts,"&lt;/strong&gt; to be published by Apress (Springer-Nature). The book is targeted for release by the end of Q3 or Q4 2024. That's this year!&lt;/p&gt;

&lt;p&gt;If you've followed my blog, you might recall that I &lt;a href="https://diegocarrasco.com/digital-marketing-playbook/"&gt;initially conceived&lt;/a&gt; this project as a short book. My idea was to write a practical guide with the main topics related to digital marketing. It has now evolved into a comprehensive resource. Designed for professionals grounded in marketing or business and for those particularly interested in the field, it guides readers through the complexities of digital marketing, emphasizing effective collaboration with various partners. I think the title of the book is also self-explanatory. 😁&lt;/p&gt;

&lt;h3&gt;
  
  
  The Journey and Collaboration
&lt;/h3&gt;

&lt;p&gt;The book has evolved significantly over the past few months. My &lt;a href="https://diegocarrasco.com/digital-marketing-playbook/"&gt;first post&lt;/a&gt; about it marked the beginning of this journey. Since then, ten months later, I've moved away from the idea of self-publishing for this project, choosing instead to sign to go with traditional publishing. This decision came after discussing the book proposal with Shivangi Ramachandran, an Apress Senior Editor (Acquisitions), which ended with me signin with Apress (Springer-Nature).&lt;/p&gt;

&lt;p&gt;Partnering with them and working closely with Shiva and Sowmya Thodur (Production Editor), brought about substantial changes. After signing, I received a lot of guidelines regarding the structure how the book, which made me realize that the chapters were more that just a compilation of important points and I had to elaborate on them. These changes quickly expanded the book into a comprehensive 250+ page resource. That structured approach to writing required me to rethink and rewrite many sections of the book.&lt;/p&gt;

&lt;p&gt;Throughout this journey, I have dedicated countless hours refining the content, often late into the night. My amazing wife’s patience has been invaluable, and I cannot thank her enough for her support. Throughout the entire process, she also served as a thoughtful partner, sharing her insights and candid comments.&lt;/p&gt;

&lt;p&gt;Additionally, the &lt;a href="https://www.uph.de/"&gt;Unperfekthaus&lt;/a&gt; in Essen provided a perfect environment with their focus room and endless coffee, where I spent nearly three days a week until closing time last month to finish the manuscript.&lt;/p&gt;

&lt;p&gt;I also have to thank my colleagues at &lt;a href="https://www.mehrkanal.com/"&gt;MEHRKANAL&lt;/a&gt;, especially Miri and Mario, for enduring my questions and serving as sparring partners on several book topics. They often heard me talk about the book, perhaps more than they would have liked. Victor and Eva, who gave me detailed feedback on the first version of the Table of Content. Damian, Tom, Holger, Christian also listened to my thoughts on the book and gave their feedback. There are many others whose names escape my memory, as it's again late into the night.&lt;/p&gt;

&lt;p&gt;Although many of them saw this as just another item on my never ending list of personal projects, I'm thrilled it has become a reality. 😎&lt;/p&gt;

&lt;p&gt;I wrapped up the manuscript in early June, fueled by an impressive coffee intake—seriously, about 4-6 cups per session! Thanks to the patience of many, it's now in the capable hands of the Apress team for review. Can't wait to share it with you soon!&lt;/p&gt;

&lt;h3&gt;
  
  
  A quick preface before diving into the details
&lt;/h3&gt;

&lt;p&gt;This project has not only deepened my grasp of familiar topics; it has also allowed me to enrich the manuscript with innovative content driven by the latest trends and technologies in digital marketing.&lt;/p&gt;

&lt;p&gt;Some chapters turned out shorter than anticipated, while others demanded more detail. I focused on keeping the content both core and practical, but ultimately, you'll be the judge of that.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates and sneak peeks of the book! I am excited to share this resource with those of you eager to master digital marketing.&lt;/p&gt;

&lt;p&gt;If you want to be among the first to explore "The Digital Marketer’s Playbook," please fill out the form below.&lt;/p&gt;

&lt;p&gt;Click here to show form&lt;/p&gt;

&lt;h3&gt;
  
  
  What will you learn by reading the book?
&lt;/h3&gt;

&lt;p&gt;This book is my effort to provide you an all-inclusive resource to enhance your understanding of &lt;strong&gt;digital marketing&lt;/strong&gt; and equip you with the skills and knowledge to work effectively with various partners in the field.&lt;/p&gt;

&lt;p&gt;My goal throughout its pages is to provide you with everything you need to communicate your requirements to your partners, understand what they do and ask the right questions when you need to. I define digital marketing as a process, and that's also how the book is structured.&lt;/p&gt;

&lt;p&gt;Within its pages, I guide you through the foundational concepts of digital marketing. You'll grasp what digital marketing is, familiarize yourself with crucial terms like digital assets, advertising channels, and customer awareness, and learn to distinguish between walled gardens and the open internet. This knowledge will be essential for discussing your goals and your campaigns implementations with your partners. I also describe the landscape of taxes and laws regarding digital marketing and how it can impact your digital marketing efforts.&lt;/p&gt;

&lt;p&gt;As you dive deeper, I'll show you how to set up and structure digital marketing campaigns effectively. You'll understand bid strategies, ad quality, and the importance of placements and inventory. We'll explore various campaign types and their significance, focusing on how to craft a briefing to get impactful creatives, messages, and copy to achieve marketing success and align your digital marketing initiatives with your business goals.&lt;/p&gt;

&lt;p&gt;Finally, I offer practical examples tailored to various company types, detailing key factors to consider based on company size, resources, and business structure. I also share my perspective on using artificial intelligence in digital marketing, discussing both its benefits and risks. Additionally, I provide an overview of social media and its role in digital marketing.&lt;/p&gt;

&lt;p&gt;Ready to dive deeper into digital marketing? Sign up below to receive updates on "The Digital Marketer’s Playbook" and access exclusive digital marketing resources.&lt;/p&gt;

</description>
      <category>apress</category>
      <category>books</category>
      <category>digitalmarketersplay</category>
      <category>projects</category>
    </item>
    <item>
      <title>Quick and simple Local WordPress Setup for Lazy Developers</title>
      <dc:creator>Diego Carrasco Gubernatis</dc:creator>
      <pubDate>Tue, 25 Jun 2024 06:00:00 +0000</pubDate>
      <link>https://dev.to/dacog/quick-and-simple-local-wordpress-setup-for-lazy-developers-5292</link>
      <guid>https://dev.to/dacog/quick-and-simple-local-wordpress-setup-for-lazy-developers-5292</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i-U6NgWk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/simple-docker-compose-wordpress-setup.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i-U6NgWk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://diegocarrasco.com/images/social-images/simple-docker-compose-wordpress-setup.jpg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick and simple WordPress Setup for Lazy Developers
&lt;/h3&gt;

&lt;p&gt;I needed a fast way to set up WordPress locally. I tried various methods, but they were either too complex or didn't work. So, I created a simple, lazy solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is by no way secure, but it runs on the first try 😁&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The code is in this GitHub repository. Feel free to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;This setup revolves around 4 files:&lt;/p&gt;

&lt;h4&gt;
  
  
  1 &lt;strong&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;/strong&gt; :
&lt;/h4&gt;

&lt;p&gt;This file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses the latest official containers for WordPress, MariaDB, PHPMyAdmin, and WP-CLI.&lt;/li&gt;
&lt;li&gt;Sets up a &lt;code&gt;wordpress&lt;/code&gt; database with user and password &lt;code&gt;root&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Launches a WordPress instance linked to the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2 &lt;strong&gt;&lt;code&gt;setup.sh&lt;/code&gt;&lt;/strong&gt; :
&lt;/h4&gt;

&lt;p&gt;This script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detects whether you have &lt;code&gt;docker-compose&lt;/code&gt; or &lt;code&gt;docker compose&lt;/code&gt; and uses the correct one.&lt;/li&gt;
&lt;li&gt;Sets your UID and GID in a &lt;code&gt;.env&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Generates an alias file for quick commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3 &lt;strong&gt;&lt;code&gt;start.sh&lt;/code&gt;&lt;/strong&gt; :
&lt;/h4&gt;

&lt;p&gt;This script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates the WordPress directory.&lt;/li&gt;
&lt;li&gt;Sets permissions to 777 (yes, it's insecure).&lt;/li&gt;
&lt;li&gt;Starts Docker Compose.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4 &lt;strong&gt;&lt;code&gt;alias.sh&lt;/code&gt;&lt;/strong&gt; :
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Autogenerated&lt;/strong&gt; by &lt;code&gt;setup.sh&lt;/code&gt; or &lt;code&gt;start.sh&lt;/code&gt;. Source it to get these aliases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dc&lt;/code&gt;: Docker Compose commands.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wpcli&lt;/code&gt;: WP-CLI commands.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wpbackup&lt;/code&gt;: Backs up the database to &lt;code&gt;./backups&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wpdown&lt;/code&gt;: Backs up and then stops and removes containers and volumes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Use
&lt;/h3&gt;

&lt;p&gt;First you need to clone the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/dacog/lazy-docker-compose-wordpress-setup.git
cd lazy-docker-compose-wordpress-setup

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run these commands to get started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x setup.sh
chmod +x start.sh
./start.sh
source alias.sh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are good to go. You will see a new folder &lt;code&gt;wordpress&lt;/code&gt; is created in the path you were in.&lt;/p&gt;

&lt;p&gt;Now you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt; for the WordPress site&lt;/li&gt;
&lt;li&gt;Check &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt; for PHPMyAdmin. User and password is root&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You receive this information also when you run &lt;code&gt;start.sh&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the Aliases
&lt;/h3&gt;

&lt;h4&gt;
  
  
  alias &lt;code&gt;dc&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Bring up the services:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dc up -d

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Stop the services:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dc down

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Stop and remove volumes:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dc down -v

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;View the status of the services:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dc ps

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  alias &lt;code&gt;wpcli&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Run WP-CLI as root (it includes &lt;code&gt;--allow-root&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check WordPress version:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wpcli core version

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install a plugin:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wpcli plugin install hello-dolly --activate

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Update WordPress core:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wpcli core update

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a new post:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wpcli post create --post_title='My New Post' --post_content='This is the content of the post.' --post_status=publish

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;wpbackup&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Back up the database to &lt;code&gt;./backups&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;wpdown&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Back up the database and files, then stop and remove everything:&lt;br&gt;
&lt;/p&gt;

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alternatives
&lt;/h3&gt;

&lt;p&gt;Here are some other methods to consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://localwp.com/"&gt;Local by Flywheel&lt;/a&gt;&lt;/strong&gt;: User-friendly local WordPress setup with advanced features. To be fair, I completely forgot about this when I was trying to get WordPress to run locally. This is way more powerful, but you need many clicks... and you need to fill a form to download it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://kinsta.com/de/devkinsta/"&gt;DevKinsta&lt;/a&gt;&lt;/strong&gt;: Offers local development with easy deployment to Kinsta hosting. I haven't tried this one.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>bash</category>
      <category>development</category>
      <category>docker</category>
      <category>dockercompose</category>
    </item>
  </channel>
</rss>
