<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged server management</title>
<link>https://coderlegion.com/tag/server+management</link>
<description>Powered by Question2Answer</description>
<item>
<title>Linux Fundamentals for DevOps: Filesystem</title>
<link>https://coderlegion.com/16003/linux-fundamentals-for-devops-filesystem</link>
<description>&lt;p&gt;When you SSH into a server to fix a broken application or install a new tool, the absolute worst thing you can do is guess where files belong. Linux does not put files in random places; it follows a strict, predictable map.&lt;/p&gt;
&lt;p&gt;Understanding this map means you know exactly where to look when an application crashes, when a disk fills up, or when you need to configure a container.&lt;/p&gt;
&lt;p&gt;If you run &lt;code&gt;ls /&lt;/code&gt; on your server, you'll see a massive wall of folders.&lt;/p&gt;
&lt;p&gt;As a DevOps engineer, you don't need to memorize every single one. Here are the crucial directories you will &lt;em&gt;actually&lt;/em&gt; use, what they do, and the proof of why you should care about them.&lt;/p&gt;
&lt;h4 id=&quot;-etc-the-control-room-configurations-&quot;&gt;&lt;code&gt;/etc&lt;/code&gt; — The Control Room (Configurations)&lt;/h4&gt;
&lt;p&gt;You need to change the port your web server listens on, block a user from SSHing into the server, or configure a systemd service.&lt;/p&gt;
&lt;p&gt;Historically, &lt;code&gt;/etc&lt;/code&gt; stood for &quot;et cetera,&quot; but today it is best understood as &lt;strong&gt;Editable Text Configurations&lt;/strong&gt;. Every server, daemon, and background service stores its settings here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real scenario: Change the port Nginx listens on&lt;/strong&gt;&lt;br&gt;
Your app is running on port 80 but you need it on 8080 for a staging environment.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Step 1: Find the config
cat /etc/nginx/nginx.conf

# Step 2: Edit it
nano /etc/nginx/nginx.conf
# Change: listen 80  →  listen 8080

# Step 3: Reload (no downtime!)
systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-var-the-growing-data-hub&quot;&gt;&lt;code&gt;/var&lt;/code&gt; — The Growing Data Hub&lt;/h4&gt;
&lt;p&gt;This directory stands for &quot;&lt;strong&gt;variable&lt;/strong&gt;.&quot; It is designed to hold data that actively grows and changes while the system is running. If your server suddenly triggers a &quot;Disk Space 100%&quot; alert, &lt;code&gt;/var&lt;/code&gt; is almost always the culprit.&lt;/p&gt;
&lt;p&gt;We split this into two critical sub-directories:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/var/log&lt;/code&gt; &lt;strong&gt;(System and Application Logs):&lt;/strong&gt; Your web application returned a 500 Error, or a database failed to start. This is the very first place you check.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Watch errors as they happen, live
tail -f /var/log/nginx/error.log

# Search last 100 lines for &quot;error&quot; keyword
tail -n 100 /var/log/syslog | grep -i error

# See how much log data has accumulated
du -sh /var/log/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/var/lib&lt;/code&gt; &lt;strong&gt;(State Information and Databases):&lt;/strong&gt; This is where applications save their actual heavy data. It is where PostgreSQL stores its database files, and where Docker stores its images and containers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# &quot;Why is my disk 80% full after installing Docker?&quot;
du -sh /var/lib/docker

# Prune unused Docker images to reclaim space
docker system prune -a

# Where PostgreSQL stores its actual database files
ls /var/lib/postgresql/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; On modern Linux (Ubuntu 20.04+, Debian 10+), &lt;code&gt;/lib&lt;/code&gt; is not a real directory anymore. You can see &lt;code&gt;/lib&lt;/code&gt; and &lt;code&gt;/usr/lib&lt;/code&gt; has common files&lt;/p&gt;
&lt;h4 id=&quot;-home-and-root-user-territories&quot;&gt;&lt;code&gt;/home&lt;/code&gt; and &lt;code&gt;/root&lt;/code&gt; — User Territories&lt;/h4&gt;
&lt;p&gt;You need to grant a new developer SSH access to a server, or you need to authenticate your server to pull code from a private Git repository.&lt;/p&gt;
&lt;p&gt;These directories hold user-specific files. &lt;code&gt;/home&lt;/code&gt; contains folders for standard users (e.g., &lt;code&gt;/home/saeed&lt;/code&gt;), while &lt;code&gt;/root&lt;/code&gt; is the isolated home directory for the superuser.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The DevOps importance:&lt;/strong&gt; configuration files starting with a dot that control how tools behave per-user. Your &lt;code&gt;.bashrc&lt;/code&gt; (shell settings), &lt;code&gt;.kube/config&lt;/code&gt; (Kubernetes cluster access credentials), and &lt;code&gt;.ssh/&lt;/code&gt; (SSH keys) are all stored here.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Grant a new developer SSH access
# They send you their public key. You do this:
cat dev-alice-key.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys

# Verify it was added
tail -n 3 ~/.ssh/authorized_keys

# Alice can now SSH in — no password needed
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-proc-the-matrix-a-window-into-the-kernel-&quot;&gt;&lt;code&gt;/proc&lt;/code&gt; — The Matrix (A Window Into the Kernel)&lt;/h4&gt;
&lt;p&gt;You are running a Docker container and need to know exactly how much memory the kernel is allowing it to use, or you need to see the exact environment variables a running process received. Every running process gets a numbered folder here (its Process ID, or PID) containing its live runtime data.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/proc&lt;/code&gt; The files aren't stored on disk — they don't exist until you read them. It is a &quot;&lt;strong&gt;virtual filesystem&lt;/strong&gt;&quot; created in memory by the Linux kernel. . The moment you open &lt;code&gt;/proc/1234/status&lt;/code&gt;, the kernel generates the content on the fly. It's a live feed into what's actually happening right now.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Find the PID of your container's main process
docker inspect --format='{{.State.Pid}}' my-container

# See every env variable it received at startup
cat /proc/1234/environ | tr '\0' '\n'

# See what files/sockets it has open right now
ls -la /proc/1234/fd

# See exact memory usage the kernel is tracking
cat /proc/1234/status | grep VmRSS

# How long has this server been running?
cat /proc/uptime

# CPU info — useful in CI/CD pipelines
cat /proc/cpuinfo | grep &quot;model name&quot; | head -1

# Current memory usage
cat /proc/meminfo
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-dev-everything-is-a-file&quot;&gt;&lt;code&gt;/dev&lt;/code&gt; — Everything is a File&lt;/h4&gt;
&lt;p&gt;Linux's philosophy is: &lt;strong&gt;&lt;em&gt;&quot;if it can be read from or written to, it's a file.&quot;&lt;/em&gt;&lt;/strong&gt; Your hard drive? A file. A USB drive? A file. Even &lt;em&gt;nothingness&lt;/em&gt; and &lt;em&gt;randomness&lt;/em&gt; are files. /dev is where all these hardware-and-virtual devices live as file objects. Your hard drives show up here (like &lt;code&gt;/dev/sda&lt;/code&gt; or &lt;code&gt;/dev/nvme0n1&lt;/code&gt;). But it also holds special virtual devices that are incredibly useful for scripting.&lt;/p&gt;
&lt;p&gt;You are writing a cron job and want to completely hide its output so it doesn't spam your logs, or you are attaching a new block storage volume to your cloud instance.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;#/dev/null — The Black Hole                                                                                                                                                                                                                                                                                                                                                        
# This cron job spams your mail. Make it silent:
# The &quot;2&amp;gt;&amp;amp;1&quot; part also redirects error output to null

./noisy-backup-script.sh &amp;gt; /dev/null 2&amp;gt;&amp;amp;1

# Useful breakdown:
#   &amp;gt;           redirects stdout
#   /dev/null   the black hole
#   2&amp;gt;&amp;amp;1        also send stderr to wherever stdout goes
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-usr-the-real-home-of-installed-software&quot;&gt;&lt;code&gt;/usr&lt;/code&gt; — The Real Home of Installed Software&lt;/h4&gt;
&lt;p&gt;You downloaded a pre-compiled binary (like &lt;code&gt;terraform&lt;/code&gt; or &lt;code&gt;helm&lt;/code&gt;) and want to install it so that anyone on the server can use it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/usr&lt;/code&gt; (&lt;strong&gt;Unix System Resources&lt;/strong&gt;) is where the vast majority of your installed applications, libraries, and tools actually live.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The DevOps importance:&lt;/strong&gt; When you manually download and install a binary, you should place it in &lt;code&gt;/usr/local/bin&lt;/code&gt;. This specific folder is meant for tools managed by the system administrator, ensuring they don't get overwritten when the system package manager (like &lt;code&gt;apt&lt;/code&gt; or &lt;code&gt;yum&lt;/code&gt;) runs its automated updates.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Move a downloaded binary to the standard location for user-installed tools
mv terraform /usr/local/bin/terraform
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-opt-third-party-add-ons&quot;&gt;&lt;code&gt;/opt&lt;/code&gt; — Third-Party Add-ons&lt;/h4&gt;
&lt;p&gt;You are installing a heavy monitoring agent like Datadog, or a proprietary vendor application.&lt;/p&gt;
&lt;p&gt;Linux reserves &lt;code&gt;/opt&lt;/code&gt; (&lt;strong&gt;Optional software&lt;/strong&gt;) for self-contained, third-party applications. Instead of scattering files across &lt;code&gt;/usr&lt;/code&gt; and &lt;code&gt;/etc&lt;/code&gt;, these monolithic tools keep everything neatly sandboxed inside their own dedicated folder here.&lt;/p&gt;
&lt;h4 id=&quot;-tmp-the-throwaway-folder&quot;&gt;&lt;code&gt;/tmp&lt;/code&gt; — The Throwaway Folder&lt;/h4&gt;
&lt;p&gt;You need to download a zip file, extract a shell script, run it, and never think about it again.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;/tmp&lt;/code&gt; directory is for temporary files. It is completely wiped clean every time the server reboots, so you should never put persistent or important data here. It also usually has open write permissions, making it the perfect staging ground for quick tasks.&lt;/p&gt;
&lt;h4 id=&quot;blog-summary&quot;&gt;Blog Summary&lt;/h4&gt;
&lt;p&gt;This guide breaks down the essential directories every DevOps engineer needs to know—like &lt;code&gt;/etc&lt;/code&gt; for configurations, &lt;code&gt;/var&lt;/code&gt; for logs, and &lt;code&gt;/proc&lt;/code&gt; for live system processes. Complete with real-world use cases and simulated terminal outputs, this post serves as a practical map for quickly troubleshooting crashes, managing servers, and finding exactly what you need without getting lost.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/16003/linux-fundamentals-for-devops-filesystem</guid>
<pubDate>Mon, 27 Apr 2026 16:45:41 +0000</pubDate>
</item>
<item>
<title>Linux Fundamentals For DevOps: Linux core mechanism</title>
<link>https://coderlegion.com/16002/linux-fundamentals-for-devops-linux-core-mechanism</link>
<description>&lt;p&gt;Knowing where files live is only half the battle. To be an effective DevOps engineer, you need to know how Linux actually executes programs, manages their lifecycles, and secures them.&lt;br&gt;
The crucial concepts you need to troubleshoot effectively.&lt;/p&gt;
&lt;h3 id=&quot;the-path-variable&quot;&gt;The &lt;code&gt;$PATH&lt;/code&gt; Variable&lt;/h3&gt;
&lt;p&gt;Linux does not search your entire hard drive when you type a command. It only checks a specific, prioritized list of folders. This list is saved in an environment variable called &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You download a new binary tool (like &lt;code&gt;kubectl&lt;/code&gt; or &lt;code&gt;terraform&lt;/code&gt;). You type its name in the terminal, but Linux replies with the dreaded &lt;code&gt;command not found&lt;/code&gt;. To fix this, you must either move the binary into a folder that is already in your &lt;code&gt;$PATH&lt;/code&gt;, or add your custom folder to the &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Command: View the list of directories Linux currently checks for commands

echo $PATH

# Output Proof (Directories are separated by colons):
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Command: Add your custom scripts folder to the PATH for the current session

export PATH=&quot;/home/saeed/custom-scripts:$PATH&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;how-binaries-work-shared-libraries-&quot;&gt;How Binaries Work (Shared Libraries)&lt;/h3&gt;
&lt;p&gt;When you run a command like &lt;code&gt;nginx&lt;/code&gt; or &lt;code&gt;python&lt;/code&gt;, you are executing a binary file. In Linux, executables are typically formatted as ELF (Executable and Linkable Format) files. However, most binaries are not standalone; they rely on external pieces of code called shared libraries (&lt;code&gt;.so&lt;/code&gt; files, similar to &lt;code&gt;.dll&lt;/code&gt; files in Windows).&lt;/p&gt;
&lt;p&gt;You compile a Go application or migrate a tool into a minimal Docker container (like Alpine Linux). When you run it, it crashes silently or throws a confusing &lt;code&gt;no such file or directory&lt;/code&gt; error—even though you can see the binary sitting right there. Usually, the binary isn't missing; &lt;strong&gt;its required &lt;em&gt;libraries&lt;/em&gt; are missing.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can use the &lt;code&gt;ldd&lt;/code&gt; command to print the shared libraries required by any program.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Command: Verify exactly which shared libraries Nginx needs to run
ldd /usr/sbin/nginx

# Output Proof:
        linux-vdso.so.1 (0x00007ffe3b1f4000)
        libcrypt.so.1 =&amp;gt; /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f3a8b411000)
        libpcre.so.3 =&amp;gt; /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3a8b39c000)
        libssl.so.3 =&amp;gt; /lib/x86_64-linux-gnu/libssl.so.3 (0x00007f3a8b2f6000)
        libc.so.6 =&amp;gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3a8b0cd000)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;file-permission&quot;&gt;File Permission&lt;/h3&gt;
&lt;p&gt;Linux strict permissions dictate exactly who can &lt;strong&gt;R&lt;/strong&gt;ead, &lt;strong&gt;W&lt;/strong&gt;rite, or e&lt;strong&gt;X&lt;/strong&gt;ecute a file. This is often represented by numbers (like 777 or 644).&lt;/p&gt;
&lt;p&gt;You are trying to connect to a cloud server via SSH using a private key (&lt;code&gt;.pem&lt;/code&gt; file), but the connection is instantly rejected. If you set a &lt;code&gt;.pem&lt;/code&gt; file to &lt;code&gt;777&lt;/code&gt; (meaning everyone on the system can &lt;strong&gt;read&lt;/strong&gt;, &lt;strong&gt;write&lt;/strong&gt;, and &lt;strong&gt;execute&lt;/strong&gt; it), SSH will intentionally reject it for being too exposed. Private keys must be set to &lt;code&gt;400&lt;/code&gt;—meaning absolutely no one except the owner is allowed to read it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Command: Attempting to SSH with a bad permission key
ssh -i my-key.pem ubuntu@10.0.0.5

# Output Proof:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'my-key.pem' are too open.

# Command: Secure the key so only the owner can read it (4), and no one can write (0) or execute (0)

chmod 400 my-key.pem
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;processes-and-signals&quot;&gt;Processes and Signals&lt;/h3&gt;
&lt;p&gt;Every running program is a process assigned a unique Process ID (PID). The operating system communicates with and controls these processes using &quot;Signals.&quot;&lt;/p&gt;
&lt;p&gt;An application is hogging 100% of the CPU and needs to be stopped, or Kubernetes is trying to scale down a pod without dropping active user connections. You can send a &lt;code&gt;SIGTERM&lt;/code&gt; (Signal 15), which politely asks the program to save its data and exit cleanly. Alternatively, a &lt;code&gt;SIGKILL&lt;/code&gt; (Signal 9) forcefully terminates it at the hardware level, bypassing cleanup and potentially causing data corruption.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Command: Find the Process ID of an application
pgrep -la nginx

# Output Proof:
1234 nginx: master process
1235 nginx: worker process

# Command: Politely ask the master process to shut down and clean up
kill -15 1234
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;file-descriptors&quot;&gt;File Descriptors&lt;/h3&gt;
&lt;p&gt;Remember concept , &lt;strong&gt;&quot;Everything is a File&quot;&lt;/strong&gt;? That rule has a dark side.&lt;/p&gt;
&lt;p&gt;Because Linux treats &lt;strong&gt;&lt;em&gt;network connections&lt;/em&gt;&lt;/strong&gt; as files, every time a user connects to your web server, the operating system opens a &quot;File Descriptor&quot; to track that connection. To protect itself from crashing, the Linux kernel sets strict limits on how many file descriptors a single process can open at once.&lt;/p&gt;
&lt;p&gt;Your Nginx web server or Node.js application is suddenly dropping user connections during a high-traffic spike. You check the CPU and RAM, and both are perfectly fine. You check the Nginx error logs and see the dreaded &lt;code&gt;worker_connections are not enough&lt;/code&gt; or &lt;code&gt;Too many open files&lt;/code&gt; error. The operating system has forcibly stopped your app from accepting new traffic.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;# Command: Show the maximum number of open file descriptors allowed for this user
ulimit -n

# Output Proof:
1024

# Command: Check how many file descriptors the entire system is currently using
cat /proc/sys/fs/file-nr

# Output Proof:
1205   0   9223372036854775807
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;blog-summary-1&quot;&gt;Blog Summary&lt;/h4&gt;
&lt;p&gt;Understanding Linux goes beyond knowing where files live; it’s about understanding how the operating system executes code, secures data, and manages its own limits. This guide breaks down the invisible mechanics of Linux that every DevOps engineer must master to troubleshoot effectively.&lt;/p&gt;
&lt;p&gt;You'll learn why binaries silently fail due to missing shared libraries, how to quickly fix &quot;command not found&quot; errors using the &lt;code&gt;$PATH&lt;/code&gt; variable, and the strict permission rules required to secure SSH keys. We also cover how to safely manage and terminate running processes using signals, and finally, uncover the hidden trap of File Descriptors—explaining why servers suddenly drop connections with &quot;Too many open files&quot; errors and how to raise those limits.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/16002/linux-fundamentals-for-devops-linux-core-mechanism</guid>
<pubDate>Mon, 27 Apr 2026 16:45:13 +0000</pubDate>
</item>
</channel>
</rss>