<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thomas Jager</title>
    <description>The latest articles on DEV Community by Thomas Jager (@aka_artem_dd17be93c).</description>
    <link>https://dev.to/aka_artem_dd17be93c</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%2F3372101%2F3e20e52b-8501-4ab8-8071-2deba9872e59.png</url>
      <title>DEV Community: Thomas Jager</title>
      <link>https://dev.to/aka_artem_dd17be93c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aka_artem_dd17be93c"/>
    <language>en</language>
    <item>
      <title>First sakila project log</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Tue, 28 Oct 2025 12:33:40 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/first-sakila-project-log-3hl4</link>
      <guid>https://dev.to/aka_artem_dd17be93c/first-sakila-project-log-3hl4</guid>
      <description>&lt;p&gt;📅 Date: 2025-10-16 → 2025-10-18&lt;/p&gt;

&lt;p&gt;🔧 Tools: Python, Pydantic, MySQL, JSON, Git Submodules&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;How It Started&lt;/p&gt;

&lt;p&gt;I hit a point where my project needed more than raw input() checks.&lt;br&gt;
Validation logic was scattered between main.py, connectors, and random if/else.&lt;br&gt;
Time to clean it up.&lt;/p&gt;

&lt;p&gt;At the same time, my teacher asked to create a separate repo for homeworks, but I already use a monorepo. I finally decided to try something I wanted a long time:&lt;/p&gt;

&lt;p&gt;create a second repo and attach it as git submodule.&lt;/p&gt;

&lt;p&gt;So now advanced_python lives inside my main PythonJourney repo.&lt;/p&gt;




&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;User input validation became too complicated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keyword must be validated&lt;/li&gt;
&lt;li&gt;genre must exist in DB&lt;/li&gt;
&lt;li&gt;years must be within allowed range&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed one system that handles all validation in one place.&lt;/p&gt;

&lt;p&gt;Also, performing validation directly against the DB was slow.&lt;br&gt;
Each user input triggered a DB read.&lt;/p&gt;




&lt;p&gt;The Fix:&lt;/p&gt;

&lt;p&gt;1.Created a separate module dedicated only to validation.&lt;br&gt;
All checks now run through Pydantic.&lt;/p&gt;

&lt;p&gt;2.Extracted genres from the Sakila database and saved them into genre.json.&lt;/p&gt;

&lt;p&gt;3.Created a cache module to load genres once and keep them in a dict&lt;br&gt;
so validation is instant.&lt;/p&gt;

&lt;p&gt;4.Added custom validators in Pydantic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keyword validation&lt;/li&gt;
&lt;li&gt;genre existence check (compared using cache dict)&lt;/li&gt;
&lt;li&gt;year range validation&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Updated main.py to send user input through Pydantic first, then run DB query.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;What I Learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validation belongs between user input and DB, not inside DB logic.&lt;/li&gt;
&lt;li&gt;Pydantic simplifies input handling and makes code cleaner.&lt;/li&gt;
&lt;li&gt;Cache is faster than querying the DB on every input.&lt;/li&gt;
&lt;li&gt;Git submodules are perfect when you want to keep a monorepo but split projects.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✍ Personal Note&lt;br&gt;
Not a huge feature, but this was the first time when the structure finally felt right.&lt;/p&gt;

</description>
      <category>python</category>
      <category>sideprojects</category>
      <category>mysql</category>
      <category>programming</category>
    </item>
    <item>
      <title>Log015_sakila_mysql_pymongo</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Fri, 17 Oct 2025 18:02:58 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log015sakilamysqlpymongo-9na</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log015sakilamysqlpymongo-9na</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;about.post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;title: "First School Project: Kino Search"&lt;/p&gt;

&lt;p&gt;date: 2025-09-24&lt;/p&gt;

&lt;p&gt;tags: [python, mysql, mongodb, school-project, learning]&lt;/p&gt;

&lt;p&gt;summary: "My first real Python project — a console movie search app built with MySQL and MongoDB. Graded 1 (Sehr Gut)."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqotbmn1co0jezdw58d1r.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%2Fqotbmn1co0jezdw58d1r.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎬 Kino Search — My First School Project&lt;/p&gt;

&lt;p&gt;Graded 1 (Sehr Gut) - &lt;a href="https://github.com/ThomasJager99/sakila_movie_search" rel="noopener noreferrer"&gt;https://github.com/ThomasJager99/sakila_movie_search&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“It started as a simple console movie search app.&lt;br&gt;
Then it became my first real experience of building something that actually works.”&lt;br&gt;
I. The Beginning&lt;/p&gt;

&lt;p&gt;This was my first school project — a console application for movie search.&lt;br&gt;
I built it completely from scratch: no templates, no frameworks, no IDE automation.&lt;br&gt;
Just a terminal, a clean .venv, and a few libraries.&lt;/p&gt;

&lt;p&gt;cd Projects/movie_search/&lt;br&gt;
python -m venv .venv&lt;br&gt;
source .venv/bin/activate&lt;br&gt;
pip install pymysql pymongo python-dotenv tabulate&lt;/p&gt;

&lt;p&gt;That’s where it all started — the moment when theory turned into practice.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;II. Connecting the Databases&lt;/p&gt;

&lt;p&gt;I created a .env file for database credentials and added it to .gitignore.&lt;/p&gt;

&lt;p&gt;My first test script didn’t work — the school’s MySQL server was down.&lt;/p&gt;

&lt;p&gt;Later it came back online, and my connection finally succeeded.&lt;/p&gt;

&lt;p&gt;Then I connected MongoDB to handle logs.&lt;br&gt;
A simple test created a document with my name and returned an ID.&lt;br&gt;
That was the first “alive” moment of the project.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;III. SQL vs NoSQL&lt;/p&gt;

&lt;p&gt;Working with both databases side by side taught me a lot:&lt;/p&gt;

&lt;p&gt;• MySQL — explicit open/close, manual sessions.&lt;br&gt;
• MongoDB — persistent client, automatic connection pooling.&lt;/p&gt;

&lt;p&gt;Different rules, different personalities, one task: make them cooperate.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;IV. Refactoring the Code&lt;/p&gt;

&lt;p&gt;After a few tests the code became messy — too many prints, repeated connections.&lt;br&gt;
I cleaned everything up:&lt;/p&gt;

&lt;p&gt;• Added _mysql_conn() encapsulation.&lt;br&gt;
• Moved credentials and factories into config.py.&lt;br&gt;
• Created log_writer.py for Mongo logging.&lt;br&gt;
• Made each module communicate through config.py.&lt;/p&gt;

&lt;p&gt;Now MySQL opens and closes cleanly for every query,&lt;br&gt;
and MongoDB stays persistent through one global client.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;V. Organizing the Project&lt;/p&gt;

&lt;p&gt;To keep things under control, I expanded my PyCharm task markers:&lt;br&gt;
TODO, WIP, BUG, NOTE, QUESTION.&lt;br&gt;
Small detail, but it keeps focus on what matters.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;VI. What I Learned&lt;/p&gt;

&lt;p&gt;• How to manage two databases in one project.&lt;br&gt;
• Why context managers matter for clean SQL sessions.&lt;br&gt;
• How to refactor config and connection logic properly.&lt;br&gt;
• How structure makes learning faster and calmer.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;VII. Closing Thoughts&lt;/p&gt;

&lt;p&gt;Kino Search was my first real experience of putting theory into code —&lt;br&gt;
a simple console app, but a complete working system.&lt;br&gt;
It was later graded 1 (Sehr Gut) — and that feels like a solid start.&lt;/p&gt;

</description>
      <category>python</category>
      <category>database</category>
      <category>linux</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>PromptLock: When AI Meets Ransomware</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Thu, 11 Sep 2025 07:44:00 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/promptlock-when-ai-meets-ransomware-1h6f</link>
      <guid>https://dev.to/aka_artem_dd17be93c/promptlock-when-ai-meets-ransomware-1h6f</guid>
      <description>&lt;p&gt;So, this week I stumbled across something that instantly caught my eye: PromptLock. Researchers dug it up, and it's basically the first ransomware prototype that runs on top of a local AI model. &lt;/p&gt;

&lt;p&gt;Yeah, not ChatGPT through an API, but an actual LLM sitting right there on your machine, helping the malware decide what to do.&lt;/p&gt;




&lt;p&gt;What's Going On Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PromptLock uses a local model called gpt-oss:20b (running via Ollama).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of shipping one fixed script, it tells the model: "Hey, write me some Lua code to scan these folders". Then next run it might generate a slightly different script.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those scripts can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;list and filter your files&lt;/li&gt;
&lt;li&gt;pick "valuable" stuff&lt;/li&gt;
&lt;li&gt;encrypt or even exfiltrate it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically, it doesn't look the same each time, which is a nightmare for signature-based antiviruses.&lt;/p&gt;




&lt;p&gt;Why It Matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's cross-platform - Windows, Linux, macOS.&lt;/li&gt;
&lt;li&gt;It's adaptive - behavior shifts each time.&lt;/li&gt;
&lt;li&gt;And it's local - so no obvious API calls to track.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, not everyone's going to be hit by this. Most people don't have a giant LLM sitting on their personal laptop. &lt;/p&gt;

&lt;p&gt;This smells way more like a corporate-level threat: servers, research labs, or any environment where local AI models are being tested. &lt;/p&gt;

&lt;p&gt;For everyday users, your bigger risk is still the usual phishing mails and classic ransomware.&lt;/p&gt;




&lt;p&gt;What We Can Actually Do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Backups (the ones you test and actually restore).&lt;/li&gt;
&lt;li&gt;Least privilege (don't run daily stuff as root/admin).&lt;/li&gt;
&lt;li&gt;Watch your scripts - random Lua popping up on your box is never a good sign.&lt;/li&gt;
&lt;li&gt;Behavior-based security tools over signature-based.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nothing revolutionary here, but PromptLock shows how fast attackers adapt.&lt;/p&gt;




&lt;p&gt;My Take&lt;/p&gt;

&lt;p&gt;To me, the interesting bit isn't "oh no, AI is evil," but that malware authors are now treating LLMs as toolchains. They don't even need to write perfect malware anymore - they just need a model that can generate and tweak code on demand.&lt;/p&gt;

&lt;p&gt;Feels like a new chapter in the cat-and-mouse game. But again, this isn't a doomsday scenario for every PC out there. It's a warning shot for enterprises and anyone experimenting with self-hosted AI.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>learning</category>
      <category>security</category>
      <category>news</category>
    </item>
    <item>
      <title>Log014_CloudFlare_Zoho.mail_ec2.md</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Thu, 04 Sep 2025 14:48:45 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log014cloudflarezohomailec2md-2pn3</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log014cloudflarezohomailec2md-2pn3</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;about.post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📅 Date: 2025-09-04&lt;/p&gt;

&lt;p&gt;🔧 Tools: Cloudflare, Zoho Mail, AWS EC2, Elastic IP, Apache, Certbot (Let’s En$ &lt;/p&gt;




&lt;p&gt;How It Started:&lt;/p&gt;

&lt;p&gt;Today’s goal was to protect my website. I decided to start with Cloudflare and $&lt;/p&gt;




&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;To have a proper setup I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Email address for the domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DNS records for website + mail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static IP for my AWS instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SSL certificate installed directly on the server&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Fix&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Domain + SSL via Cloudflare:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Bought a domain on Cloudflare&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activated free SSL included in the plan&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Zoho Mail setup:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Used Zoho’s free plan (5 GB/mailbox, up to 5 accounts)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authorized DNS with Zoho and added MX records (mx.zoho.eu)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configured priority levels (10 → 20 → 30) for redundancy&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;DNS Records:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Added www as a CNAME alias&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set MX for mail delivery&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bound domain to AWS Elastic IP (so DNS won’t break after reboot)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Elastic IP:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Allocated Elastic IP in AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attached it to the EC2 instance to prevent IP changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;SSL Certificate (Let’s Encrypt + Certbot):&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Installed certbot on the EC2 instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generated SSL certificate with certbot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configured Apache to use HTTPS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I Learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cloudflare free plan already includes Universal SSL, but server-side SSL is s$&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MX records define where domain mail goes, priority numbers ensure fallback or$&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elastic IP is essential for stable DNS pointing to AWS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Certbot automates SSL certificate creation and Apache integration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real setup = domain → Cloudflare proxy → AWS server with SSL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✍ Personal Note:&lt;br&gt;
All of this was mostly for learning — now my portfolio website has HTTPS.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>debian</category>
      <category>aws</category>
      <category>dns</category>
    </item>
    <item>
      <title>Log013 - AWS, Debian 13, Fail2ban, Logrotate, Docker, AlmaLinux, Apache, AWS S3, CloudFront, AWS CLI.</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Fri, 29 Aug 2025 14:04:25 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log013-aws-debian-13-fail2ban-logrotate-docker-almalinux-apache-aws-s3-cloudfront-aws-34j</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log013-aws-debian-13-fail2ban-logrotate-docker-almalinux-apache-aws-s3-cloudfront-aws-34j</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;about.post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📅 Date: 2025-08-29&lt;/p&gt;

&lt;p&gt;🔧 Tools: AWS, Debian 13, Fail2ban, Logrotate, Docker, AlmaLinux, Apache, AWS S3, CloudFront, AWS CLI&lt;/p&gt;

&lt;p&gt;How It Started&lt;/p&gt;

&lt;p&gt;I continued hardening my AWS server and setting up proper logging and monitoring. At the same time, I experimented with AlmaLinux in Docker to get a taste of corporate Linux environments. On the frontend side, I played with AI-generated React templates and finally connected AWS S3 with CloudFront to serve static files.&lt;/p&gt;

&lt;p&gt;The Problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up fail2ban and logrotate required extra tweaking.&lt;/li&gt;
&lt;li&gt;After switching the SSH port, I initially locked myself out until I fixed both the AWS firewall rules and the server’s configs.&lt;/li&gt;
&lt;li&gt;AlmaLinux containers are extremely minimal — no passwd, no shadow-tools, no utilities.&lt;/li&gt;
&lt;li&gt;Apache cached a doomed image and refused to update it on the website.&lt;/li&gt;
&lt;li&gt;With S3 → I had to figure out how to keep my bucket private but still serve files publicly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Fix:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installed logrotate on AWS, set up fail2ban for SSH.&lt;/li&gt;
&lt;li&gt;Reinstalled htop and tmux on Debian 13 to make SSH work easier.&lt;/li&gt;
&lt;li&gt;Backed up and locked down SSH keys on an external drive.&lt;/li&gt;
&lt;li&gt;Adjusted SSH config → added rules in AWS firewall first, then updated the server configs. Learned about jail.d/sshd_config.d for persistent overrides.&lt;/li&gt;
&lt;li&gt;Spun up an AlmaLinux container (800 MB base) → installed passwd, shadow-tools, and basic utils with dnf.&lt;/li&gt;
&lt;li&gt;Fixed Apache image issue by replacing the faulty picture with a valid one.&lt;/li&gt;
&lt;li&gt;Set up AWS CLI on Mac, created a dedicated IAM user with keys, and configured ~/.zshrc for easier usage.&lt;/li&gt;
&lt;li&gt;Created private S3 bucket + CloudFront distribution → now static content (images, etc.) is served globally while keeping the bucket private.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I Learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Persistent SSH configs live in /etc/ssh/sshd_config.d/ and survive updates.&lt;/li&gt;
&lt;li&gt;AlmaLinux base containers are minimal — need to manually add tools.&lt;/li&gt;
&lt;li&gt;Apache may serve old/corrupted assets → sometimes it’s the file, not the cache.&lt;/li&gt;
&lt;li&gt;AWS best practice → never generate keys as root, always use IAM users.&lt;/li&gt;
&lt;li&gt;S3 + CloudFront combo = perfect way to serve static content privately but globally.&lt;/li&gt;
&lt;li&gt;Commands Used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logs cleanup on Debian&lt;/p&gt;

&lt;p&gt;sudo journalctl --vacuum-size=200M&lt;/p&gt;

&lt;p&gt;Install logrotate&lt;/p&gt;

&lt;p&gt;sudo apt install logrotate&lt;/p&gt;

&lt;p&gt;Fail2ban setup (Debian)&lt;/p&gt;

&lt;p&gt;sudo apt install fail2ban&lt;/p&gt;

&lt;p&gt;Useful tools&lt;/p&gt;

&lt;p&gt;sudo apt install htop tmux&lt;/p&gt;

&lt;p&gt;Change password utilities on AlmaLinux&lt;/p&gt;

&lt;p&gt;sudo dnf install passwd shadow-tools&lt;/p&gt;

&lt;p&gt;AWS S3: upload/download files&lt;/p&gt;

&lt;p&gt;aws s3 cp ./cat.png s3://my-bucket/cat.png aws s3 ls s3://my-bucket&lt;/p&gt;

&lt;p&gt;AWS CloudFront: invalidate cache&lt;/p&gt;

&lt;p&gt;aws cloudfront create-invalidation&lt;br&gt;
--distribution-id &lt;br&gt;
--paths "/*"&lt;/p&gt;




&lt;p&gt;✍ Personal Note: Today I finally got the “aha moment” with S3 + CloudFront: private bucket as the source, CDN as the face. Feels good to see my site pulling images from “millions of warehouses around the world.”&lt;/p&gt;

</description>
      <category>linux</category>
      <category>debian</category>
      <category>aws</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Log012 - Docker, Apache, EC2 etc.</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Sat, 23 Aug 2025 18:31:58 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log012-docker-apache-ec2-etc-31ea</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log012-docker-apache-ec2-etc-31ea</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;about.post&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;📅 Date: 2025-08-23&lt;/p&gt;

&lt;p&gt;🔧 Tools: nginx, Docker, GPG, shred, logrotate, AWS EC2, SSH, Apache&lt;/p&gt;




&lt;p&gt;How It Started&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kept working on my local server and fixing the webpage.&lt;/li&gt;
&lt;li&gt;Started learning Docker on my Mac and explored file deletion concepts.&lt;/li&gt;
&lt;li&gt;Tried to configure logrotate on Debian.&lt;/li&gt;
&lt;li&gt;Decided to set up my first AWS Debian server as a playground for future portfolio work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Problem&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub link on my local webpage pointed to a 404.&lt;/li&gt;
&lt;li&gt;Locale errors popped up every time I connected to the new AWS server.&lt;/li&gt;
&lt;li&gt;Logrotate configuration wasn’t clear at first.&lt;/li&gt;
&lt;li&gt;Learned that deleting files doesn’t actually erase them from HDD/SSD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Fix&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed the broken GitHub link by editing /var/www/html/index.nginx.&lt;/li&gt;
&lt;li&gt;Studied secure file deletion:&lt;/li&gt;
&lt;li&gt;On HDD use:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;shred -u -v -z filename.txt&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On SSD, due to TRIM, true deletion requires vendor-specific tools.&lt;/li&gt;
&lt;li&gt;Configured logrotate with custom adjustments.&lt;/li&gt;
&lt;li&gt;Installed Docker on Mac and, along the way, learned about GPG and key signatures.&lt;/li&gt;
&lt;li&gt;Set up the first AWS Debian server and fixed locale issues with:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;sudo dpkg-reconfigure locales&lt;/p&gt;

&lt;p&gt;choosing en_US.UTF-8.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Planned next step: install and test Apache (httpd).&lt;/li&gt;
&lt;li&gt;Created an SSH config on Mac for easier access to servers:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Host aws&lt;br&gt;
    HostName &lt;br&gt;
    User admin&lt;br&gt;
    IdentityFile ~/.ssh/.pem&lt;/p&gt;

&lt;p&gt;What I Learned&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes errors are trivial — one line in the config can fix a 404.&lt;/li&gt;
&lt;li&gt;HDD vs SSD file deletion is fundamentally different: SSDs require special tools.&lt;/li&gt;
&lt;li&gt;Logrotate is essential to keep the system from flooding with logs.&lt;/li&gt;
&lt;li&gt;GPG and signatures are part of the foundation of secure software distribution.&lt;/li&gt;
&lt;li&gt;AWS Debian requires fixing locales manually.&lt;/li&gt;
&lt;li&gt;SSH config is a game-changer when working with multiple servers.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✍ Personal Note:&lt;br&gt;
Feels like I’m slowly building a “server zoo”: local Debian with nginx, AWS with Apache, and Docker on my Mac.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F563highreejnimch5oju.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%2F563highreejnimch5oju.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>beginners</category>
      <category>debian</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Log011 - UFW, nginx and a dream.</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Sat, 16 Aug 2025 16:32:10 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log011-ufw-nginx-and-a-dream-4j5l</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log011-ufw-nginx-and-a-dream-4j5l</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;About.post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📅 Date: 2025-08-16 &lt;/p&gt;

&lt;p&gt;🔧 Tools: ufw, nginx, apt, systemctl&lt;/p&gt;




&lt;p&gt;How It Started:&lt;/p&gt;

&lt;p&gt;The idea was to install UFW, allow the necessary ports, and install nginx — then put something on it to test locally in browser.&lt;/p&gt;




&lt;p&gt;The Process:&lt;/p&gt;

&lt;p&gt;Install simple firewall — UFW&lt;br&gt;
sudo apt update &amp;amp;&amp;amp; sudo apt install ufw&lt;/p&gt;

&lt;p&gt;Installation went successfully, nothing to complain about. I allowed port 22 to maintain SSH connection and did it before enabling the firewall, like a smart move:&lt;/p&gt;

&lt;p&gt;sudo ufw allow 22&lt;/p&gt;

&lt;p&gt;This added a new rule: SSH is allowed. And what I really like about UFW is its default policy — everything is denied unless allowed.&lt;/p&gt;

&lt;p&gt;Allow nginx to talk to the browser Before enabling the firewall, I allowed another port:&lt;br&gt;
sudo ufw allow 80&lt;/p&gt;

&lt;p&gt;This is needed for HTTP.&lt;/p&gt;

&lt;p&gt;Install and set up the web service — nginx:&lt;br&gt;
sudo apt install nginx sudo systemctl start nginx sudo systemctl enable nginx&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgjz5qkf0ngvenn06uir.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%2Fbgjz5qkf0ngvenn06uir.png" alt=" " width="735" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although enable might not be necessary — after installation, nginx was already set to autostart on boot (as seen in systemctl status).&lt;/p&gt;

&lt;p&gt;Result:&lt;br&gt;
After a couple of iterations, I managed to create a small useful website — with all the links I need for my study. A small win for me. But it’s the foundation for future things.&lt;/p&gt;




&lt;p&gt;What I Learned&lt;/p&gt;

&lt;p&gt;• Always allow SSH before enabling the firewall.&lt;/p&gt;

&lt;p&gt;• ufw is dead simple and efficient — good choice for minimal systems.&lt;/p&gt;

&lt;p&gt;• nginx installs fast and works out of the box.&lt;/p&gt;

&lt;p&gt;• Port 80 should be explicitly opened with ufw allow 80.&lt;/p&gt;

&lt;p&gt;• Even minimal Debian is capable of serving something useful in a couple of minutes.&lt;/p&gt;




&lt;p&gt;✍ Personal Note: Little win for me. From here, I’ll build up to more.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>homelab</category>
      <category>beginners</category>
      <category>debian</category>
    </item>
    <item>
      <title>Log010 — wpa_supplicant trouble</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Fri, 15 Aug 2025 15:22:48 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log010-wpasupplicant-trouble-16l9</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log010-wpasupplicant-trouble-16l9</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;About.post&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;📅 Date: 2025-08-14 &lt;/p&gt;

&lt;p&gt;🔧 Tools: NetworkManager, ip, dhclient, rfkill, systemctl, wpa_supplicant, SSH, ssh-keygen&lt;/p&gt;




&lt;p&gt;How It Started&lt;/p&gt;

&lt;p&gt;I was setting up a fresh Debian 13 system on my server and wanted to migrate from using wpa_supplicant manually to managing my connection with NetworkManager. Along the way, I also began syncing my workflow between my Mac and the server, using SSH.&lt;/p&gt;

&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;NetworkManager broke the IP settings when I tried to restart it.&lt;br&gt;
SSH wouldn’t connect after the server rebooted because IP addresses kept changing (e.g. from .121 back to .120, which conflicted with saved keys on my Mac).&lt;br&gt;
Even after installing all the firmware and ensuring no blocks via rfkill, NetworkManager couldn’t manage the connection because wpa_supplicant was running independently.&lt;br&gt;
The Fix&lt;/p&gt;

&lt;p&gt;Manual IP Assignment (before DHCP setup):&lt;/p&gt;

&lt;p&gt;sudo ip addr add 192.189.156.120/24 dev wlp3s0&lt;br&gt;
sudo ip link set wlp3s0 up&lt;br&gt;
sudo ip route add default via 192.189.156.1&lt;br&gt;
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf&lt;/p&gt;

&lt;p&gt;Install DHCP Client:&lt;br&gt;
sudo apt install isc-dhcp-client&lt;br&gt;
sudo ip link set wlp3s0 up&lt;br&gt;
sudo dhclient -r wlp3s0&lt;br&gt;
sudo dhclient wlp3s0&lt;/p&gt;

&lt;p&gt;Check Internet:&lt;/p&gt;

&lt;p&gt;ip a&lt;br&gt;
ping 8.8.8.8&lt;br&gt;
ping google.com&lt;br&gt;
Verify Wi-Fi Module Status:&lt;br&gt;
sudo apt install rfkill&lt;br&gt;
rfkill list&lt;/p&gt;

&lt;p&gt;Disable wpa_supplicant Process:&lt;/p&gt;

&lt;p&gt;sudo systemctl stop wpa_supplicant&lt;/p&gt;

&lt;p&gt;sudo systemctl disable wpa_supplicant&lt;/p&gt;

&lt;h1&gt;
  
  
  Later: sudo systemctl mask wpa_supplicant (for hard stop)
&lt;/h1&gt;

&lt;p&gt;Fix SSH Key Conflict on Mac:&lt;br&gt;
ssh-keygen -R 192.189.156.120&lt;/p&gt;

&lt;h1&gt;
  
  
  Reconnect to update known_hosts
&lt;/h1&gt;

&lt;p&gt;Comment Out Auto-wpa_supplicant Launch:&lt;br&gt;
Edit /etc/network/interfaces and comment out any lines that autostart wpa_supplicant&lt;/p&gt;

&lt;p&gt;Stress Test:&lt;br&gt;
Performed 5 reboots. Verified that IP remains stable (e.g., 192.189.156.120) only after masking wpa_supplicant and removing DHCP-based IP churn.&lt;br&gt;
What I Learned&lt;/p&gt;

&lt;p&gt;wpa_supplicant can launch outside of NetworkManager and interfere.&lt;/p&gt;

&lt;p&gt;mask in systemctl completely disables the unit, redirecting it to /dev/null.&lt;/p&gt;

&lt;p&gt;DHCP client assigns dynamic IPs on reboot unless static configuration is forced.&lt;/p&gt;

&lt;p&gt;ssh-keygen -R  is a lifesaver for known_hosts mismatch.&lt;/p&gt;

&lt;p&gt;/etc/network/interfaces still matters in CLI-only Debian setups.&lt;/p&gt;

&lt;p&gt;rfkill is critical for diagnosing Wi-Fi module blocks.&lt;/p&gt;




&lt;p&gt;✍ Personal Note:&lt;/p&gt;

&lt;p&gt;This was an interesting experience, because I made a lot of unnecessary moves. Like with every beginning - just like in Kendo - before you can strike properly, you’ll make a bunch of mistakes. But all of them are worth it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dys1k076anyccwc2vqr.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%2F3dys1k076anyccwc2vqr.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>debian</category>
      <category>homelab</category>
      <category>selftaught</category>
    </item>
    <item>
      <title>Log009 - Debian 13</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Fri, 15 Aug 2025 15:17:33 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log009-debian-13-4b46</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log009-debian-13-4b46</guid>
      <description>&lt;p&gt;Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;About.post&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;📅 Date: 2025-08-14 🔧 Tools: USB with Debian 13&lt;/p&gt;




&lt;p&gt;How It Started&lt;/p&gt;

&lt;p&gt;It all started when I realized that my system, even after removing the GUI, was still heavy. It was a great experience troubleshooting the issues that came after deleting the GUI along with a bunch of variables and caches.&lt;/p&gt;

&lt;p&gt;I used sudo apt --purge and ended up losing SSH, drivers, and a bunch of other things. I managed to fix most of them, but the system was already a mess.&lt;/p&gt;

&lt;p&gt;So today, I rebooted and installed a fresh Debian 13 (light) on my server.&lt;/p&gt;




&lt;p&gt;The Problem&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Removed almost all network components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleted drivers, especially ath10k_pci (internet-related).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Made a big mess in the file system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Had trouble with a 5G Wifi connection — Debian 12 wouldn’t let me use my 5Gb internet because it wasn’t friendly with my drivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The Fix&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Most file system issues were solved after spending a lot of time cleaning things up. I created one main directory for everything and built a tree with manuals and notes inside it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The network was trickier — I had to use a USB stick, find the right driver manually, download it, and then set up wpa_supplicant &amp;amp; wpa_passphrase to create the first connection. After that, I installed Network Manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The 5G issue wasn’t completely solved. I replaced my firmware with a newer one, which gave me a 5G connection, but the speed was only 15 Mb/s.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the end, I decided to completely erase the system. First, I created a tar -czf backup of the main directory and saved it to an external drive. Then I installed Debian 13 — now I’m building my environment from scratch, starting with a clean 1.4 GB base.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;What I Learned&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to set up a network connection from scratch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to organize space better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to create a personalized environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to use usermod to rename the server (did it twice).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gained a deeper understanding of my system.&lt;/p&gt;&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%2Fq12v8l02azdcn5p5hfou.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%2Fq12v8l02azdcn5p5hfou.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>debian</category>
      <category>homelab</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Log001 - 008/ From Ubuntu to Debian journey.</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Fri, 15 Aug 2025 15:10:50 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/log001-008-from-ubuntu-to-debian-journey-3m4m</link>
      <guid>https://dev.to/aka_artem_dd17be93c/log001-008-from-ubuntu-to-debian-journey-3m4m</guid>
      <description>&lt;h1&gt;
  
  
  Start-here.page=&lt;a href="https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94"&gt;About.post&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;A bit of context…&lt;/p&gt;

&lt;p&gt;I first discovered Linux a little over 3 months ago — and honestly, it was love at first boot. From the very beginning, I chose Ubuntu, the most beginner-friendly distro, and started exploring everything I could get my hands on: SSH, Nginx, UFW… you name it.&lt;/p&gt;

&lt;p&gt;For the first few weeks, it felt like I had entered a new world.&lt;/p&gt;

&lt;p&gt;But after a month of living in Linux day and night, it started to feel… easy. Too easy.&lt;/p&gt;

&lt;p&gt;I realized I wanted more control. A cleaner, more focused environment. That’s when I started looking into alternatives — something closer to the bare metal, but still stable.&lt;/p&gt;

&lt;p&gt;After some research, I settled on Debian 12. It felt like the right choice for my learning goals and the server project I had in mind.&lt;/p&gt;

&lt;p&gt;So, I made the jump. &lt;/p&gt;




&lt;p&gt;Log 001&lt;/p&gt;

&lt;p&gt;⚙Week 1 — Distro Migration: Ubuntu → Debian 12&lt;/p&gt;

&lt;p&gt;Background: &lt;/p&gt;

&lt;p&gt;• First contact with Linux: ~3 months ago &lt;/p&gt;

&lt;p&gt;• Initial distro: Ubuntu (for accessibility and package availability) &lt;/p&gt;

&lt;p&gt;• Explored basics: SSH, Nginx, UFW, local networking&lt;/p&gt;

&lt;p&gt;Motivation to switch: &lt;/p&gt;

&lt;p&gt;• Ubuntu became too “user-friendly” for learning deeper system control &lt;/p&gt;

&lt;p&gt;• Wanted a cleaner, more minimal system &lt;/p&gt;

&lt;p&gt;• Seeking full control for headless server setup&lt;/p&gt;

&lt;p&gt;Decision: &lt;br&gt;
• Switched to Debian 12 &lt;/p&gt;

&lt;p&gt;• Chosen for: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Stability &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better suitability for terminal-based workflows &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Educational value for learning real Linux internals&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Status: Migration complete. Debian is now the base OS for server experiments.&lt;/p&gt;




&lt;p&gt;LOG 002&lt;/p&gt;

&lt;p&gt;Install Process: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ubuntu removed &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Debian 12 installed (successful on 3rd attempt) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chosen for lightweight footprint (~5 GB with minimal GUI) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GUI kept temporarily for orientation (XFCE)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wi-Fi Issue: &lt;br&gt;
• 5GHz reception broken due to hostapd update &lt;/p&gt;

&lt;p&gt;• Conflict between access point tools and receiver module &lt;/p&gt;

&lt;p&gt;• Hardware supports 5GHz, but driver setup unstable&lt;/p&gt;

&lt;p&gt;Initial Configuration: &lt;/p&gt;

&lt;p&gt;• SSH Remote Access enabled &lt;/p&gt;

&lt;p&gt;• Performance mode set via CLI &lt;/p&gt;

&lt;p&gt;• Root access used to grant sudo to user (sudoers config missing by default) &lt;/p&gt;

&lt;p&gt;• Initial SSH connection unstable — high packet loss&lt;/p&gt;

&lt;p&gt;Status: Debian system installed, partially configured. Further tuning in progress.&lt;/p&gt;




&lt;p&gt;LOG 003&lt;/p&gt;

&lt;p&gt;Test: &lt;/p&gt;

&lt;p&gt;• Source: ~/scripts/ directory on Ubuntu &lt;/p&gt;

&lt;p&gt;• Contents: mostly shell scripts in nested folders &lt;/p&gt;

&lt;p&gt;• Packed into tar.zip archive &lt;/p&gt;

&lt;p&gt;• Transferred to Debian system and unpacked&lt;/p&gt;

&lt;p&gt;Observation: &lt;/p&gt;

&lt;p&gt;• On Ubuntu: archive size ~68 MB &lt;/p&gt;

&lt;p&gt;• On Debian (unpacked): directory size ~7.2 MB &lt;/p&gt;

&lt;p&gt;• No visible difference in files or structure&lt;/p&gt;

&lt;p&gt;Conclusion: &lt;/p&gt;

&lt;p&gt;• Ubuntu system likely added extended attributes, hidden metadata, cache or indexing data to file structures &lt;/p&gt;

&lt;p&gt;• Debian maintains a cleaner FS footprint on identical data&lt;/p&gt;

&lt;p&gt;Takeaway: Debian provides significantly leaner storage behavior for plain-text scripts and directories. Useful for minimal setups or scripting environments.&lt;/p&gt;




&lt;p&gt;LOG 004&lt;/p&gt;

&lt;p&gt;Server identity and hostname updated.&lt;/p&gt;

&lt;p&gt;I’ve decided to name my personal development server. The machine is a six-year-old laptop with the following specs: &lt;/p&gt;

&lt;p&gt;• Intel Core i5 • 120 GB SSD &lt;/p&gt;

&lt;p&gt;• 20 GB DDR4 RAM (manually upgraded)&lt;/p&gt;

&lt;p&gt;While working with it on a daily basis — SSH, packages, configurations — I realized that naming the machine would be a meaningful step. From this point forward, the hostname and identity are set to:&lt;/p&gt;

&lt;p&gt;makko@kujira (kujira = クジラ = whale in Japanese, specifically referring to the sperm whale: マッコウクジラ / makko kujira)&lt;/p&gt;

&lt;p&gt;Hostname, prompt, and system references have been updated accordingly.&lt;/p&gt;

&lt;p&gt;This marks the beginning of my server journey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fryrjmalxagndsyr9zrkk.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%2Fryrjmalxagndsyr9zrkk.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;LOG 005&lt;/p&gt;

&lt;p&gt;Power state inconsistencies and crontab/rtcwake issues&lt;/p&gt;

&lt;p&gt;Recently attempted to automate power management on my Debian server: wake at 6:00 AM, shut down at 00:00.&lt;/p&gt;

&lt;p&gt;Steps taken: &lt;/p&gt;

&lt;p&gt;• Created a root-level crontab job to use rtcwake &lt;/p&gt;

&lt;p&gt;• Target: rtcwake -l -m no -t [timestamp] &lt;/p&gt;

&lt;p&gt;• Simultaneously scheduled shutdown via sudo poweroff&lt;/p&gt;

&lt;p&gt;Observed issues: &lt;br&gt;
• rtcwake did not correctly set the wake timer via crontab &lt;/p&gt;

&lt;p&gt;• System stayed powered on through the night &lt;/p&gt;

&lt;p&gt;• Only user-level crontab messages (like greetings) executed as expected&lt;/p&gt;

&lt;p&gt;Additional problem encountered: &lt;/p&gt;

&lt;p&gt;• After full shutdown via poweroff, the server powers on ~10 minutes later with only the LED on — no POST or boot &lt;/p&gt;

&lt;p&gt;• System appears stuck in an undefined power state&lt;/p&gt;

&lt;p&gt;Temporary solutions: &lt;/p&gt;

&lt;p&gt;• Disabled Wake-on-LAN in BIOS &lt;/p&gt;

&lt;p&gt;• Cleaned and adjusted crontab entries for both root and user&lt;/p&gt;

&lt;p&gt;Conclusion: Current automation using crontab and rtcwake is unreliable. Will research and eventually implement custom system daemons for robust control.&lt;/p&gt;

&lt;p&gt;Additional: After some digging, I found the main reason my server wasn’t sleeping/waking on time — a misconfigured root crontab.&lt;/p&gt;

&lt;p&gt;I updated my script and discovered a neat feature:&lt;/p&gt;

&lt;p&gt;date -d "Tomorrow 6:00" +%s&lt;/p&gt;

&lt;p&gt;This returns a timestamp for 6:00 AM tomorrow. The -d flag surprisingly accepts natural language inputs like "next Friday", which seems to be a GNU/Linux-specific thing — quite handy.&lt;/p&gt;

&lt;p&gt;I manually tested this logic: &lt;/p&gt;

&lt;p&gt;• Scheduled wake-up for 7 minutes later &lt;/p&gt;

&lt;p&gt;• Set sleep in 20 seconds &lt;/p&gt;

&lt;p&gt;• Verified wakealarm log — it worked&lt;/p&gt;

&lt;p&gt;Then I rewrote the root crontab like this:&lt;/p&gt;

&lt;p&gt;58 23 * * * /home/makko/dir/dir/sleep.script.sh &amp;gt;&amp;gt; /home/makko/sleep_log.md 2&amp;gt;&amp;amp;1&lt;/p&gt;

&lt;p&gt;Now both stdout and stderr are logged, so I can debug directly if anything fails.&lt;/p&gt;

&lt;p&gt;We’ll see if this new setup behaves better.&lt;/p&gt;




&lt;p&gt;LOG 006&lt;/p&gt;

&lt;p&gt;Issue: crontab under root failed to execute scheduled sleep/wake script due to missing PATH environment.&lt;/p&gt;

&lt;p&gt;Symptoms: &lt;br&gt;
• Script worked manually (sudo ./sleep.sh) &lt;/p&gt;

&lt;p&gt;• Cron triggered suspend, but failed to locate rtcwake: rtcwake: command not foud&lt;/p&gt;

&lt;p&gt;Diagnosis: Cron runs in a limited environment and does not inherit user-defined environment variables (like those in .bashrc or .profile). As a result, its $PATH is incomplete.&lt;/p&gt;

&lt;p&gt;Steps Taken: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Verified $PATH via echo $PATH in normal terminal and compared it to cron. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identified that rtcwake is located in /usr/sbin which was missing from cron’s path. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added full path export directly in the script: Result: &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;• Script now sets wake timer and system enters suspend mode correctly. &lt;/p&gt;

&lt;p&gt;• System wakes up at the intended time (e.g. 06:30) using rtcwake.&lt;/p&gt;

&lt;p&gt;Conclusion: Always ensure critical binaries are included in $PATH when executing scripts via crontab, especially under root. Cron’s limited environment requires explicit context setup.&lt;/p&gt;

&lt;p&gt;Plan: – Add a 20-minute warning before shutdown. (The laptop shut down last night while I was working — forgot about the crontab.)&lt;/p&gt;




&lt;p&gt;LOG 007&lt;/p&gt;

&lt;p&gt;Lid closed, system alive — configuring logind.conf&lt;/p&gt;

&lt;p&gt;Task: Prevent the server (a repurposed laptop) from suspending when the lid is closed.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;p&gt;Switched to root.&lt;/p&gt;

&lt;p&gt;Edited the config file: /etc/systemd/logind.conf&lt;/p&gt;

&lt;p&gt;Found this line (commented by default): #HandleLidSwitch=suspend&lt;/p&gt;

&lt;p&gt;Uncommented it and changed value to: HandleLidSwitch=ignore&lt;/p&gt;

&lt;p&gt;Rebooted system.&lt;/p&gt;

&lt;p&gt;Result: Now, the machine stays fully functional with the lid closed. SSH sessions stay alive, workflows uninterrupted.&lt;/p&gt;

&lt;p&gt;Also explored /sys/class/power_supply/BAT1/ for battery monitoring: • capacity — battery percentage • status — current charging state&lt;/p&gt;




&lt;p&gt;LOG 008&lt;/p&gt;

&lt;p&gt;Startup monitor script via .bashrc&lt;/p&gt;

&lt;p&gt;Implemented a custom Bash script that runs every time the terminal is launched (via ~/.bashrc). While it’s not a daemon, it acts as a simple visual status dashboard.&lt;/p&gt;

&lt;p&gt;Functionality includes: &lt;/p&gt;

&lt;p&gt;• Welcome message on shell launch &lt;/p&gt;

&lt;p&gt;• Battery level readout &lt;/p&gt;

&lt;p&gt;• Charging status (Charging, Discharging, or Full) &lt;/p&gt;

&lt;p&gt;• CPU model info &lt;/p&gt;

&lt;p&gt;• Core temperature and voltage reporting &lt;/p&gt;

&lt;p&gt;• Basic network diagnostics (ping to laptop and router with ping -c 5)&lt;/p&gt;

&lt;p&gt;Notes: • The ping -c flag allows for fixed-length diagnostics — clearer output for terminal-based checks • Output design (colors, formatting) took significantly longer than the actual logic&lt;/p&gt;

&lt;p&gt;Goal: Create a personal visual health-check system for the server - lightweight, non-intrusive, and tailored for manual inspection. Future plans: turn this into a daemon for background monitoring and automated alerts.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>linux</category>
      <category>debian</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🧭 Start Here: Linux Server Logbook</title>
      <dc:creator>Thomas Jager</dc:creator>
      <pubDate>Fri, 15 Aug 2025 14:46:44 +0000</pubDate>
      <link>https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94</link>
      <guid>https://dev.to/aka_artem_dd17be93c/start-here-linux-server-logbook-4i94</guid>
      <description>&lt;p&gt;Welcome to my personal devlog series. &lt;/p&gt;

&lt;p&gt;A logbook of how I learn Linux by building and breaking things on my own server.&lt;br&gt;
This is hands-on learning, and i love it.&lt;/p&gt;




&lt;p&gt;💻 My Hardware&lt;/p&gt;

&lt;p&gt;• CPU: Intel Core i5-7200U @ 2.5GHz (Turbo 3.11GHz)&lt;/p&gt;

&lt;p&gt;• GPU: NVIDIA MX150, 2GB GDDR5&lt;/p&gt;

&lt;p&gt;• RAM: Upgraded to 20GB DDR4&lt;/p&gt;

&lt;p&gt;• Storage: 126GB SSD Sandisk&lt;/p&gt;

&lt;p&gt;• Wi-Fi: 802.11ac&lt;/p&gt;

&lt;p&gt;• Ports: Thunderbolt + standard I/O&lt;/p&gt;

&lt;p&gt;• Current OC: Debian GNU/Linux 13 (trixie) / Space: fn 1,5Gb. &lt;/p&gt;

&lt;p&gt;•Server name: "マッコウクジラ — makkō kujira - sperm whale"&lt;/p&gt;




&lt;p&gt;📂 What is this logbook?&lt;/p&gt;

&lt;p&gt;This is a collection of logs documenting:&lt;/p&gt;

&lt;p&gt;• install and reinstall systems manually&lt;/p&gt;

&lt;p&gt;• fight with wpa_supplicant and systemd masking&lt;/p&gt;

&lt;p&gt;• configure static IPs and chase down DHCP demons&lt;/p&gt;

&lt;p&gt;• run a fully terminal-based setup with no GUI&lt;/p&gt;

&lt;p&gt;• plan to build a proper homelab and NAS — and more later&lt;/p&gt;




&lt;p&gt;📌 How the logs are structured&lt;/p&gt;

&lt;p&gt;Each post follows this format:&lt;/p&gt;

&lt;p&gt;📅 Date: YYYY-MM-DD&lt;br&gt;&lt;br&gt;
🔧 Tools:   &lt;/p&gt;

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

&lt;p&gt;(Short intro)&lt;/p&gt;

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

&lt;p&gt;(What went wrong)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;(How I solved it)&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;(Quick list)&lt;/p&gt;

&lt;p&gt;✍ Personal Note:&lt;br&gt;
(Optional reflection or joke)&lt;/p&gt;




&lt;p&gt;🔗 Index of logs&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log001-008-from-ubuntu-to-debian-journey-3m4m"&gt;Log001 - 008&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log009-debian-13-4b46"&gt;Log009 - Debian 13&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log010-wpasupplicant-trouble-16l9"&gt;Log010 - wpa_supplicant vs Network Manager&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log011-ufw-nginx-and-a-dream-4j5l"&gt;Log011 - UFW, nginx and a dream&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log012-docker-apache-ec2-etc-31ea"&gt;Log012 - Docker, Apache, EC2 etc.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log013-aws-debian-13-fail2ban-logrotate-docker-almalinux-apache-aws-s3-cloudfront-aws-34j"&gt;Log013 - AWS, Debian 13, Fail2ban, Logrotate, Docker, AlmaLinux, Apache, AWS S3, CloudFront, AWS CLI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log014cloudflarezohomailec2md-2pn3"&gt;Log014_CloudFlare_Zoho.mail_ec2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/aka_artem_dd17be93c/log015sakilamysqlpymongo-9na"&gt;Log015_sakila_mysql_pymongo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;9.&lt;/p&gt;

&lt;p&gt;10.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtfj925738mprnbsmciw.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%2Fmtfj925738mprnbsmciw.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🧷 How to keep this post “pinned”&lt;/p&gt;

&lt;p&gt;Since dev.to doesn’t support pinned posts:&lt;/p&gt;

&lt;p&gt;• This post includes the #start-here tag&lt;/p&gt;

&lt;p&gt;• I’ll link back to it in each future log&lt;/p&gt;

&lt;p&gt;• It’s also added to my profile bio&lt;/p&gt;

&lt;p&gt;• You can bookmark it or follow the series tag&lt;/p&gt;

</description>
      <category>linux</category>
      <category>homelab</category>
      <category>beginners</category>
      <category>debian</category>
    </item>
  </channel>
</rss>
