How to Find Large Files on Ubuntu Linux (and Clean Up Disk Space)

🧹 How to Find Large Files on Ubuntu 18.04 (and Clean Up Disk Space)

If you’ve ever run into the dreaded “No space left on device” error on your Linux system, you’re not alone. Over time, log files, package caches, and forgotten downloads can fill up your disk. In this guide, we’ll walk through several ways to identify large files and directories on your Ubuntu 18.04 system — using both command-line tools and interactive utilities.


📁 Why You Might Need This

  • Your system is running low on disk space.
  • You’re managing a server and want to optimize storage.
  • You want to clean up unused data before creating a backup.
  • You’re just curious what’s eating up all your GBs.

🔍 Method 1: Find Large Files Using

find

Let’s say you want to find files larger than 100 MB:

sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k 5 -hr | head -n 20

What this does:

  • find /

    — search the whole system

  • -type f

    — look for files only

  • -size +100M

    — files larger than 100 megabytes

  • ls -lh

    — show file size in human-readable format

  • sort -k 5 -hr

    — sort files by size, descending

  • head -n 20

    — show only the top 20 results

🔐 Note: You may need

sudo

to access some directories.


📦 Method 2: Show Largest Directories with

du

To find out which folders are taking up the most space, use:

du -h --max-depth=1 | sort -hr

This lists the size of each subdirectory in the current folder. Example output from

/var

:

3.4G    ./log
1.2G    ./cache
5.0G    .

You can also search the whole system:

sudo du -ah / | sort -rh | head -n 30

This command lists the 30 biggest files and folders system-wide.


🖥️ Method 3: Use

ncdu

– The Friendly Disk Usage Viewer

Prefer something more visual and interactive? Try

ncdu

:

Install it:

sudo apt update
sudo apt install ncdu

Run it:

sudo ncdu /

Navigate the disk usage tree using arrow keys. Press

d

to delete files directly from within the tool (be careful!).


🧼 Bonus Tips: Clean Up with Built-in Tools

Clear APT cache:

sudo apt clean

Remove old kernels (Ubuntu auto handles this, but still):

sudo apt autoremove --purge

Check disk space usage at a glance:

df -h

🔚 Wrapping Up

Identifying and removing large files can dramatically improve system performance and free up valuable space. Whether you’re a sysadmin managing a fleet of servers or just cleaning up your dev laptop, these tools will help you stay in control.


💬 What’s your favorite way to clean up disk space on Linux?

Feel free to share your tips in the comments box below this blog post or contribute to the conversation on Reddit, X (Twitter), or your favorite dev community.

🔍 How to Verify Inserted Rows Using a CTE in SQL (WITH expected AS Pattern)

🔍 How to Verify Inserted Rows Using a CTE in SQL (

WITH expected AS

Pattern)

Whether you’re writing seeders, migration scripts, or integration tests — verifying that specific records were inserted into a table is a common and critical task.

Let me show you a clean and portable SQL technique using a Common Table Expression (CTE) to check that a set of expected rows exists in your database — without writing 6 separate

SELECT

queries or messing with application-level checks.


✅ Use Case

Imagine you just ran this

INSERT

into a table called

template

:

INSERT INTO template (service__id, id, os__id, ...)
VALUES
  ('wpsquared', 'cloudlinux8-wp2-v1', 'cloudlinux-8', ...),
  ('wpsquared', 'cloudlinux9-wp2-v1', 'cloudlinux-9', ...),
  ('wpsquared', 'cloudlinux9-wp2-v2', 'cloudlinux-9', ...),
  ('wpsquared', 'cloudlinux9-wp2-v3', 'cloudlinux-9', ...),
  ('plesk',     'ubuntu2204-plesk-v1', 'ubuntu-22.04', ...),
  ('cpanel',    'ubuntu2404-cpanel-v1', 'ubuntu-24.04', ...);

Now you want to confirm that all 6 rows exist.


🧠 The Pattern:

WITH expected AS (...)

Here’s the SQL snippet:

-- Step 1: Define the rows we expect
WITH expected AS (
    SELECT 'wpsquared' AS service__id, 'cloudlinux8-wp2-v1'  AS id UNION ALL
    SELECT 'wpsquared', 'cloudlinux9-wp2-v1'  UNION ALL
    SELECT 'wpsquared', 'cloudlinux9-wp2-v2'  UNION ALL
    SELECT 'wpsquared', 'cloudlinux9-wp2-v3'  UNION ALL
    SELECT 'plesk',     'ubuntu2204-plesk-v1' UNION ALL
    SELECT 'cpanel',    'ubuntu2404-cpanel-v1'
)

-- Step 2: Check which of them are missing
SELECT  e.service__id,
        e.id
FROM    expected e
LEFT JOIN template t
       ON  t.id = e.id
       AND t.service__id = e.service__id
WHERE   t.id IS NULL;

📋 Result

  • If the query returns 0 rows → ✅ You’re good! All expected rows are present.
  • If any rows are returned → ⚠️ These are missing or mismatched by primary key or foreign key.

🔄 Bonus: Quick Boolean Check

Want a compact version that tells you how many rows are missing?

WITH expected AS (
    -- same as above
)
SELECT COUNT(*) AS missing_count
FROM   expected e
LEFT   JOIN template t
       ON t.id = e.id AND t.service__id = e.service__id
WHERE  t.id IS NULL;

🧬 Cross-Database Compatibility

This pattern works on:

  • PostgreSQL
  • MySQL / MariaDB
  • SQLite
  • SQL Server 2005+ (with some minor syntax adaptation)

The key is that all of these databases support CTEs (Common Table Expressions) and

LEFT JOIN

logic.


🧑‍💻 When Should You Use This?

  • To test database seeders
  • To verify data migration scripts
  • During CI pipelines or test automation
  • For quick manual checks in staging or dev

📎 Final Tip

You can also extend this pattern to check not just existence, but field-level equality, version numbers, or even timestamps — just join on more columns and compare.


If you liked this trick, follow me or join my community [insert your Reddit, blog, or channel link here] where I share more real-world PHP + SQL tips like this one!

How to create a simple IP address tracker with geolocation in Symfony 6+

Do you want to know who visits your website, where they’re from, and when?
In this post, I’ll show you how to build a small Symfony project that:

  • Detects the visitor’s IP address
  • Retrieves geolocation data based on the IP
  • Stores this data in a database
  • Displays the IP, country, and city on the homepage

⚙️ Project Setup

Creating a new Symfony project:

composer create-project symfony/skeleton:"6.4.*" ip-tracker  
cd ip-tracker

Installing required dependencies:

composer require symfony/twig-bundle  
composer require symfony/http-client  
composer require symfony/orm-pack doctrine/doctrine-bundle  
composer require nesbot/carbon  
composer require symfony/maker-bundle --dev

🧱 Creating the Controller

File:

src/Controller/ClientIpController.php

<?php

namespace App\Controller;

use App\Entity\VisitorLog;
use App\Service\IpGeolocationService;
use Carbon\Carbon;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class ClientIpController extends AbstractController
{
    #[Route('/', name: 'app_home')]
    public function index(Request $request, IpGeolocationService $ipService, EntityManagerInterface $em): Response
    {
        $ip = $request->getClientIp();
        $geo = $ipService->getGeolocation($ip);

        $log = new VisitorLog();
        $log->setIp($ip);
        $log->setCountry($geo['country'] ?? null);
        $log->setCity($geo['city'] ?? null);
        $log->setCreatedAt(Carbon::now());

        $em->persist($log);
        $em->flush();

        return $this->render('client_ip/index.html.twig', [
            'ip' => $ip,
            'geo' => $geo,
        ]);
    }
}

🌐 Geolocation Service

File:

src/Service/IpGeolocationService.php

<?php

namespace App\Service;

use Symfony\Contracts\HttpClient\HttpClientInterface;

class IpGeolocationService
{
    public function __construct(private HttpClientInterface $client) {}

    public function getGeolocation(string $ip): array
    {
        $response = $this->client->request('GET', "https://ipapi.co/{$ip}/json/");
        return $response->toArray();
    }
}

🗃 Creating an Entity for Logging

Command:

php bin/console make:entity VisitorLog

Fields:

  • ip

    : string

  • country

    : string (nullable)

  • city

    : string (nullable)

  • createdAt

    : datetime_immutable

Migrations:

php bin/console make:migration  
php bin/console doctrine:migrations:migrate

🖥 Template for Displaying Information to Users

File:

templates/client_ip/index.html.twig

{% extends ‘base.html.twig’ %}

{% block title %}Your IP Address is: {{ ip_address }}{% endblock %}

{% block body %}
<div class="ip-address-wrapper"><h1>Your IP Address is: {{ ip_address }}</h1></div>
{% if geo %}
<ul class="ip-info">
<li>Country: {{ geo.country }}</li>
<li>City: {{ geo.city }}</li>
</ul>
{% endif %}
{% endblock %}


📦 Project Dependencies

According to the list in

composer.json

, this project uses:

  • Symfony 6.4
  • Doctrine ORM
  • Twig
  • Carbon
  • HttpClient
  • MakerBundle (dev)

📝 Conclusion

Together we’ve built a full-featured IP logger on Symfony:

✅ Detects IP
✅ Retrieves geolocation
✅ Stores data in the database
✅ Displays it on the page

This functionality can serve as the foundation for a more complete analytics system, access control, or content personalization for your users.

How to Open Unverified Apps on macOS: MarkText Example

🚀 How to Open Unverified Apps on macOS: MarkText Example

If you’ve ever tried launching an app like MarkText on macOS and saw the warning:

“The application can’t be opened because the developer cannot be verified”

— don’t worry. You’re not alone, and yes, there’s a safe way around it.

In this article, I’ll show you how to launch unverified but trusted applications like MarkText, step-by-step.


🔒 Why Does macOS Block Some Apps?

macOS has a security feature called Gatekeeper that only allows apps from:

  • The Mac App Store
  • Verified developers registered with Apple

This is great for security but can block open-source tools and smaller projects — even if they’re totally safe.


✅ Option 1: Allow Once via System Settings

Here’s how to bypass the block and launch an app manually:

  1. Try to launch the app — you’ll get a warning popup.

  2. Open System SettingsPrivacy & Security

  3. Scroll down and find the section saying:

    “MarkText was blocked from use because it is not from an identified developer.”

  4. Click Allow Anyway

  5. Go back and right-click the app icon, then select Open

  6. This time, you’ll get a new popup with an Open button. Click it.

That’s it — your app will now launch!


🧑‍💻 Option 2: Use Terminal to Bypass Gatekeeper (Power Users)

If you’re comfortable with Terminal, here’s a quick command to remove the "quarantine" flag that macOS adds when downloading apps from the internet:

sudo xattr -rd com.apple.quarantine /Applications/MarkText.app

🧠 Tip: If your app is located somewhere else (like Downloads), adjust the path accordingly.

This command tells macOS: “Hey, I trust this app — stop treating it like malware.”


⚠️ A Word of Caution

Only bypass Gatekeeper for software from trusted sources like GitHub or official project websites. If you’re not 100% sure an app is safe, don’t ignore the warning — it’s there for your protection.


💡 Conclusion

You now know how to safely launch unverified apps like MarkText on your Mac. Whether you prefer the GUI route or the terminal method, you’re back in control.

Let your creativity flow — Markdown away! 😉

What is Docker and Why Developers Should Care

Docker is a tool that allows you to run your projects inside special isolated environments called containers.
Imagine packing your app together with all its dependencies — PHP version, MySQL, Redis, configs — and giving it to another developer or running it on a server without the classic “but it worked on my machine!”.

A container is like a mini-computer inside your system: it starts in seconds, can be copied or destroyed easily, and doesn’t eat up gigabytes of RAM like traditional virtual machines.


Why web developers love Docker:

  • Consistent environments. The same code runs identically on your local, staging, and production servers.
  • Fast onboarding. A new team member? One command and they’re ready to code.
  • Service isolation. PHP, MySQL, Redis, Nginx — each in its own container. Easily swappable and scalable.
  • Effortless deployment. A container is a portable unit ready to be deployed anywhere.
  • CI/CD integration. Works smoothly with GitLab CI, GitHub Actions, Jenkins, and more.

A few key terms to know:

  • Docker Engine – the core software that manages containers.
  • Image – a template used to create containers (e.g., php:8.2-fpm).
  • Container – a running instance of an image.
  • Dockerfile – a file that defines how to build your own image.
  • – Docker Compose – a file that defines and runs multi-container applications (like php, mysql, nginx, etc.).

In the next post, I’ll show how to install Docker on Ubuntu and other operating systems.
But for now, ask yourself: “How much time do I waste configuring dev environments?”
Docker might save you days.


If you found this post helpful — save it, share it, or follow the series. More practical stuff coming soon!

Service Classes in Laravel: Clean Architecture and Scalability

✍️ Introduction

In Laravel, it’s convenient to put business logic into controllers or models. But what should you do when the logic starts to grow? The right solution is to move it into dedicated service classes. This approach follows the Single Responsibility Principle (SRP) and helps make your code scalable and easy to test.


🧱 Structure of a Service Class

Let’s take a look at a basic example of a service class responsible for creating an order:

app/
├── Services/
│   └── OrderService.php
namespace App\Services;

use App\Models\Order;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class OrderService
{
    public function create(array $data, User $user): Order
    {
        return DB::transaction(function () use ($data, $user) {
            $order = new Order();
            $order-&gt;user_id = $user-&gt;id;
            $order-&gt;total = $data['total'];
            $order-&gt;status = 'new';
            $order-&gt;save();

            // Here you could dispatch events, send emails, etc.

            return $order;
        });
    }
}

🚀 Using It in a Controller

namespace App\Http\Controllers;

use App\Http\Requests\OrderRequest;
use App\Services\OrderService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;

class OrderController extends Controller
{
    public function __construct(
        protected OrderService $orderService
    ) {}

    public function store(OrderRequest $request): JsonResponse
    {
        $order = $this-&gt;orderService-&gt;create($request-&gt;validated(), Auth::user());

        return response()-&gt;json([
            'message' =&gt; 'Order created successfully.',
            'order' =&gt; $order,
        ]);
    }
}

Why This Approach Rocks

  • Cleaner architecture: Controllers become slim and act as entry points, not logic holders.
  • Easy testing: Services can be tested in isolation with mocked dependencies.
  • Flexibility: Services are easier to extend or modify without touching the controller.
  • Reusability: You can call the same service from REST APIs, Artisan commands, or queued jobs.

🧪 How to Unit Test the Service

use App\Models\User;
use App\Services\OrderService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class OrderServiceTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_creates_an_order()
    {
        $user = User::factory()-&gt;create();
        $data = ['total' =&gt; 1000];

        $service = new OrderService();
        $order = $service-&gt;create($data, $user);

        $this-&gt;assertDatabaseHas('orders', [
            'user_id' =&gt; $user-&gt;id,
            'total' =&gt; 1000,
        ]);
    }
}

🔚 Conclusion

Service classes in Laravel aren’t overengineering — they’re a smart and maintainable way to structure your business logic. By adopting this pattern, your Laravel applications become cleaner, more modular, and ready for future growth.

🧭 What is Symfony? And How Is It Different from Laravel?

🧭 Symfony is a powerful open-source PHP framework focused on stability, flexibility, and reusable components. It’s widely used to build complex, scalable web applications, enterprise systems, or RESTful APIs. At its core, Symfony is a component-based architecture — and many of its components are actually used by other frameworks, including… Laravel.

Yes, you read that right: Laravel is built on top of Symfony components like HttpFoundation, Routing, Console, EventDispatcher, and more. But despite that, there are several major differences between the two.


🔍 Key Differences Between Symfony and Laravel

1. Architecture Philosophy

  • Symfony follows a flexible and modular approach — you choose exactly which components you want to use.
  • Laravel comes with most features "batteries-included" — everything is ready to go out of the box.

2. Configuration Style

  • Symfony encourages configuration using YAML, XML, or PHP files.
  • Laravel primarily uses PHP config files located in the config/ directory and a simple .env file for environment variables.

3. Project Structure

  • Symfony enforces a stricter project structure, with a strong focus on PSR standards and SOLID principles.
  • Laravel has a simpler, more beginner-friendly structure, though it sacrifices some architectural flexibility.

4. Templating

  • Symfony uses Twig — a secure, fast, and lightweight templating engine.
  • Laravel uses Blade, which is tightly integrated with Laravel’s core and favored by many PHP developers.

5. Strengths and Use Cases

  • Symfony is ideal for large-scale, enterprise-grade applications that demand long-term support (with LTS releases).
  • Laravel is great for rapid development of MVPs, startups, or projects with a quick release cycle.

🎯 Conclusion

Symfony is not a direct replacement for Laravel — it’s simply a different tool for different needs. If you want full control over architecture, advanced service container management, and long-term support — Symfony is your friend. Laravel is all about developer happiness and speed. Symfony is about stability and scale.

In the next post, we’ll dive into installing Symfony and creating your first project. Stay tuned! 😉

Laravel Facades Uncovered: Convenient, but Always Safe?

Facades are a common and convenient practice in Laravel development.
No need to import services manually — just call Cache::get() and go.
But do you really know what’s happening behind the scenes?

In this post, we’ll break it down:

1. How Facades Work Under the Hood

A facade is just a static wrapper around a service in the Laravel Service Container.

Cache::get('key');

is essentially the same as:

app('cache')->get('key');
// or via dependency injection:
$cache->get('key');

So, facades aren’t really static — they resolve real objects from the container dynamically.


2. What’s the Catch?

Facades are convenient, but:

  • Harder to test — mocking with Cache::shouldReceive() or Mail::fake() can be unintuitive;
  • Hidden dependencies — classes don’t explicitly declare what they rely on;
  • Weak IoC principles — swapping implementations becomes more difficult.

3. When Should You Use Dependency Injection Instead?

Prefer DI when you:

  • Want testable, flexible code;
  • Work with multiple implementations of a contract;
  • Need to clearly express a class’s dependencies.
use Illuminate\Contracts\Cache\Repository as Cache;

class UserService 
{
    public function __construct(private Cache $cache) {}

    public function getUser(int $id)
    {
        return $this->cache->remember("user:$id", 60, fn() => User::find($id));
    }
}

4. Refactoring from Facade to Dependency Injection

Before:

class UserService 
{
    public function getUser(int $id)
    {
        return Cache::get("user:$id");
    }
}

After:

use Illuminate\Contracts\Cache\Repository as Cache;

class UserService 
{
    public function __construct(private Cache $cache) {}

    public function getUser(int $id)
    {
        return $this->cache->get("user:$id");
    }
}

TL;DR

Facades are fast and easy to use.
But for scalable, testable, and maintainable architecture — consider dependency injection instead.

Do you use facades in your Laravel projects? Share your thoughts in the comments!

🎧 How to Convert and Combine Multiple iPhone .m4a Audio Files into One .mp3 on Linux using ffmpeg

Have you ever recorded several audio files on your iPhone, only to realize you need them in .mp3 format for easier sharing, editing, or publishing? Here’s a simple and effective way to convert and merge multiple .m4a files into a single .mp3 file using ffmpeg on a Linux system.

🛠️ Step 1: Convert .m4a Files to .mp3
Assume you have three .m4a files saved from your iPhone:

ffmpeg -i 'file-1.m4a' -codec:a libmp3lame -qscale:a 2 2025-05-08_file-1.mp3
ffmpeg -i 'file-2.m4a' -codec:a libmp3lame -qscale:a 2 2025-05-08_file-2.mp3
ffmpeg -i 'file-3.m4a' -codec:a libmp3lame -qscale:a 2 2025-05-08_file-3.mp3

📌 Tip: The -qscale:a 2 flag sets high audio quality. Lower numbers mean better quality (and larger files).

📄 Step 2: Create a Playlist File for Concatenation
You’ll need to prepare a text file that lists the MP3 files in the correct order for merging:

cat mp3_list.txt
file '2025-05-08_file-1.mp3'
file '2025-05-08_file-2.mp3'
file '2025-05-08_file-3.mp3'

🔄 Step 3: Merge the MP3 Files into One
Use ffmpeg with the concat demuxer to join all MP3s into a single file:

ffmpeg -f concat -safe 0 -i mp3_list.txt -c copy 2025-05-08__full_output_combined_3_files.mp3

And voilà — you now have a single MP3 file that combines all three recordings!

🔗 See Also
For more on merging MP3 files with ffmpeg, check out this helpful StackOverflow thread.

How to Merge and Extract PDF Pages on Linux Like a Pro

📄 How to Merge and Extract PDF Pages on Linux Like a Pro

Working with PDF files on Linux is easier than you think. Whether you need to merge multiple PDFs into a single file or extract specific pages (even in reverse order!), Linux has powerful and free tools to get the job done.

Here’s your ultimate guide to merging and extracting PDF pages using the command line.


🔧 Tool of Choice: pdftk

✅ Install pdftk on Ubuntu Linux:

sudo apt update
sudo apt install pdftk

📚 Merge Multiple PDF Files into One

If you have several PDFs and want to combine them:

pdftk file1.pdf file2.pdf file3.pdf cat output merged.pdf

This command will create a new file called merged.pdf containing all pages from file1.pdf, file2.pdf, and file3.pdf in that order.


✂️ Extract Specific Pages from a PDF

Example: Extract pages 1 to 5

pdftk input.pdf cat 1-5 output output_pages_1_to_5.pdf

Extract specific non-consecutive pages:

pdftk input.pdf cat 1 3 5 output selected_pages.pdf

🔁 Extract Pages in Reverse Order

Let’s say you want to extract the first five pages from input.pdf but in reverse order—page 5 becomes 1, page 4 becomes 2, etc.

pdftk input.pdf cat 5 4 3 2 1 output reversed_pages_1_to_5.pdf

🐚 BONUS: Bash Script to Reverse Page Ranges

Want to automate reversing a range of pages? Here’s a neat bash snippet:

START=1
END=5
REVERSED=$(seq $END -1 $START | tr '\n' ' ')
pdftk input.pdf cat $REVERSED output reversed_range.pdf

💡 Alternatives

If you want GUI or extra formatting features, check out:

  • PDF Arranger – GUI tool to merge/reorder visually

    sudo apt install pdfarranger
  • qpdf – powerful CLI tool:

    qpdf input.pdf --pages . 5-1 -- reversed.pdf

🏁 Final Thoughts

With tools like pdftk, qpdf, and pdfarranger, working with PDFs on Linux becomes a breeze. Whether you’re splitting, merging, or reordering pages, there’s no need for paid or proprietary software.

Got a favorite PDF tip or tool on Linux? Drop it in the comments and let’s build an even better toolbox together! 🧰🐧