<?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>Forem: Fedya Serafiev</title>
    <description>The latest articles on Forem by Fedya Serafiev (@fedya_serafiev).</description>
    <link>https://forem.com/fedya_serafiev</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%2F3690986%2F1d5ca9fa-da0b-4c41-902f-b7320a8e9993.jpg</url>
      <title>Forem: Fedya Serafiev</title>
      <link>https://forem.com/fedya_serafiev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fedya_serafiev"/>
    <language>en</language>
    <item>
      <title>Automated Secure Hosting with Cloudflare Tunnel &amp; Docker</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Sun, 29 Mar 2026 04:33:45 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/automated-secure-hosting-with-cloudflare-tunnel-docker-504h</link>
      <guid>https://forem.com/fedya_serafiev/automated-secure-hosting-with-cloudflare-tunnel-docker-504h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📖 &lt;em&gt;This article is a translation of the original post published on &lt;a href="https://itpraktika.com/hosting-s-cloudflare-tunnel/" rel="noopener noreferrer"&gt;ITpraktika.com&lt;/a&gt; (Bulgarian).&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;If you own a server — whether a VPS or a home machine — and want to host websites or monitoring tools, security and configuration can quickly become a headache. This post introduces a single Bash script that handles everything for you: from generating strong passwords to spinning up a fully isolated Docker environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛡️ What Does This Script Do?
&lt;/h2&gt;

&lt;p&gt;This tool is built for people who want a professional-grade setup with minimal effort. It automates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt; — Connects your server to Cloudflare's network &lt;em&gt;without&lt;/em&gt; opening ports 80 or 443 on your router or firewall. Your server stays invisible to bots and scanners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uptime Kuma&lt;/strong&gt; — Installs one of the best open-source monitoring tools for tracking your sites and services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WordPress support&lt;/strong&gt; — Optionally spins up to 2 independent WordPress sites, each with its own isolated database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maximum security&lt;/strong&gt; — Generates unique 24-character passwords for every component and sets proper file permissions on all config files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Healthchecks&lt;/strong&gt; — Intelligently waits for MariaDB to be fully ready before starting your sites, preventing startup race conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ How to Use It
&lt;/h2&gt;

&lt;p&gt;The entire setup takes less than a minute. SSH into your Linux server and run these three commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Download the script:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://gist.fedia.eu/urocibg/8edf74d152594176a1052308054ed36c/raw/HEAD/setup_hosting.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Make it executable:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x setup_hosting.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Run the installer:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./setup_hosting.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📋 What Happens Next?
&lt;/h2&gt;

&lt;p&gt;The script will ask you a few questions — whether you want Uptime Kuma, how many WordPress sites you need, and your Cloudflare tunnel token. Once you answer, it generates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An &lt;code&gt;.env&lt;/code&gt; file containing all your passwords.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;docker-compose.yml&lt;/code&gt; with optimized settings.&lt;/li&gt;
&lt;li&gt;An initialization SQL script for your databases.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you've answered all the questions, the script takes care of the rest — including starting all the containers. Your entire infrastructure will be online automatically. 🎉&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This script is an ideal solution for developers and sysadmins looking for the right balance between cost, security, and ease of maintenance.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Original article (Bulgarian): &lt;a href="https://itpraktika.com/hosting-s-cloudflare-tunnel/" rel="noopener noreferrer"&gt;https://itpraktika.com/hosting-s-cloudflare-tunnel/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>cloudflare</category>
      <category>devops</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>I built my first website in 2004. Here's what I wish someone had told me.</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Sat, 21 Mar 2026 08:45:43 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/i-built-my-first-website-in-2004-heres-what-i-wish-someone-had-told-me-3jg1</link>
      <guid>https://forem.com/fedya_serafiev/i-built-my-first-website-in-2004-heres-what-i-wish-someone-had-told-me-3jg1</guid>
      <description>&lt;h2&gt;
  
  
  A honest letter from a grandfather who codes — to everyone who thinks they started too late.
&lt;/h2&gt;

&lt;p&gt;Most of you reading this were probably still figuring out what "the internet" even was. I wasn't young. I wasn't fresh out of university. I wasn't some prodigy who grew up with a keyboard in my hands. I was just a person who was genuinely, deeply curious — and that turned out to be enough.&lt;/p&gt;

&lt;p&gt;The site was called &lt;strong&gt;fedia design&lt;/strong&gt;. Pure HTML. A little CSS. No frameworks, no npm, no Stack Overflow (well, barely). If something broke, you stared at it until you understood why. That kind of learning leaves marks. Good ones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Talent is just patience that hasn't been named yet."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Nobody tells you this part
&lt;/h2&gt;

&lt;p&gt;I've watched colleagues throw around words they don't fully understand — big architectural terms, trendy acronyms, names dropped like currency. I made a choice early on: I would rather explain something simply and be understood, than sound impressive and leave someone confused. The goal was never to impress. It was to be useful.&lt;/p&gt;

&lt;p&gt;Every article I write, every tutorial I put together — I ask myself: would someone reading this for the first time actually get it? If not, I rewrite it. Not because I think I'm a great teacher. Because I remember exactly what it felt like not to understand something, and how isolating that can be.&lt;/p&gt;

&lt;p&gt;Write for the person you were when you didn't understand anything yet.&lt;/p&gt;




&lt;h2&gt;
  
  
  IT is not a young person's game
&lt;/h2&gt;

&lt;p&gt;I was already well into my adult life when I seriously started working in tech. People looked at me sideways sometimes. I looked back, smiled, and kept learning. Today I'm a grandfather. And I still write code. I still get excited when something clicks. I still break things and fix them at odd hours of the night.&lt;/p&gt;

&lt;p&gt;If you think you're too old to start — you're not. If you think you're not talented enough — talent is just patience that hasn't been named yet. What you need isn't a gift. What you need is to be genuinely interested, stubborn enough to keep going, and honest enough to ask for help when you're stuck.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually believe
&lt;/h2&gt;

&lt;p&gt;We have a responsibility to each other in this field. The more experienced you get, the more you should simplify — not complicate. Share what you know in plain language. Make it easier for the next person. That's how this whole thing grows.&lt;/p&gt;

&lt;p&gt;I'm proud of &lt;strong&gt;fedia design&lt;/strong&gt;. I'm proud of every broken tag, every misaligned div, every CSS hack that somehow worked. That's where it all started. And I'm still here, still building, still learning — just with a few more grey hairs and a lot more perspective.&lt;/p&gt;

&lt;p&gt;If you're just starting out: &lt;strong&gt;welcome. You're going to be fine.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to follow more of my work or see what I've been building, you can find me at &lt;a href="https://itpraktika.com/" rel="noopener noreferrer"&gt;itpraktika.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>motivation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Install Paperless-ngx with Docker Compose on Ubuntu</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Sat, 21 Mar 2026 08:02:48 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/how-to-install-paperless-ngx-with-docker-compose-on-ubuntupublished-5h3l</link>
      <guid>https://forem.com/fedya_serafiev/how-to-install-paperless-ngx-with-docker-compose-on-ubuntupublished-5h3l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📄 This article is a translation and adaptation of the original post published in Bulgarian at &lt;a href="https://itpraktika.com/instalirane-na-paperless-ngx-s-docker-compose/" rel="noopener noreferrer"&gt;itpraktika.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Managing documents in a digital environment can quickly become overwhelming — especially as the number of files (PDFs, DOC files, scanned images) grows. &lt;strong&gt;Paperless-ngx&lt;/strong&gt; is a modern Document Management System (DMS) that offers automatic indexing, OCR (Optical Character Recognition), and a powerful search engine.&lt;/p&gt;

&lt;p&gt;In this guide, we'll walk through step by step how to install and configure Paperless-ngx using Docker Compose on Ubuntu, so it runs reliably and stably.&lt;/p&gt;




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

&lt;p&gt;Before we begin, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu server (20.04 or newer)&lt;/li&gt;
&lt;li&gt;Docker installed&lt;/li&gt;
&lt;li&gt;Docker Compose installed&lt;/li&gt;
&lt;li&gt;Terminal access (SSH)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If you don't have Docker installed yet, check the official Docker documentation or a guide for your specific distro.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 1: Prepare the Directory Structure
&lt;/h2&gt;

&lt;p&gt;Create the necessary folders for storing data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /data/paperless/&lt;span class="o"&gt;{&lt;/span&gt;data,media,export,consume,db&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each folder is for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt; – metadata&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;media&lt;/code&gt; – the actual document files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;export&lt;/code&gt; – exported documents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;consume&lt;/code&gt; – incoming folder for automatic import&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;db&lt;/code&gt; – database files&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2: Create the docker-compose.yml File
&lt;/h2&gt;

&lt;p&gt;Create the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then paste in the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;broker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:7&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless-redis&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis-server --save "" --appendonly no&lt;/span&gt;

  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:15&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless-db&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless_password_change_me&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/data/paperless/db:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;paperless"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;webserver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/paperless-ngx/paperless-ngx:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;
      &lt;span class="na"&gt;broker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_started&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_REDIS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis://broker:6379&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_DBHOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_DBNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_DBUSER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_DBPASS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paperless_password_change_me&lt;/span&gt;

      &lt;span class="c1"&gt;# Uncomment if using a domain:&lt;/span&gt;
      &lt;span class="c1"&gt;# PAPERLESS_URL: https://paperless.yourdomain.com&lt;/span&gt;
      &lt;span class="c1"&gt;# PAPERLESS_CSRF_TRUSTED_ORIGINS: https://paperless.yourdomain.com&lt;/span&gt;

      &lt;span class="na"&gt;PAPERLESS_SECRET_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;change_me_to_something_long_and_random"&lt;/span&gt;
      &lt;span class="na"&gt;USERMAP_UID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;
      &lt;span class="na"&gt;USERMAP_GID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;

      &lt;span class="na"&gt;PAPERLESS_OCR_LANGUAGE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eng&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_TIME_ZONE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Europe/London&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_OCR_LANGUAGES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eng&lt;/span&gt;

      &lt;span class="na"&gt;PAPERLESS_CONSUMER_POLLING&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
      &lt;span class="na"&gt;PAPERLESS_FILENAME_FORMAT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{created_year}/{correspondent}/{title}"&lt;/span&gt;

    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/data/paperless/data:/usr/src/paperless/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/data/paperless/media:/usr/src/paperless/media&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/data/paperless/export:/usr/src/paperless/export&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/data/paperless/consume:/usr/src/paperless/consume&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🔐 &lt;strong&gt;Important:&lt;/strong&gt; Change &lt;code&gt;paperless_password_change_me&lt;/code&gt; and &lt;code&gt;PAPERLESS_SECRET_KEY&lt;/code&gt; to strong, unique values before deploying.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Start the Containers
&lt;/h2&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few seconds, the system will be accessible at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://YOUR_SERVER_IP:8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Create an Admin User
&lt;/h2&gt;

&lt;p&gt;No default user is created automatically. You need to create one manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; paperless python3 manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be prompted to enter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username&lt;/li&gt;
&lt;li&gt;Email (optional)&lt;/li&gt;
&lt;li&gt;Password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, you can log into the web interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Working with Documents
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Uploading Files
&lt;/h3&gt;

&lt;p&gt;You have several options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; Drop&lt;/strong&gt; in the browser&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Upload&lt;/strong&gt; button in the UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic import&lt;/strong&gt; via the consume folder:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.pdf /data/paperless/consume/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All files placed in that folder will be processed automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: ⚠️ Domain Configuration (IMPORTANT)
&lt;/h2&gt;

&lt;p&gt;If you plan to use a domain (e.g., behind Cloudflare or nginx), you &lt;strong&gt;must&lt;/strong&gt; add the following environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;PAPERLESS_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://your-domain.com&lt;/span&gt;
&lt;span class="na"&gt;PAPERLESS_CSRF_TRUSTED_ORIGINS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://your-domain.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ &lt;strong&gt;Important notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do &lt;strong&gt;NOT&lt;/strong&gt; add a trailing slash &lt;code&gt;/&lt;/code&gt; at the end of the URL&lt;/li&gt;
&lt;li&gt;If you use &lt;code&gt;www&lt;/code&gt;, add both versions:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;PAPERLESS_CSRF_TRUSTED_ORIGINS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://your-domain.com,https://www.your-domain.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why is this necessary?
&lt;/h3&gt;

&lt;p&gt;Without these settings, you will get a &lt;code&gt;403 CSRF verification failed&lt;/code&gt; error. This is a built-in security mechanism that requires the domain to be explicitly trusted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Can't log in
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make sure you created a superuser (Step 4)&lt;/li&gt;
&lt;li&gt;Try clearing your browser cache/cookies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. OCR not working
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Verify that all containers are running: &lt;code&gt;docker compose ps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check language settings in your environment variables&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Slow processing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is normal during the initial indexing phase&lt;/li&gt;
&lt;li&gt;OCR is CPU-intensive — be patient on lower-end hardware&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use strong, unique passwords&lt;/li&gt;
&lt;li&gt;Set up regular backups:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  rsync &lt;span class="nt"&gt;-av&lt;/span&gt; /data/paperless /backup/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;/consume&lt;/code&gt; folder to automate document ingestion&lt;/li&gt;
&lt;li&gt;Organize documents with tags and correspondents from the start&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Once you've completed the setup, you'll quickly appreciate how much easier document management becomes. Paperless-ngx isn't just a file store — it's a tool that genuinely saves time when searching, sorting, and organizing information.&lt;/p&gt;

&lt;p&gt;A few long-term recommendations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up automated backups from day one&lt;/li&gt;
&lt;li&gt;Use a domain with HTTPS if accessible over the internet&lt;/li&gt;
&lt;li&gt;Restrict access if the instance is publicly reachable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't be afraid to experiment. Paperless-ngx has a lot of automation and customization options you can tune to your workflow. With the right setup and a small initial investment of time, you'll have a fast, reliable, and user-friendly document management system.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;📄 Original article in Bulgarian: &lt;a href="https://itpraktika.com/instalirane-na-paperless-ngx-s-docker-compose/" rel="noopener noreferrer"&gt;Как да инсталираме Paperless-ngx с Docker Compose&lt;/a&gt; — itpraktika.com&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>docker</category>
      <category>selfhosted</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Docker Compose Secrets: How to Stop Hardcoding Passwords in Your docker-compose.yml</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Thu, 19 Feb 2026 06:49:11 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/docker-compose-secrets-how-to-stop-hardcoding-passwords-in-your-docker-composeyml-13fb</link>
      <guid>https://forem.com/fedya_serafiev/docker-compose-secrets-how-to-stop-hardcoding-passwords-in-your-docker-composeyml-13fb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📝 &lt;em&gt;This is a translated and adapted version of the original article published in Bulgarian at &lt;a href="https://itpraktika.com/docker-compose-secrets/" rel="noopener noreferrer"&gt;itpraktika.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;We've all done it. You're spinning up a new project, you need a database, and you write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysupersecretpassword123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. You commit it. You push it to GitHub.&lt;/p&gt;

&lt;p&gt;And just like that, your database password is now public. Forever. Even if you delete it later, it lives in the git history.&lt;/p&gt;

&lt;p&gt;In this article I'll show you &lt;strong&gt;three proper ways&lt;/strong&gt; to handle secrets in Docker Compose — from simple to production-grade — so you never have to hardcode credentials again.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Is a Real Problem
&lt;/h2&gt;

&lt;p&gt;Before we jump into solutions, let's be clear about what's at stake.&lt;/p&gt;

&lt;p&gt;Hardcoded secrets in &lt;code&gt;docker-compose.yml&lt;/code&gt; are dangerous because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git history never forgets.&lt;/strong&gt; Even if you remove the password in the next commit, anyone with access to your repo history can find it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It scales badly.&lt;/strong&gt; The same file gets used in dev, staging, and production — with the same credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It violates the 12-factor app principle&lt;/strong&gt; of strict separation between config and code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's the #1 source of credential leaks&lt;/strong&gt; in public repositories. GitHub scans for these patterns automatically and will warn you — but the damage is already done.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Method 1: &lt;code&gt;.env&lt;/code&gt; Files (Quick Win for Development)
&lt;/h2&gt;

&lt;p&gt;The simplest improvement. Instead of hardcoding values directly, you reference them as variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Create a &lt;code&gt;.env&lt;/code&gt; file:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .env&lt;/span&gt;
&lt;span class="nv"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;myapp
&lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;a-much-safer-password
&lt;span class="nv"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production_db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Reference it in &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_USER}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_PASSWORD}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_DB}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker Compose automatically reads &lt;code&gt;.env&lt;/code&gt; from the same directory — no extra configuration needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — The most important part. Add &lt;code&gt;.env&lt;/code&gt; to &lt;code&gt;.gitignore&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".env"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Provide a safe template for your team:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .env.example  ← commit this one&lt;/span&gt;
&lt;span class="nv"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Pros:&lt;/strong&gt; Simple, zero dependencies, works everywhere.&lt;br&gt;
⚠️ &lt;strong&gt;Cons:&lt;/strong&gt; The &lt;code&gt;.env&lt;/code&gt; file still lives as plaintext on disk. Fine for development, not ideal for production.&lt;/p&gt;


&lt;h2&gt;
  
  
  Method 2: Docker Secrets (Production-Ready)
&lt;/h2&gt;

&lt;p&gt;Docker has a built-in secrets management system. Secrets are stored encrypted in memory and are &lt;strong&gt;never written to disk or exposed as environment variables&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; Docker Secrets in this form require &lt;strong&gt;Docker Swarm mode&lt;/strong&gt; to be initialized. If you're running a single-node setup, you can still use it — just run &lt;code&gt;docker swarm init&lt;/code&gt; once.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Create the secret:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From a string&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"my-super-secret-db-password"&lt;/span&gt; | docker secret create db_password -

&lt;span class="c"&gt;# Or from a file&lt;/span&gt;
docker secret create db_password ./password.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Reference it in &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production_db&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/run/secrets/db_password&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db_password&lt;/span&gt;

&lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db_password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The secret is mounted as a &lt;strong&gt;file&lt;/strong&gt; inside the container at &lt;code&gt;/run/secrets/db_password&lt;/code&gt;. Many official Docker images (PostgreSQL, MySQL, MariaDB) support the &lt;code&gt;_FILE&lt;/code&gt; suffix specifically for this pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Deploy:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stack deploy &lt;span class="nt"&gt;-c&lt;/span&gt; docker-compose.yml myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Pros:&lt;/strong&gt; Secrets are encrypted at rest, never in environment variables, ideal for production.&lt;br&gt;
⚠️ &lt;strong&gt;Cons:&lt;/strong&gt; Requires Swarm mode. Slightly more complex to set up.&lt;/p&gt;


&lt;h2&gt;
  
  
  Method 3: Secrets as Local Files (Swarm-Free Alternative)
&lt;/h2&gt;

&lt;p&gt;If you don't want to use Swarm mode but still want to keep secrets out of your &lt;code&gt;docker-compose.yml&lt;/code&gt;, you can mount secret files directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Create a directory for secrets (outside your project if possible):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ./secrets
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"my-db-password"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./secrets/db_password.txt
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"my-redis-password"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./secrets/redis_password.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Add secrets directory to &lt;code&gt;.gitignore&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"secrets/"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3 — Mount as read-only files in &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production_db&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/run/secrets/db_password&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./secrets/db_password.txt:/run/secrets/db_password:ro&lt;/span&gt;

  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:7-alpine&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sh -c 'redis-server --requirepass "$$(cat /run/secrets/redis_password)"'&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./secrets/redis_password.txt:/run/secrets/redis_password:ro&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Pros:&lt;/strong&gt; No Swarm required, works with standard &lt;code&gt;docker compose up&lt;/code&gt;, keeps secrets out of YAML.&lt;br&gt;
⚠️ &lt;strong&gt;Cons:&lt;/strong&gt; Secret files still live on disk — make sure the host machine is secure.&lt;/p&gt;


&lt;h2&gt;
  
  
  Bonus: Validate That You're Not Leaking Secrets
&lt;/h2&gt;

&lt;p&gt;Before every commit, check that no secrets ended up in your YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search for common patterns in your compose file&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Ei&lt;/span&gt; &lt;span class="s1"&gt;'(password|secret|key|token)\s*[:=]\s*[^\$\{]'&lt;/span&gt; docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this command returns any output — you have a hardcoded secret. Fix it before committing.&lt;/p&gt;

&lt;p&gt;You can also add this as a &lt;strong&gt;pre-commit hook&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .git/hooks/pre-commit&lt;/span&gt;
&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Ei&lt;/span&gt; &lt;span class="s1"&gt;'(password|secret|key|token)\s*[:=]\s*[^\$\{]'&lt;/span&gt; docker-compose.yml&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"❌ Possible hardcoded secret detected in docker-compose.yml. Aborting commit."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make it executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x .git/hooks/pre-commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local development&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.env&lt;/code&gt; file + &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single-server production&lt;/td&gt;
&lt;td&gt;Local secret files (Method 3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-node / orchestrated production&lt;/td&gt;
&lt;td&gt;Docker Secrets (Method 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD pipelines&lt;/td&gt;
&lt;td&gt;Environment variables injected by the CI system (GitHub Actions Secrets, GitLab CI Variables, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Quick Checklist Before You Push
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] No plaintext passwords in &lt;code&gt;docker-compose.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;.env&lt;/code&gt; is in &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;.env.example&lt;/code&gt; exists and is committed (with empty values)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;secrets/&lt;/code&gt; directory is in &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Pre-commit hook is in place&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hardcoding passwords in &lt;code&gt;docker-compose.yml&lt;/code&gt; is one of those habits that's easy to fall into and hard to undo once your repo is public. The good news is that all three methods above are straightforward to implement — even in an existing project.&lt;/p&gt;

&lt;p&gt;Start with &lt;code&gt;.env&lt;/code&gt; files today if you haven't already. It takes five minutes and immediately eliminates the most common source of accidental credential leaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your future self (and your security team) will thank you.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Fedya Serafiev — &lt;a href="https://itpraktika.com" rel="noopener noreferrer"&gt;itpraktika.com&lt;/a&gt; — practical IT solutions and automation.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>security</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why I Stopped Paying for Software: 6 Open Source Tools That Changed How I Work</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Thu, 19 Feb 2026 05:57:12 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/why-i-stopped-paying-for-software-6-open-source-tools-that-changed-how-i-work-1h9f</link>
      <guid>https://forem.com/fedya_serafiev/why-i-stopped-paying-for-software-6-open-source-tools-that-changed-how-i-work-1h9f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📝 &lt;em&gt;This is a translated and adapted version of the original article published in Bulgarian at &lt;a href="https://itpraktika.com/instrumenti-s-otvoren-kod/" rel="noopener noreferrer"&gt;itpraktika.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;As a tech enthusiast, I spent years searching for the perfect toolset. I used to believe that a high price tag guaranteed quality — paying for expensive subscriptions, convinced it was the only way to stay professional.&lt;/p&gt;

&lt;p&gt;Over time, I discovered something remarkable: the world of open source software has evolved beyond recognition. Today, these solutions don't just compete with paid alternatives — they often surpass them.&lt;/p&gt;

&lt;p&gt;In this article, I'm sharing 6 tools that are at the core of my workflow. They save me hundreds of dollars a year and give me complete freedom.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Visual Studio Code (VS Code) — My Digital Home 💻
&lt;/h2&gt;

&lt;p&gt;If I had to pick just one tool, it would be &lt;strong&gt;VS Code&lt;/strong&gt;. Before it, I used paid IDEs — they were bloated and slow. VS Code changed everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it's indispensable:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight, fast, and completely free&lt;/li&gt;
&lt;li&gt;Supports almost every programming language through extensions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IntelliSense&lt;/strong&gt; predicts your next step as you write code&lt;/li&gt;
&lt;li&gt;Integrated terminal and Git built right into the interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why I stopped paying:&lt;/strong&gt; Paid IDEs offer features I rarely use. With VS Code, I only add what I actually need — which keeps it lightning fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Docker — Containerization Without the Headaches 🐳
&lt;/h2&gt;

&lt;p&gt;Before &lt;strong&gt;Docker&lt;/strong&gt;, I constantly heard: &lt;em&gt;"But it works on my machine!"&lt;/em&gt; That was a nightmare for team collaboration. Docker solved that problem once and for all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Packages your software and its dependencies into a "container" so code runs the same everywhere&lt;/li&gt;
&lt;li&gt;Spin up databases and servers in seconds with a single command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Test different technologies without "polluting" your operating system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt; I save hours on environment configuration. Docker is the industry standard — and it's free for my use case.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. LibreOffice — A Full Office Suite, Zero Fees 📝
&lt;/h2&gt;

&lt;p&gt;For a long time I felt trapped by Microsoft 365 subscriptions. Paying a monthly fee just to write documents seemed unnecessary. &lt;strong&gt;LibreOffice&lt;/strong&gt; was my salvation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Opens and saves &lt;code&gt;.docx&lt;/code&gt;, &lt;code&gt;.xlsx&lt;/code&gt;, and &lt;code&gt;.pptx&lt;/code&gt; files without issues&lt;/li&gt;
&lt;li&gt;Writer and Calc cover 100% of my needs for reports and spreadsheets&lt;/li&gt;
&lt;li&gt;Files stay local — not locked in someone else's cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's better:&lt;/strong&gt; LibreOffice is stable, powerful, and doesn't interrupt you with upsell prompts. It's a clean tool built for work.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Obsidian — My "Second Brain" 🧠
&lt;/h2&gt;

&lt;p&gt;Knowledge management is critical. I used to use Notion, but the slow loading and constant need for an internet connection frustrated me. &lt;strong&gt;Obsidian&lt;/strong&gt; changed the way I think.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it special:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All notes are stored as Markdown files on your own computer&lt;/li&gt;
&lt;li&gt;Link ideas together the way your brain actually works&lt;/li&gt;
&lt;li&gt;Graph view gives you a visual map of all your knowledge and projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why I chose it:&lt;/strong&gt; My data is permanent. Even if Obsidian ceases to exist, my notes remain as plain text files I can open anywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Brave Browser — Speed and Privacy by Default 🦁
&lt;/h2&gt;

&lt;p&gt;The browser is the most-used tool in any workflow. Chrome is decent, but it consumes too many resources and tracks your activity. &lt;strong&gt;Brave&lt;/strong&gt; is the better version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built-in ad blocker stops annoying ads automatically&lt;/li&gt;
&lt;li&gt;Blocks trackers that try to profile you&lt;/li&gt;
&lt;li&gt;Pages load significantly faster without the ad overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What I save:&lt;/strong&gt; I no longer pay for premium services just to browse without ads. Brave gives me a clean experience for free.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. GIMP — Professional Design Without a Subscription 🎨
&lt;/h2&gt;

&lt;p&gt;Photoshop is the industry standard, but its price is steep for smaller projects. For image editing, I use &lt;strong&gt;GIMP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layers, masks, filters — everything you need is here&lt;/li&gt;
&lt;li&gt;Hundreds of free plugins that extend its functionality&lt;/li&gt;
&lt;li&gt;Works perfectly on Windows, Linux, and macOS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My experience:&lt;/strong&gt; It took me about a week to get used to the interface. Now I handle everything — from banners to photo retouching — without spending a cent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Paid Alternative&lt;/th&gt;
&lt;th&gt;My Open Source Pick&lt;/th&gt;
&lt;th&gt;Main Benefit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code editing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebStorm&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;VS Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Speed + extensions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Environments&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;VMware&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Containerization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Office suite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Microsoft 365&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LibreOffice&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No subscription&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Notion / Evernote&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Obsidian&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Privacy + offline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Browser&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Chrome / Safari&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Brave&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Design&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Photoshop&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;GIMP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full power&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion: Why Open Source Wins 🏆
&lt;/h2&gt;

&lt;p&gt;Switching to these tools isn't just about saving money. It's about &lt;strong&gt;sustainability&lt;/strong&gt;. Open source software is built by the community, for the community.&lt;/p&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Transparent&lt;/strong&gt; — you know what it does with your data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible&lt;/strong&gt; — you can tailor it exactly to your needs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt; — you'll never get an email about a "price increase"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The open source world is ready for you. Are you ready for it?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published in Bulgarian at &lt;a href="https://itpraktika.com/instrumenti-s-otvoren-kod/" rel="noopener noreferrer"&gt;itpraktika.com&lt;/a&gt; by Fedya Serafiev — a platform dedicated to practical IT solutions and automation.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>productivity</category>
      <category>tools</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Built Software from Scratch with Google Antigravity: My Experience</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Tue, 27 Jan 2026 02:27:34 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/how-i-built-software-from-scratch-with-google-antigravity-my-experience-5dhg</link>
      <guid>https://forem.com/fedya_serafiev/how-i-built-software-from-scratch-with-google-antigravity-my-experience-5dhg</guid>
      <description>&lt;p&gt;To be honest? I was skeptical.&lt;/p&gt;

&lt;p&gt;In a world flooded with AI tools that promise miracles but deliver only basic responses, I approached &lt;strong&gt;Google Antigravity&lt;/strong&gt; with reservations. I thought: &lt;em&gt;"Okay, another chatbot. It'll write me two lines of code and then freeze."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Today I want to tell you why I was wrong. And how in just a few minutes I turned an idea into a professional, working product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Task: Next-Generation PDF Editor
&lt;/h2&gt;

&lt;p&gt;My idea was simple but technically challenging: I wanted to create a &lt;strong&gt;PDF editor that runs entirely in the browser&lt;/strong&gt;. No file uploads to servers, no risk to personal data, no monthly fees. I wanted speed, security, and modern design.&lt;/p&gt;

&lt;p&gt;I asked Antigravity. Instead of the standard &lt;em&gt;"Here's sample code for a button"&lt;/em&gt;, I got something different. I got a &lt;strong&gt;partner&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Process: More Than Just Coding
&lt;/h2&gt;

&lt;p&gt;Antigravity didn't just generate code. It understood context.&lt;/p&gt;

&lt;p&gt;When I asked for a "progress bar", it didn't just add a bar – it connected it with asynchronous processing operations.&lt;/p&gt;

&lt;p&gt;When I said "I want it to look beautiful", it created a modern, "glass" interface with a dark theme and smooth animations that looks like a $50 application.&lt;/p&gt;

&lt;p&gt;Together we built features that typically take days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; Drop system&lt;/strong&gt; for page reordering – intuitive and fast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image to PDF conversion&lt;/strong&gt; – with automatic resizing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart watermarks&lt;/strong&gt; – text or logo, embedded directly into the document&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multilingual support&lt;/strong&gt; – switching between Bulgarian and English with one click&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  The Moment of Truth
&lt;/h2&gt;

&lt;p&gt;The most impressive part wasn't that the code worked. It was how we handled problems. When one library refused to work (due to an outdated version), Antigravity immediately diagnosed the issue, suggested an alternative, and rewrote the logic without losing momentum.&lt;/p&gt;

&lt;p&gt;This isn't just a tool that "executes commands". This is an agent that &lt;strong&gt;thinks in perspective&lt;/strong&gt;. It remembers what we did 5 steps ago, suggests improvements I hadn't thought of, and most importantly – writes code that is structured, clean, and production-ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Today I have a fully functional &lt;strong&gt;PDF Editor&lt;/strong&gt;. It's not just a prototype. This is a tool I use daily. And we made it together – I provided the vision, Antigravity provided the engineering power.&lt;/p&gt;

&lt;p&gt;If you're wondering whether the future of programming is here – yes, it's here. And it's called Google Antigravity.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Download the source code from my *&lt;/em&gt;&lt;a href="https://github.com/fedya-dev/PDF-Editor" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;***&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Created with ❤️ by Fedya Serafiev, Google Antigravity, and *&lt;/em&gt;&lt;a href="https://itpraktika.com/" rel="noopener noreferrer"&gt;ITpraktika.com&lt;/a&gt;***&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Original article in Bulgarian: &lt;a href="https://itpraktika.com/google-antigravity-2/" rel="noopener noreferrer"&gt;https://itpraktika.com/google-antigravity-2/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Critical Issues with Windows 11 January Update (KB5074109): What You Need to Know</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Sat, 24 Jan 2026 12:11:53 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/critical-issues-with-windows-11-january-update-kb5074109-what-you-need-to-know-4ifc</link>
      <guid>https://forem.com/fedya_serafiev/critical-issues-with-windows-11-january-update-kb5074109-what-you-need-to-know-4ifc</guid>
      <description>&lt;p&gt;January 2026 started with challenges for Windows 11 users. Microsoft's latest security update &lt;strong&gt;KB5074109&lt;/strong&gt;, which was supposed to bring stability and security, triggered a wave of technical problems – from system lockups to black screens.&lt;/p&gt;

&lt;p&gt;Although the update patches over 100 vulnerabilities, including three critical zero-day exploits, the cost for many users has been high.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 By The Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;100+&lt;/strong&gt; Patched vulnerabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3&lt;/strong&gt; Critical zero-day exploits fixed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1000+&lt;/strong&gt; Problem reports from users and sysadmins&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔴 Main Symptoms and Issues
&lt;/h2&gt;

&lt;p&gt;Reports from users and system administrators point to several major defects in the new version:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Complete System Lockups
&lt;/h3&gt;

&lt;p&gt;Many users report sudden computer freezing without the familiar Blue Screen of Death (BSOD). The problem is particularly severe when working with graphics-intensive applications such as 3D modeling software (BforArtists/Blender).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Black Screens and Graphics Regressions
&lt;/h3&gt;

&lt;p&gt;Nvidia and AMD graphics card owners are encountering black screens immediately after installation. It appears that changes to the Windows kernel graphics stack conflict with current drivers.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Cloud Storage and Outlook Problems
&lt;/h3&gt;

&lt;p&gt;Applications that store data in OneDrive or Dropbox frequently stop responding (hanging). Classic Outlook is also affected – it either won't start or freezes when attempting to access emails.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Azure Virtual Desktop Errors
&lt;/h3&gt;

&lt;p&gt;Business users report inability to connect remotely (error &lt;code&gt;0x80080005&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 Why Is This Happening?
&lt;/h2&gt;

&lt;p&gt;The KB5074109 update for versions &lt;strong&gt;24H2&lt;/strong&gt; and &lt;strong&gt;25H2&lt;/strong&gt; includes massive changes to &lt;strong&gt;DirectX&lt;/strong&gt; and the &lt;strong&gt;servicing stack&lt;/strong&gt;. These changes aim to optimize the operation of NPUs (neural processors) for AI features in Copilot+ computers, but apparently lead to incompatibility with older drivers and specific File Explorer configurations.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ How to Protect Your System? (Working Solutions)
&lt;/h2&gt;

&lt;p&gt;If you've already installed the update and are experiencing problems, experts recommend the following steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Uninstall the Update
&lt;/h3&gt;

&lt;p&gt;Go to &lt;code&gt;Settings → Windows Update → Update history → Uninstall updates&lt;/code&gt;. Find &lt;code&gt;KB5074109&lt;/code&gt; and select &lt;code&gt;"Uninstall"&lt;/code&gt;. Restart the system immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Pause Automatic Updates
&lt;/h3&gt;

&lt;p&gt;After uninstalling, stop automatic updates for 1-2 weeks until Microsoft releases an official fix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Update Graphics Drivers
&lt;/h3&gt;

&lt;p&gt;Check for the latest WHQL drivers from Nvidia or AMD websites. In some cases, however, rolling back to a previous driver version may be the more stable solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Azure-Specific Fix
&lt;/h3&gt;

&lt;p&gt;Microsoft has already released an emergency patch (&lt;code&gt;KB5077744&lt;/code&gt;) specifically for Azure Virtual Desktop issues. If this is your only problem, install only this patch.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Conclusion
&lt;/h2&gt;

&lt;p&gt;The situation puts system administrators in a difficult position: leave systems vulnerable to serious cyber threats or risk workflow stability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For regular users, the advice is clear:&lt;/strong&gt; if your computer is running unstably after the latest update, don't hesitate to remove it and wait for a corrected version from Microsoft.&lt;/p&gt;

&lt;p&gt;Microsoft is expected to coordinate additional fixes in the coming days. Follow official channels for updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Quick Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Windows 11 update KB5074109 causing crashes, black screens, and application hangs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; Versions 24H2 and 25H2&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Fix:&lt;/strong&gt; Uninstall KB5074109 and pause updates temporarily&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alternative:&lt;/strong&gt; Install KB5077744 if you only have Azure issues&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is a translation of the original Bulgarian article: &lt;a href="https://itpraktika.com/kritichni-problemi-s-windows-11/" rel="noopener noreferrer"&gt;Windows 11 update KB5074109: Problems and fix&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>windows11</category>
      <category>sysadmin</category>
      <category>troubleshooting</category>
    </item>
    <item>
      <title>Why Use Ripgrep Over grep in 2026: The Complete Guide</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Fri, 23 Jan 2026 17:44:03 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/why-use-ripgrep-over-grep-in-2026-the-complete-guide-2mnm</link>
      <guid>https://forem.com/fedya_serafiev/why-use-ripgrep-over-grep-in-2026-the-complete-guide-2mnm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction 🚀
&lt;/h2&gt;

&lt;p&gt;You've probably watched your terminal freeze while grep searches through, say, 10 GB of log files. Using ripgrep, this took about 5 seconds, while classic grep was still processing the first gigabyte. This isn't a coincidence. This is the difference between a tool from the 1970s and a modern tool built for today's needs.&lt;/p&gt;

&lt;p&gt;In this article, I'll explore why ripgrep (command: &lt;code&gt;rg&lt;/code&gt;) has become the standard for code searching in 2026. You'll see concrete examples, benchmarks, and practical tips for daily work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;📖 This article is also available in Bulgarian:&lt;/strong&gt; &lt;a href="https://itpraktika.com/ripgrep-vs-grep-2026/" rel="noopener noreferrer"&gt;Защо да използваме Ripgrep, а не grep през 2026 г.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What is Ripgrep? 🔍
&lt;/h2&gt;

&lt;p&gt;Ripgrep is a line-oriented search tool written in Rust. It recursively searches directories for text patterns. By default, it respects &lt;code&gt;.gitignore&lt;/code&gt; rules and automatically skips hidden files, binary files, and unnecessary directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: Extremely fast, often 10-20x faster than grep&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart defaults&lt;/strong&gt;: Respects &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.ignore&lt;/code&gt;, hidden files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unicode support&lt;/strong&gt;: Full UTF-8 support without performance loss&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform&lt;/strong&gt;: Works on Windows, macOS, and Linux&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelization&lt;/strong&gt;: Automatically uses all CPU cores&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1551288049-bebda4e38f71%3Fw%3D1200%26h%3D600%26fit%3Dcrop" 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%2Fimages.unsplash.com%2Fphoto-1551288049-bebda4e38f71%3Fw%3D1200%26h%3D600%26fit%3Dcrop" alt="Performance Chart" width="1200" height="600"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why is Ripgrep Faster Than grep? ⚡
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Modern Rust Architecture
&lt;/h3&gt;

&lt;p&gt;Ripgrep uses Rust's regex engine, which combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Finite automata&lt;/strong&gt;: Efficient regular expression processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIMD instructions&lt;/strong&gt;: Parallel processing of multiple bytes at once&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggressive literal optimizations&lt;/strong&gt;: Searching for literal strings before regex&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Automatic Parallelization
&lt;/h3&gt;

&lt;p&gt;Unlike grep, ripgrep uses all available CPU cores by default. When searching through thousands of files, this makes a huge difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benchmark Example&lt;/strong&gt; (Linux kernel source tree):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ripgrep:  ~0.06 seconds
GNU &lt;span class="nb"&gt;grep&lt;/span&gt;: ~0.67 seconds
Difference: 11x slower
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Intelligent Strategy Selection
&lt;/h3&gt;

&lt;p&gt;Ripgrep automatically chooses the optimal strategy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory maps for single large files&lt;/li&gt;
&lt;li&gt;Incremental buffering for multiple files&lt;/li&gt;
&lt;li&gt;Automatic binary file detection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Optimized Line Counting
&lt;/h3&gt;

&lt;p&gt;Ripgrep counts lines using packed comparisons (16 bytes at a time). This is significantly faster than the naive byte-by-byte approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Comparisons: Ripgrep vs grep 📊
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: Searching a Large Codebase
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Task&lt;/strong&gt;: Find all uses of a variable in a React project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# With grep (slow, noisy)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time grep&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"useState"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node_modules &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.git
real    0m8.342s

&lt;span class="c"&gt;# With ripgrep (fast, clean)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;rg &lt;span class="s2"&gt;"useState"&lt;/span&gt;
real    0m0.089s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Ripgrep is &lt;strong&gt;93x faster&lt;/strong&gt; in this real scenario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1555066931-4365d14bab8c%3Fw%3D1200%26h%3D600%26fit%3Dcrop" 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%2Fimages.unsplash.com%2Fphoto-1555066931-4365d14bab8c%3Fw%3D1200%26h%3D600%26fit%3Dcrop" alt="Code Search" width="1200" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Searching with Line Numbers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# grep&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time grep&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; &lt;span class="s2"&gt;"function"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
real    0m9.484s

&lt;span class="c"&gt;# ripgrep&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"function"&lt;/span&gt;
real    0m1.664s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Ripgrep is &lt;strong&gt;5.7x faster&lt;/strong&gt; with line numbers enabled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 3: Real Monorepo (1.4 GB, 250,000 files)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Files Scanned&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;grep&lt;/td&gt;
&lt;td&gt;45s&lt;/td&gt;
&lt;td&gt;250,000+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ripgrep&lt;/td&gt;
&lt;td&gt;2.3s&lt;/td&gt;
&lt;td&gt;~15,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ripgrep automatically skipped &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;.git&lt;/code&gt;, &lt;code&gt;dist&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, and others.&lt;/p&gt;




&lt;h2&gt;
  
  
  Smart Defaults 🎯
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Automatic Ignoring
&lt;/h3&gt;

&lt;p&gt;Ripgrep &lt;strong&gt;automatically&lt;/strong&gt; respects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.gitignore&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.ignore&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.rgignore&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Hidden directories (starting with &lt;code&gt;.&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Binary files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# grep requires long exclude flags&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node_modules &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.git &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dist &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.venv &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;__pycache__

&lt;span class="c"&gt;# ripgrep does this automatically&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automatic Case-Insensitive Search
&lt;/h3&gt;

&lt;p&gt;If your query is all lowercase, ripgrep becomes case-insensitive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Automatically case-insensitive&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;rg &lt;span class="s2"&gt;"error"&lt;/span&gt;        &lt;span class="c"&gt;# finds Error, ERROR, error&lt;/span&gt;

&lt;span class="c"&gt;# If it has uppercase, becomes case-sensitive&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;rg &lt;span class="s2"&gt;"Error"&lt;/span&gt;        &lt;span class="c"&gt;# finds only Error, ERROR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Colored Output by Default
&lt;/h3&gt;

&lt;p&gt;No need to add &lt;code&gt;--color=auto&lt;/code&gt;. Ripgrep automatically colors results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1629654297299-c8506221ca97%3Fw%3D1200%26h%3D600%26fit%3Dcrop" 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%2Fimages.unsplash.com%2Fphoto-1629654297299-c8506221ca97%3Fw%3D1200%26h%3D600%26fit%3Dcrop" alt="Terminal Output" width="1200" height="600"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing Ripgrep 💻
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ubuntu/Debian
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ubuntu 18.10+&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep

&lt;span class="c"&gt;# For older versions or latest release&lt;/span&gt;
&lt;span class="nv"&gt;RIPGREP_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://api.github.com/repos/BurntSushi/ripgrep/releases/latest"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Po&lt;/span&gt; &lt;span class="s1"&gt;'"tag_name": "\K[0-9.]+'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
wget &lt;span class="nt"&gt;-qO&lt;/span&gt; ripgrep.deb &lt;span class="s2"&gt;"https://github.com/BurntSushi/ripgrep/releases/latest/download/ripgrep_&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RIPGREP_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-1_amd64.deb"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; ripgrep.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  macOS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# With Homebrew&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# With Chocolatey&lt;/span&gt;
choco &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep

&lt;span class="c"&gt;# With Scoop&lt;/span&gt;
scoop &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep

&lt;span class="c"&gt;# With winget&lt;/span&gt;
winget &lt;span class="nb"&gt;install &lt;/span&gt;BurntSushi.ripgrep.MSVC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Arch Linux
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; ripgrep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Via Cargo (Rust)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# ripgrep 15.0.1 (or newer)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Usage Examples 🛠️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Basic Search
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search for "TODO" recursively in current directory&lt;/span&gt;
rg &lt;span class="s2"&gt;"TODO"&lt;/span&gt;

&lt;span class="c"&gt;# Search for exact word&lt;/span&gt;
rg &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Case-sensitive search&lt;/span&gt;
rg &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"Error"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Search by File Type
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Only Python files&lt;/span&gt;
rg &lt;span class="s2"&gt;"import"&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; py

&lt;span class="c"&gt;# Only JavaScript/TypeScript&lt;/span&gt;
rg &lt;span class="s2"&gt;"useState"&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; js &lt;span class="nt"&gt;-t&lt;/span&gt; ts

&lt;span class="c"&gt;# Exclude JavaScript&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; js

&lt;span class="c"&gt;# See all available types&lt;/span&gt;
rg &lt;span class="nt"&gt;--type-list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Show Context
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 2 lines before and after match&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; 2

&lt;span class="c"&gt;# 3 lines before&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;-B&lt;/span&gt; 3

&lt;span class="c"&gt;# 3 lines after&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Search Specific Files
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search only in .env files&lt;/span&gt;
rg &lt;span class="s2"&gt;"API_KEY"&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"*.env"&lt;/span&gt;

&lt;span class="c"&gt;# Search in all config files&lt;/span&gt;
rg &lt;span class="s2"&gt;"database"&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"*config*"&lt;/span&gt;

&lt;span class="c"&gt;# Exclude test files&lt;/span&gt;
rg &lt;span class="s2"&gt;"function"&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"!*test*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Text Replacement (with other tools)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all matches and replace with sed&lt;/span&gt;
rg &lt;span class="s2"&gt;"oldName"&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | xargs &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/oldName/newName/g'&lt;/span&gt;

&lt;span class="c"&gt;# Or with modern ripgrep + sd (string-displacing tool)&lt;/span&gt;
rg &lt;span class="s2"&gt;"oldName"&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | xargs sd &lt;span class="s2"&gt;"oldName"&lt;/span&gt; &lt;span class="s2"&gt;"newName"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Search Compressed Files
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search in .gz, .xz, .bz2, .lz4 files&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;--search-zip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Show Only File Names
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show only files containing pattern&lt;/span&gt;
rg &lt;span class="s2"&gt;"TODO"&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;

&lt;span class="c"&gt;# Show only files NOT containing pattern&lt;/span&gt;
rg &lt;span class="s2"&gt;"TODO"&lt;/span&gt; &lt;span class="nt"&gt;--files-without-match&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Match Statistics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Count matches&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;

&lt;span class="c"&gt;# Show statistics&lt;/span&gt;
rg &lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="nt"&gt;--stats&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Advanced Techniques 🎓
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Combining with Other Tools
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ripgrep + fzf for interactive search&lt;/span&gt;
rg &lt;span class="nt"&gt;--line-number&lt;/span&gt; &lt;span class="nt"&gt;--no-heading&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt; | fzf

&lt;span class="c"&gt;# Ripgrep + bat for syntax highlighting&lt;/span&gt;
rg &lt;span class="s2"&gt;"function"&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | xargs bat

&lt;span class="c"&gt;# Ripgrep + jq for JSON files&lt;/span&gt;
rg &lt;span class="s2"&gt;"userId"&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt; | jq &lt;span class="s1"&gt;'.data.text'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Using a Config File
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;~/.ripgreprc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Always show line numbers&lt;/span&gt;
&lt;span class="nt"&gt;--line-number&lt;/span&gt;

&lt;span class="c"&gt;# Always show hidden files&lt;/span&gt;
&lt;span class="nt"&gt;--hidden&lt;/span&gt;

&lt;span class="c"&gt;# Ignore specific directories&lt;/span&gt;
&lt;span class="nt"&gt;--glob&lt;/span&gt;&lt;span class="o"&gt;=!&lt;/span&gt;.git/
&lt;span class="nt"&gt;--glob&lt;/span&gt;&lt;span class="o"&gt;=!&lt;/span&gt;node_modules/
&lt;span class="nt"&gt;--glob&lt;/span&gt;&lt;span class="o"&gt;=!&lt;/span&gt;dist/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Activate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;RIPGREP_CONFIG_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ripgreprc"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Regex Patterns
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Email addresses&lt;/span&gt;
rg &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;[A-Z|a-z]{2,}&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# IP addresses&lt;/span&gt;
rg &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;(?:&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;{1,3}&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;){3}&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;{1,3}&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# URLs&lt;/span&gt;
rg &lt;span class="s2"&gt;"https?://[^&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="s2"&gt;]+"&lt;/span&gt;

&lt;span class="c"&gt;# Hex colors&lt;/span&gt;
rg &lt;span class="s2"&gt;"#[0-9A-Fa-f]{6}&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Multiline Search
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search multi-line patterns&lt;/span&gt;
rg &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="s2"&gt;"function.*&lt;/span&gt;&lt;span class="se"&gt;\{&lt;/span&gt;&lt;span class="s2"&gt;.*&lt;/span&gt;&lt;span class="se"&gt;\}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 5

&lt;span class="c"&gt;# PCRE2 regex for complex patterns&lt;/span&gt;
rg &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"(?s)function.*?end"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  When to Use grep Instead of Ripgrep? 🤔
&lt;/h2&gt;

&lt;p&gt;There are situations where grep is the better choice:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Maximum Portability
&lt;/h3&gt;

&lt;p&gt;Grep is everywhere. If you're writing scripts for multiple systems, grep is safer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. POSIX Compliance
&lt;/h3&gt;

&lt;p&gt;Ripgrep is not POSIX-compliant. If you need POSIX compliance, use grep.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Piping from stdin
&lt;/h3&gt;

&lt;p&gt;For streaming data and pipe processing, grep is sometimes more suitable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# grep is good here&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;python

&lt;span class="c"&gt;# ripgrep works but isn't optimal&lt;/span&gt;
ps aux | rg python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Minimal Embedded Systems
&lt;/h3&gt;

&lt;p&gt;On systems without the ability to install additional software, grep is the only option.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Specific Legacy Scripts
&lt;/h3&gt;

&lt;p&gt;If you have old scripts that rely on grep's exact behavior, migration might create problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ripgrep in CI/CD and Automation 🤖
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Actions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Code Quality&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;check-todos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install ripgrep&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;wget https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep_14.1.0-1_amd64.deb&lt;/span&gt;
          &lt;span class="s"&gt;sudo dpkg -i ripgrep_14.1.0-1_amd64.deb&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check for TODOs&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;if rg "TODO|FIXME" -t py; then&lt;/span&gt;
            &lt;span class="s"&gt;echo "Found TODOs in code!"&lt;/span&gt;
            &lt;span class="s"&gt;exit 1&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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



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

&lt;span class="c"&gt;# Install ripgrep&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; ripgrep &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Use in scripts&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; search.sh /usr/local/bin/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/search.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pre-commit Hooks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# .git/hooks/pre-commit&lt;/span&gt;

&lt;span class="c"&gt;# Check for debug statements&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;rg &lt;span class="s2"&gt;"console.log|debugger"&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; js &lt;span class="nt"&gt;-t&lt;/span&gt; ts &lt;span class="nt"&gt;--quiet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"❌ Found debug statements in code!"&lt;/span&gt;
    rg &lt;span class="s2"&gt;"console.log|debugger"&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; js &lt;span class="nt"&gt;-t&lt;/span&gt; ts
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ No debug statements found"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performance: Real Numbers 📈
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test 1: Monorepo (250,000 files, 1.4 GB)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;grep&lt;/th&gt;
&lt;th&gt;ripgrep&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search "error"&lt;/td&gt;
&lt;td&gt;45.2s&lt;/td&gt;
&lt;td&gt;2.3s&lt;/td&gt;
&lt;td&gt;19.6x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regex search&lt;/td&gt;
&lt;td&gt;67.8s&lt;/td&gt;
&lt;td&gt;3.1s&lt;/td&gt;
&lt;td&gt;21.9x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search with -n&lt;/td&gt;
&lt;td&gt;72.4s&lt;/td&gt;
&lt;td&gt;3.8s&lt;/td&gt;
&lt;td&gt;19.0x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Test 2: Single Large File (10 GB log)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;grep&lt;/th&gt;
&lt;th&gt;ripgrep&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search "ERROR"&lt;/td&gt;
&lt;td&gt;18.2s&lt;/td&gt;
&lt;td&gt;4.8s&lt;/td&gt;
&lt;td&gt;3.8x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regex pattern&lt;/td&gt;
&lt;td&gt;45.6s&lt;/td&gt;
&lt;td&gt;12.3s&lt;/td&gt;
&lt;td&gt;3.7x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Test 3: Python Codebase (5,000+ files)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search import statements&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time grep&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; &lt;span class="s2"&gt;"^import "&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.py"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
real    0m3.421s

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;rg &lt;span class="s2"&gt;"^import "&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; py
real    0m0.156s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: 21.9x faster for daily tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes and Solutions ❌✅
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistake 1: Ripgrep Doesn't Find Files
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: &lt;code&gt;rg "text"&lt;/code&gt; shows no results, but you know the text exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Files might be ignored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show all files, including ignored ones&lt;/span&gt;
rg &lt;span class="s2"&gt;"text"&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;

&lt;span class="c"&gt;# Show even hidden and binary&lt;/span&gt;
rg &lt;span class="s2"&gt;"text"&lt;/span&gt; &lt;span class="nt"&gt;-uuu&lt;/span&gt;

&lt;span class="c"&gt;# Check which files are ignored&lt;/span&gt;
rg &lt;span class="nt"&gt;--files&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
rg &lt;span class="nt"&gt;--files&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 2: Slow Search in Home Directory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: &lt;code&gt;rg "something"&lt;/code&gt; in &lt;code&gt;/home&lt;/code&gt; or &lt;code&gt;/&lt;/code&gt; is very slow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Limit the scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search only in specific directory&lt;/span&gt;
rg &lt;span class="s2"&gt;"something"&lt;/span&gt; ~/projects/

&lt;span class="c"&gt;# Or add --max-depth&lt;/span&gt;
rg &lt;span class="s2"&gt;"something"&lt;/span&gt; &lt;span class="nt"&gt;--max-depth&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 3: Regex Doesn't Work as Expected
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Regex from grep doesn't work in ripgrep.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use PCRE2 mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Standard regex (might not work)&lt;/span&gt;
rg &lt;span class="s2"&gt;"(?&amp;lt;=@)&lt;/span&gt;&lt;span class="se"&gt;\w&lt;/span&gt;&lt;span class="s2"&gt;+"&lt;/span&gt;

&lt;span class="c"&gt;# With PCRE2 support&lt;/span&gt;
rg &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"(?&amp;lt;=@)&lt;/span&gt;&lt;span class="se"&gt;\w&lt;/span&gt;&lt;span class="s2"&gt;+"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mistake 4: Can't Search UTF-16 Files
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Ripgrep doesn't support UTF-16. Convert first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iconv &lt;span class="nt"&gt;-f&lt;/span&gt; UTF-16 &lt;span class="nt"&gt;-t&lt;/span&gt; UTF-8 file.txt | rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion: Why Ripgrep is the Future 🌟
&lt;/h2&gt;

&lt;p&gt;After thoroughly examining ripgrep, here's why it's the right choice in 2026:&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Advantages:
&lt;/h3&gt;

&lt;p&gt;✅ &lt;strong&gt;Speed&lt;/strong&gt;: 10-20x faster than grep in real scenarios&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Intelligence&lt;/strong&gt;: Automatic ignoring of unnecessary files&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Modernity&lt;/strong&gt;: Built for today's codebases&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Safety&lt;/strong&gt;: Written in Rust, memory-safe&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Convenience&lt;/strong&gt;: Better defaults, fewer flags&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Unicode&lt;/strong&gt;: Full support without performance penalty&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Parallelization&lt;/strong&gt;: Automatically uses all cores  &lt;/p&gt;

&lt;h3&gt;
  
  
  When to Start Using Ripgrep:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ You work with large codebases&lt;/li&gt;
&lt;li&gt;✅ You search frequently across multiple files&lt;/li&gt;
&lt;li&gt;✅ You use git and have &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ You value your time and productivity&lt;/li&gt;
&lt;li&gt;✅ You work with Unicode text&lt;/li&gt;
&lt;li&gt;✅ You have a multi-core processor&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to Stick with grep:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ You write POSIX-compliant scripts&lt;/li&gt;
&lt;li&gt;⚠️ You work on embedded systems without Rust&lt;/li&gt;
&lt;li&gt;⚠️ You have legacy systems without update capability&lt;/li&gt;
&lt;li&gt;⚠️ You process stdin pipes intensively&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Additional Resources 📚
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Official Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/BurntSushi/ripgrep" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md" rel="noopener noreferrer"&gt;User guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.burntsushi.net/ripgrep/" rel="noopener noreferrer"&gt;Andrew Gallant's blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Useful Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bat&lt;/strong&gt;: Syntax highlighting cat (works perfectly with rg)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fd&lt;/strong&gt;: Modern find (ripgrep's sibling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fzf&lt;/strong&gt;: Fuzzy finder (combines great with rg)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sd&lt;/strong&gt;: Modern sed (for text replacement)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Community
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reddit.com/r/rust" rel="noopener noreferrer"&gt;r/rust on Reddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://users.rust-lang.org/" rel="noopener noreferrer"&gt;Rust Users Forum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Copy Commands 📋
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Installation&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep                    &lt;span class="c"&gt;# macOS&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep                &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
cargo &lt;span class="nb"&gt;install &lt;/span&gt;ripgrep                   &lt;span class="c"&gt;# Rust&lt;/span&gt;

&lt;span class="c"&gt;# Basic commands&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt;                            &lt;span class="c"&gt;# Basic search&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; py                      &lt;span class="c"&gt;# Python only&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; 2                       &lt;span class="c"&gt;# With context&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;                         &lt;span class="c"&gt;# File names only&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;-uuu&lt;/span&gt;                       &lt;span class="c"&gt;# Search everywhere&lt;/span&gt;

&lt;span class="c"&gt;# Advanced&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"*.{js,ts}"&lt;/span&gt;            &lt;span class="c"&gt;# Specific extensions&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;--stats&lt;/span&gt;                    &lt;span class="c"&gt;# Show statistics&lt;/span&gt;
rg &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"complex.*regex"&lt;/span&gt;                  &lt;span class="c"&gt;# PCRE2 regex&lt;/span&gt;
rg &lt;span class="s2"&gt;"pattern"&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt;                         &lt;span class="c"&gt;# In compressed files&lt;/span&gt;

&lt;span class="c"&gt;# Configuration&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;RIPGREP_CONFIG_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ripgreprc"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts 💭
&lt;/h2&gt;

&lt;p&gt;Switching from grep to ripgrep isn't just changing a tool. It's modernizing your workflow. In the world of 2026, where codebases grow exponentially and time is precious, ripgrep is the natural choice.&lt;/p&gt;

&lt;p&gt;Start today. Install it. Use it for a week. You won't go back.&lt;/p&gt;

&lt;p&gt;Good luck! 🚀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Article is current as of January 2026. Ripgrep continues to be actively developed.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>cli</category>
      <category>productivity</category>
      <category>linux</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Docker &amp; Docker Compose: From Zero to Server (A Practical Guide)</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Thu, 22 Jan 2026 12:40:45 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/docker-docker-compose-from-zero-to-server-a-practical-guide-ld1</link>
      <guid>https://forem.com/fedya_serafiev/docker-docker-compose-from-zero-to-server-a-practical-guide-ld1</guid>
      <description>&lt;p&gt;Welcome to the world of modern technology! If you're a beginner in programming or system administration, you've probably heard the word &lt;strong&gt;Docker&lt;/strong&gt; constantly. It might sound complicated, but the truth is that Docker was created to make our lives &lt;strong&gt;easier&lt;/strong&gt;, not harder.&lt;/p&gt;

&lt;p&gt;In this first part of our series, we'll journey from "What is this?" to launching an entire infrastructure with &lt;strong&gt;Docker Compose&lt;/strong&gt;. And we'll do it the professional way – directly on a server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is a translation of the original Bulgarian article: &lt;a href="https://itpraktika.com/docker-docker-compose/" rel="noopener noreferrer"&gt;Docker &amp;amp; Docker Compose: от нулата до сървър&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Problem: "It Works on My Machine!" 😫
&lt;/h2&gt;

&lt;p&gt;Imagine you've written an amazing program. It works perfectly on your laptop. You send it to a client or upload it to a server and... &lt;strong&gt;boom!&lt;/strong&gt; Nothing works. It turns out the server has a different version of Python, a library is missing, or the database settings are different.&lt;/p&gt;

&lt;p&gt;This is called an "environment conflict." Before Docker, programmers wasted hours (and days) configuring servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: The Digital Container 📦
&lt;/h3&gt;

&lt;p&gt;Docker takes your program and encloses it in a "container." Inside this container is everything needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code itself&lt;/li&gt;
&lt;li&gt;The libraries it uses&lt;/li&gt;
&lt;li&gt;System settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you give this container to someone else, it works in &lt;strong&gt;exactly the same way&lt;/strong&gt; because the operating system on the computer no longer matters. Docker provides isolation.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Preparation: Where Will We Work? 🌐
&lt;/h2&gt;

&lt;p&gt;To learn Docker properly, you need to use it where it belongs – on a &lt;strong&gt;Linux server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Many tutorials start with Windows installation (Docker Desktop), but this often confuses beginners with additional BIOS settings, virtual machines, and unnecessary RAM consumption. That's why we'll take the professional approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Server Access
&lt;/h3&gt;

&lt;p&gt;If you have your own server (VPS) with &lt;strong&gt;Ubuntu&lt;/strong&gt;, great! If you don't, you can rent one for a few euros per month from providers like DigitalOcean, &lt;a href="https://hetzner.cloud/?ref=irpJ7I8kXotQ" rel="noopener noreferrer"&gt;Hetzner&lt;/a&gt;, or local ones.&lt;/p&gt;

&lt;p&gt;Connect to your server via terminal (PowerShell on Windows or Terminal on Mac):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh root@your-ip-address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Professional Installation (All at Once) 🛠️
&lt;/h2&gt;

&lt;p&gt;Forget long guides. Docker provides an official script that does everything for you. Once you've logged into the server, simply copy and paste this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.docker.com &lt;span class="nt"&gt;-o&lt;/span&gt; install-docker.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;sh install-docker.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What just happened?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You downloaded the installation script&lt;/li&gt;
&lt;li&gt;You executed it with administrator privileges&lt;/li&gt;
&lt;li&gt;Docker is now installed and ready to work&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To check if everything is okay, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see a version (e.g., &lt;code&gt;Docker version 24.x.x&lt;/code&gt;), you're ready for the magic! ✨&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Three Pillars of Docker: Image, Container, Registry 🏗️
&lt;/h2&gt;

&lt;p&gt;Before we start something, you need to understand three basic concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Image:&lt;/strong&gt; This is a "frozen" snapshot of your program. It doesn't do anything, just sits on disk. Think of it as a cake recipe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container:&lt;/strong&gt; This is the actual cake. When you "start" the image, it becomes a live, working process (container). You can create 100 containers from the same image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registry:&lt;/strong&gt; The place where images are stored. The biggest is &lt;strong&gt;Docker Hub&lt;/strong&gt; – it has ready-made images for everything: databases, web servers, programming languages.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  5. Your First Container: Web Server in 5 Seconds 🚀
&lt;/h2&gt;

&lt;p&gt;Let's run &lt;strong&gt;Nginx&lt;/strong&gt; – the most widely used web server in the world. On a regular server, its installation takes time and configuration. With Docker, it's one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;--name&lt;/span&gt; my-site nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Command Breakdown (Important!):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker run&lt;/code&gt;: Tells Docker to find the image and start it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt;: (Detached) Means "run in the background." Without it, your terminal will be blocked by server logs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p 80:80&lt;/code&gt;: &lt;strong&gt;This is critical!&lt;/strong&gt; The first &lt;code&gt;80&lt;/code&gt; is your server's port. The second &lt;code&gt;80&lt;/code&gt; is the port inside the container. We're saying: "When someone visits my IP, forward them to the container"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--name my-site&lt;/code&gt;: We give it a name so we can recognize it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nginx&lt;/code&gt;: The name of the image we're pulling from Docker Hub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Open your browser and type your server's IP address. You should see: &lt;strong&gt;"Welcome to nginx!"&lt;/strong&gt;. Congratulations, you're a system administrator! 😎&lt;/p&gt;




&lt;h2&gt;
  
  
  6. How to Manage the Chaos? (Survival Commands) 🕹️
&lt;/h2&gt;

&lt;p&gt;Now that something is running, we need to know how to control it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;See which containers are currently running:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;See all containers (even stopped ones):&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stop the server:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  docker stop my-site
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;See what's happening "inside" (Logs):&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  docker logs my-site
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(If something doesn't work, this is where you'll see why)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. The Grand Finale: Docker Compose 🎼
&lt;/h2&gt;

&lt;p&gt;One container is easy. But what do we do if we need a website (Nginx) + database (MySQL)? Writing two long &lt;code&gt;docker run&lt;/code&gt; commands and manually connecting them is torture.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Docker Compose&lt;/strong&gt; comes in. It allows you to describe your entire infrastructure in one file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Installation
&lt;/h3&gt;

&lt;p&gt;On modern systems, it comes with Docker, but check with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Creating the Project
&lt;/h3&gt;

&lt;p&gt;Create a folder for your project and enter it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a file named &lt;code&gt;docker-compose.yml&lt;/code&gt;. You can use the &lt;code&gt;nano&lt;/code&gt; editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Put this code inside:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;

  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:8.0&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-password-here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(Press Ctrl+O, Enter, then Ctrl+X to save and exit nano)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: The Magic Begins
&lt;/h3&gt;

&lt;p&gt;Instead of starting things one by one, just write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happened?&lt;/strong&gt; Docker Compose read the file, understood you need two containers, created a virtual network between them, and started them simultaneously. Now you have a working web server on port 8080 and a database underneath it.&lt;/p&gt;

&lt;p&gt;To stop and delete everything at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Why Did This Work "Right Away"? 💎
&lt;/h2&gt;

&lt;p&gt;If you followed the steps, you probably already have a working system. Here are the secrets to success:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clean server:&lt;/strong&gt; When we work on clean Linux, there are no conflicts with Windows settings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YAML syntax:&lt;/strong&gt; Be careful with indentation in &lt;code&gt;docker-compose.yml&lt;/code&gt; – it matters! Don't use Tab, only spaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ports:&lt;/strong&gt; If port 80 is occupied, you can always change it to 8081 or 8082&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion and Next Steps
&lt;/h2&gt;

&lt;p&gt;Today you learned the basics of the most important technology for cloud services. You now know how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Docker professionally&lt;/li&gt;
&lt;li&gt;Start ready-made programs (Images) as containers&lt;/li&gt;
&lt;li&gt;Orchestrate complex systems with Docker Compose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next article, we'll move to the next level: &lt;strong&gt;How to package our own software.&lt;/strong&gt; We'll write our first &lt;code&gt;Dockerfile&lt;/code&gt; and turn simple code into a professional Docker image.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;About the Author:&lt;/strong&gt;&lt;br&gt;
Fedya Serafiev is the creator of &lt;a href="https://itpraktika.com/" rel="noopener noreferrer"&gt;ITpraktika.com&lt;/a&gt; – a platform dedicated to practical IT solutions and automation. With extensive experience in system optimization and web technologies, he transforms complex technical cases into clear and easy-to-follow steps.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Original Article (Bulgarian):&lt;/strong&gt; &lt;a href="https://itpraktika.com/docker-docker-compose/" rel="noopener noreferrer"&gt;Docker &amp;amp; Docker Compose: от нулата до сървър&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/" rel="noopener noreferrer"&gt;Docker Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hetzner.cloud/?ref=irpJ7I8kXotQ" rel="noopener noreferrer"&gt;Hetzner Cloud&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Best VPS Servers in 2026: A Comprehensive Guide</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Thu, 22 Jan 2026 02:44:55 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/best-vps-servers-in-2026-a-comprehensive-guide-p0b</link>
      <guid>https://forem.com/fedya_serafiev/best-vps-servers-in-2026-a-comprehensive-guide-p0b</guid>
      <description>&lt;p&gt;In the digital world of 2026, speed and security are no longer luxuries—they're essential for survival. If shared hosting feels too restrictive and renting an entire physical server is too expensive, the solution is clear: &lt;strong&gt;VPS (Virtual Private Server)&lt;/strong&gt;. 🚀&lt;/p&gt;

&lt;p&gt;This comprehensive guide explores the leading market players, how technologies have evolved in recent years, and how to make the right choice for your business or personal project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Original article (Bulgarian): &lt;a href="https://itpraktika.com/nay-dobrite-vps-sarvari-za-2026/" rel="noopener noreferrer"&gt;Най-добрите VPS сървъри за 2026&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why VPS Still Matters in 2026 🌐
&lt;/h2&gt;

&lt;p&gt;Despite the rise of serverless technologies and complex cloud ecosystems, VPS remains the "golden middle" for developers and entrepreneurs. Here's why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full Control (Root Access):&lt;/strong&gt; You have the freedom to configure your operating system and install specific software without restrictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolated Resources:&lt;/strong&gt; Your RAM and CPU power (vCPU) belong to you alone. Issues on someone else's site on the same server won't affect your performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Economic Efficiency:&lt;/strong&gt; In 2026, prices for NVMe drives and powerful processors have dropped dramatically, making VPS accessible to every startup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and Compliance:&lt;/strong&gt; Easily implement Zero Trust architectures and meet strict GDPR requirements.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Evaluation Criteria: What to Look for in 2026 📊
&lt;/h2&gt;

&lt;p&gt;Before choosing a provider, pay attention to these key indicators—the quality standard for the current year:&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡ Hardware Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NVMe Gen5 Storage:&lt;/strong&gt; Forget standard SSDs. Look for providers offering NVMe for lightning-fast read and write speeds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next-Gen Processors:&lt;/strong&gt; Seek systems with AMD EPYC™ 9004 (Genoa) or Intel® Xeon® Scalable (Sapphire Rapids).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DDR5 RAM:&lt;/strong&gt; Provides significantly higher bandwidth compared to older standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛡️ Security and Reliability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI-based DDoS Protection:&lt;/strong&gt; Built-in protection that learns and responds to new threats in real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Backups:&lt;/strong&gt; One-click daily backup capability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;99.99% Uptime:&lt;/strong&gt; Time is money—don't compromise on availability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📈 Flexibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Ability to add RAM or CPU cores without server restart (hot-plugging).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location Choice:&lt;/strong&gt; The server should be close to your users (Europe, USA, or Asia).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Top VPS Providers for 2026 🏆
&lt;/h2&gt;

&lt;p&gt;Based on performance tests, network stability, and price-to-quality ratio, here are the favorites:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Key Advantage&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hetzner&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Advanced users&lt;/td&gt;
&lt;td&gt;Best price-to-performance ratio in Europe 🇪🇺&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hostinger&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Beginners and small business&lt;/td&gt;
&lt;td&gt;Intuitive interface and excellent support 👨‍💻&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DigitalOcean&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developers and SaaS&lt;/td&gt;
&lt;td&gt;Extensive tutorial library and easy API 🤖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ionos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enterprise clients&lt;/td&gt;
&lt;td&gt;Flexible plans and Windows/Linux options 🏢&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kamatera&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Maximum scalability&lt;/td&gt;
&lt;td&gt;Hourly billing and custom configuration ⏱️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Detailed Review of Top 3:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Hetzner – The King of Efficiency
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://hetzner.cloud/?ref=irpJ7I8kXotQ" rel="noopener noreferrer"&gt;Hetzner&lt;/a&gt;&lt;/strong&gt; continues to dominate the European market. Their Cloud VPS plans offer incredible power at exceptionally low prices, ideal for resource-intensive projects on limited budgets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Advantage:&lt;/em&gt; Own data centers in Germany and Finland.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Disadvantage:&lt;/em&gt; Stricter verification process for new profiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Hostinger – Convenience and Accessibility
&lt;/h4&gt;

&lt;p&gt;If you don't want to spend hours in the terminal, Hostinger is your choice. They offer a powerful control panel and pre-installed templates (WordPress, Docker, Game Servers).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Advantage:&lt;/em&gt; Included weekly backups and 24/7 chat support.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Disadvantage:&lt;/em&gt; Renewal prices may be higher than initial rates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. DigitalOcean – A Coder's Paradise
&lt;/h4&gt;

&lt;p&gt;Known for their "Droplets," DigitalOcean makes application deployment child's play. In 2026, their Marketplace app ecosystem is the richest in the industry.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Advantage:&lt;/em&gt; Easy integration with Managed Databases and Kubernetes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How to Choose the Right Plan? 🤔
&lt;/h2&gt;

&lt;p&gt;The choice depends entirely on your project. Here are some practical examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Small blog or portfolio:&lt;/strong&gt; 1 vCPU, 2GB RAM, 20GB NVMe. Sufficient for fast loading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Online store (WooCommerce):&lt;/strong&gt; Minimum 2 vCPU, 4-8GB RAM. Important to have enough memory for processing orders during promotions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application testing (Dev Environment):&lt;/strong&gt; 1 vCPU, 1GB RAM. Focus here is on low cost and ability to quickly delete and recreate the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gaming server (Minecraft/Rust):&lt;/strong&gt; Minimum 4GB RAM and high-class processor with high clock speed.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Always start with a smaller plan. Most providers allow one-click upgrades, but downgrades are often more complex or impossible without reinstallation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Trends Driving 2026 🔮
&lt;/h2&gt;

&lt;p&gt;The hosting world never stands still. Here's what we're seeing today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AI Integration in Management:&lt;/strong&gt; Servers now predict traffic peaks and suggest optimizations automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Green Hosting (Sustainability):&lt;/strong&gt; Users prefer providers whose data centers are powered 100% by renewable sources. 🍃&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge Computing:&lt;/strong&gt; Using VPS for data processing in close proximity to users (e.g., for IoT devices).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ARM-based Servers:&lt;/strong&gt; ARM processors (like Ampere Altra) are becoming mainstream in the VPS segment, offering the same power at lower energy consumption and lower cost.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Managed vs. Unmanaged VPS 🛠️
&lt;/h2&gt;

&lt;p&gt;This is the most important question for your maintenance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unmanaged:&lt;/strong&gt; You're the administrator. You install the OS, security patches, and web server. Suitable for system administrators. Lowest price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed:&lt;/strong&gt; The provider handles the technical aspects. You focus on your business. Ideal for store owners and agencies.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion 🏁
&lt;/h2&gt;

&lt;p&gt;In 2026, choosing a VPS server is an investment in the stability and growth of your business. Whether you opt for the raw power of &lt;strong&gt;Hetzner&lt;/strong&gt;, the flexibility of &lt;strong&gt;DigitalOcean&lt;/strong&gt;, or the convenience of &lt;strong&gt;Hostinger&lt;/strong&gt;, what matters is choosing a partner that can grow with you.&lt;/p&gt;

&lt;p&gt;Always look for &lt;strong&gt;NVMe&lt;/strong&gt; disk availability, check where data centers are located, and don't forget to test support speed before making a long-term commitment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article was originally published in Bulgarian on &lt;a href="https://itpraktika.com/nay-dobrite-vps-sarvari-za-2026/" rel="noopener noreferrer"&gt;ITpraktika.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Fedya Serafiev&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://itpraktika.com/" rel="noopener noreferrer"&gt;ITpraktika.com&lt;/a&gt; – Practical IT solutions and automation&lt;/p&gt;

&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>vps</category>
      <category>whoishiring</category>
      <category>devops</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>YAML Validator - Quick Syntax Checker Tool</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Mon, 19 Jan 2026 03:29:15 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/yaml-validator-quick-syntax-checker-tool-844</link>
      <guid>https://forem.com/fedya_serafiev/yaml-validator-quick-syntax-checker-tool-844</guid>
      <description>&lt;p&gt;Recently, our team has been working more extensively with YAML files, and I noticed we were spending considerable time debugging syntax errors - especially those tricky indentation issues. Anyone who has worked with YAML knows how frustrating it can be to discover that your entire configuration doesn't work because of one extra space or a tab instead of spaces.&lt;/p&gt;

&lt;p&gt;I decided to create a simple yet effective YAML validator to help us catch errors instantly, without waiting for a deployment to fail or the CI/CD pipeline to tell us something's wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does This Tool Do?
&lt;/h2&gt;

&lt;p&gt;The YAML validator is a web-based tool that checks the syntax of your YAML files in real-time. Simply copy your code or upload a file, and you'll immediately see if there are any issues. If everything is correct, the tool also displays the parsed structure in JSON format, which is very convenient for visualizing the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Is It Useful?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt; (YAML Ain't Markup Language) is used everywhere in modern development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes manifests and configurations&lt;/li&gt;
&lt;li&gt;Docker Compose files&lt;/li&gt;
&lt;li&gt;CI/CD pipeline configurations (GitHub Actions, GitLab CI, etc.)&lt;/li&gt;
&lt;li&gt;Ansible playbooks&lt;/li&gt;
&lt;li&gt;Configuration files for various applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small indentation error can lead to hours of debugging, especially in complex configurations. This tool saves you exactly that time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;p&gt;I made it as practical and user-friendly as possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time validation&lt;/strong&gt; - write and immediately see the results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File upload&lt;/strong&gt; - you can check your .yaml/.yml files directly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detailed error messages&lt;/strong&gt; - exactly where the problem is and what's wrong&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bilingual interface&lt;/strong&gt; - Bulgarian and English&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy results&lt;/strong&gt; - easy sharing or saving&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern and intuitive design&lt;/strong&gt; - pleasant to work with&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Use It?
&lt;/h2&gt;

&lt;p&gt;Using it is extremely simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the tool in your browser&lt;/li&gt;
&lt;li&gt;Copy your YAML code or upload a file&lt;/li&gt;
&lt;li&gt;The tool automatically validates as you type&lt;/li&gt;
&lt;li&gt;If there's an error - you see a detailed description&lt;/li&gt;
&lt;li&gt;If everything is OK - you see the parsed structure&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;p&gt;The tool is completely free and you can download and use it locally. It's a single HTML file that works directly in the browser - no server or additional installations required.&lt;/p&gt;

&lt;p&gt;You can download it from the &lt;a href="https://itpraktika.com/yaml-validator/" rel="noopener noreferrer"&gt;original article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or simply open it directly in the browser and save it via "Save As" for local use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Local Tool?
&lt;/h2&gt;

&lt;p&gt;I preferred to create this as a standalone HTML file instead of an online service for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy&lt;/strong&gt; - your configuration files aren't sent anywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt; - everything works locally, no internet needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt; - you don't depend on external server availability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy integration&lt;/strong&gt; - you can add it to your team's tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you work with YAML regularly, this tool can significantly make your life easier. Instead of waiting for errors from various systems, you can check the syntax in advance and save quite a bit of time and nerves.&lt;/p&gt;

&lt;p&gt;Happy usage and fewer YAML errors! 🚀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;P.S. If you have suggestions for improvements or encounter a problem, don't hesitate to share - all feedback is welcome!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  About YAML
&lt;/h2&gt;

&lt;p&gt;YAML is a human-readable data serialization language that's commonly used for configuration files and data exchange between languages. Its clean syntax and support for complex data structures make it ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DevOps workflows&lt;/strong&gt; - Infrastructure as Code (IaC)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container orchestration&lt;/strong&gt; - Kubernetes, Docker Swarm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt; - CI/CD pipelines, configuration management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application configuration&lt;/strong&gt; - Settings, environment variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most common issues in YAML files are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Indentation errors&lt;/strong&gt; - Mixing tabs and spaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing colons&lt;/strong&gt; - After keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incorrect nesting&lt;/strong&gt; - Wrong hierarchy levels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Special characters&lt;/strong&gt; - Not properly escaped&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax issues&lt;/strong&gt; - Invalid YAML constructs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This validator helps catch all these issues before they cause problems in production!&lt;/p&gt;

&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>yaml</category>
      <category>devops</category>
      <category>docker</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>FileCloud: A Modern and Lightweight File Manager</title>
      <dc:creator>Fedya Serafiev</dc:creator>
      <pubDate>Sat, 17 Jan 2026 08:14:00 +0000</pubDate>
      <link>https://forem.com/fedya_serafiev/filecloud-a-modern-and-lightweight-file-manager-3ekj</link>
      <guid>https://forem.com/fedya_serafiev/filecloud-a-modern-and-lightweight-file-manager-3ekj</guid>
      <description>&lt;h2&gt;
  
  
  🌟 Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;FileCloud&lt;/strong&gt; is a reliable web-based file management solution designed for personal servers. It offers a premium, app-like experience with a focus on aesthetics, speed, and usability. It provides modern features like drag-and-drop upload, code editing, and full internationalization (EN/BG).&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📂 File Management&lt;/strong&gt;: Create folders, delete items, and download files with ease.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✏️ Rename and Organize&lt;/strong&gt;: Fix typos or restructure your files with a custom, elegant rename modal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Folder Customization&lt;/strong&gt;: &lt;strong&gt;[NEW]&lt;/strong&gt; Mark important folders by changing their color directly from the UI. Your choice is saved permanently!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🌍 Internationalization (i18n)&lt;/strong&gt;: Fully translated interface in &lt;strong&gt;English&lt;/strong&gt; and &lt;strong&gt;Bulgarian (български)&lt;/strong&gt;. Switch instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🚀 Drag and Drop&lt;/strong&gt;: Upload files by simply dragging them into the window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📝 Built-in Editor&lt;/strong&gt;: Edit text, code (&lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.css&lt;/code&gt;, &lt;code&gt;.py&lt;/code&gt;, etc.) and configuration files directly in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;👁️ Media Preview&lt;/strong&gt;: View images instantly without downloading them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;💎 Premium UI&lt;/strong&gt;: Dark mode by default, smooth animations, glassmorphism effects, and rich file icons.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Installation and Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js (version 14 or newer)&lt;/li&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone the repository&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone &lt;span class="o"&gt;[&lt;/span&gt;email protected]:fantomas4o/filecloud.git

&lt;span class="c"&gt;# Navigate to the project folder&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;filecloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install dependencies&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start the server&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Access the application at &lt;code&gt;http://localhost:3000&lt;/code&gt; or &lt;code&gt;http://ip:3000&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Server Deployment (Ubuntu/Systemd)
&lt;/h3&gt;

&lt;p&gt;To run FileCloud as a background service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the project to &lt;code&gt;/opt/filecloud&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a systemd service file at &lt;code&gt;/etc/systemd/system/filecloud.service&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;FileCloud Service&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/node /opt/filecloud/server.js&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/opt/filecloud&lt;/span&gt;
&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;NODE_ENV=production&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable and start the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;filecloud
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start filecloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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




&lt;h2&gt;
  
  
  💻 Technologies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Node.js, Express.js, Multer, FS-Extra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: HTML5, CSS3 (Custom Properties, Flexbox/Grid), Vanilla JavaScript (ES6+)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Icons&lt;/strong&gt;: Google Material Icons&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonts&lt;/strong&gt;: Google Fonts (One Sans)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Features in Detail
&lt;/h2&gt;

&lt;h3&gt;
  
  
  File Operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upload&lt;/strong&gt;: Drag files directly into the browser or use the upload button&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download&lt;/strong&gt;: Click on any file to download it instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete&lt;/strong&gt;: Remove files and folders with confirmation dialogs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rename&lt;/strong&gt;: Change file and folder names with a sleek modal interface&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Editor
&lt;/h3&gt;

&lt;p&gt;The built-in editor supports syntax highlighting for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript (&lt;code&gt;.js&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;CSS (&lt;code&gt;.css&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Python (&lt;code&gt;.py&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;JSON (&lt;code&gt;.json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Text files (&lt;code&gt;.txt&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;And many more...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Folder Customization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NEW Feature&lt;/strong&gt;: You can now customize folder colors to organize your workspace visually. The color selection is persistent and saved in your browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internationalization
&lt;/h3&gt;

&lt;p&gt;FileCloud supports multiple languages out of the box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;English (EN)&lt;/strong&gt;: Default interface language&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulgarian (BG)&lt;/strong&gt;: Fully translated Bulgarian interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Switch languages instantly from the settings menu.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;filecloud/
├── public/
│   ├── css/           # Stylesheets
│   ├── js/            # Client-side JavaScript
│   └── uploads/       # User uploaded files
├── views/
│   └── index.html     # Main application page
├── server.js          # Express server
├── package.json       # Dependencies
└── README.md          # Documentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔒 Security Considerations
&lt;/h2&gt;

&lt;p&gt;FileCloud is designed for personal use on private servers. If you plan to expose it to the internet, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementing authentication&lt;/li&gt;
&lt;li&gt;Adding SSL/TLS encryption&lt;/li&gt;
&lt;li&gt;Setting up proper firewall rules&lt;/li&gt;
&lt;li&gt;Restricting file upload types and sizes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤝 Contributing
&lt;/h2&gt;

&lt;p&gt;Contributions are welcome! Feel free to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Report bugs&lt;/li&gt;
&lt;li&gt;Suggest new features&lt;/li&gt;
&lt;li&gt;Submit pull requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/fantomas4o/filecloud" rel="noopener noreferrer"&gt;https://github.com/fantomas4o/filecloud&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📝 License
&lt;/h2&gt;

&lt;p&gt;This project is open source and available for free use.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Original article in Bulgarian: &lt;a href="https://itpraktika.com/filecloud/" rel="noopener noreferrer"&gt;FileCloud: Модерен и лек файлов мениджър&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Fedya Serafiev&lt;/strong&gt; is the creator of ITpraktika.com – a platform dedicated to practical IT solutions and automation. With extensive experience in system optimization and web technologies, he transforms complex technical cases into clear and easy-to-follow steps. His goal is to help users build more efficient and secure digital projects through real experience and proven tools.&lt;/p&gt;

&lt;p&gt;💝 If you found this article useful, consider supporting my work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paypal.com/donate/?hosted_button_id=UESCPAJUGUN2A" rel="noopener noreferrer"&gt;☕ PayPal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://revolut.me/fedya2s8q" rel="noopener noreferrer"&gt;💳 Revolut&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💖 Your support means a lot!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>filemanager</category>
      <category>webdev</category>
      <category>node</category>
    </item>
  </channel>
</rss>
