Skip to content

Instantly share code, notes, and snippets.

@sevmorris
Last active July 17, 2024 04:45
Show Gist options
  • Save sevmorris/a1ec6644c74db6eb7a3895d53b7ae12b to your computer and use it in GitHub Desktop.
Save sevmorris/a1ec6644c74db6eb7a3895d53b7ae12b to your computer and use it in GitHub Desktop.

Headless Raspberry Pi Optimization Guide

This is a guide detailing how to optimize a headless Raspberry Pi setup by disabling unnecessary services, removing unused software, and managing system resources efficiently.

If you're setting up a headless RasPi from scratch I would encourage you to check out my Headless Raspberry Pi Initial Setup Guide before continuing.


Disclaimer

This guide demonstrates how to remove certain services from a headless Raspberry Pi setup to optimize performance and resource usage. This is an advanced procedure and should only be attempted by experienced users who understand the risks involved.

I have personally chosen to remove these files and services from my headless Raspberry Pi, as I have (sort of, but not always fully) assessed the potential impact and am comfortable with the associated risks. In fact, I'm quite comfortable with breaking things, sometimes so completely that I have to start from scratch.

By following this guide, you acknowledge that you are solely responsible for any modifications you make to your Raspberry Pi and accept the potential risks involved. In other words, I am not responsible for any issues or data loss that may occur as a result of following these instructions.

Why I'm Doing This

While pre-optimized headless Raspberry Pi distributions like DietPi offer a convenient starting point, I've chosen manual optimization as a personal learning journey. Delving into system services, package management, and resource allocation sharpens my troubleshooting skills and allows me to tailor the system to my evolving needs. This hands-on approach fosters a sense of accomplishment and ownership as I craft a personalized Raspberry Pi experience that perfectly aligns with my interests and project goals.

Best practices

Stopping Services

It's generally a good practice to stop a service before disabling and removing it. Here's why:

  1. Clean State: Stopping the service ensures that it's not actively running any processes or using resources. This allows for a cleaner removal of the service and its associated files.

  2. Dependency Handling: Some services might depend on other services. Stopping the service first gives systemd init system a chance to gracefully handle these dependencies, avoiding potential conflicts or errors during the removal process.

  3. Preventing Unexpected Behavior: If a service is running during removal, it could potentially interfere with the uninstallation process, leading to unexpected behavior or errors.


Disabling Services

Disabling a service before removing it is considered a best practice for several reasons:

  1. Clean Shutdown: When you disable a service, you're telling the system to stop it from running. This ensures that the service is not actively using any resources or interacting with other parts of the system when you try to uninstall it.

    Removing a service while it's running can cause unexpected issues, such as data corruption or conflicts with other processes.

  2. Dependency Management: Many services have dependencies on other services or processes. Disabling a service first allows the systemd init system to gracefully handle these dependencies and stop any dependent services, preventing errors or instability during the removal process.

  3. Avoiding Conflicts: If a service is running during the removal process, it might hold locks on files or resources that the uninstallation process needs to access. This can cause conflicts and lead to incomplete or failed uninstallation.

  4. System Stability: Removing a service without disabling it first can sometimes leave behind configuration files or residual processes, which can lead to unexpected behavior or system instability. Disabling the service before removal ensures a cleaner and more reliable uninstallation.


Masking Services

The mask command is used to prevent a service from being started under any circumstances, even manually. This is a stronger form of disabling a service than the standard disable command. In some cases (noted below) we will mask a service instead of removing it.

What does mask do?

When you mask a service, systemd creates a symlink from the service's unit file to /dev/null. This effectively makes the service invisible to systemd, as if it doesn't exist at all. Even if you try to start the service manually using systemctl start, it won't work because systemd can't find the unit file.

Why use mask?

  • Permanent Disable: Masking a service is a more permanent way to disable it than simply using disable. The disabled state can be easily reverted, but a masked service requires explicit unmasking to be started again.
  • Prevent Accidental Starts: Masking prevents accidental or unintended starts of the service, either by the user or by other scripts or programs.
  • Security: In some cases, masking a service can be used as a security measure to prevent a vulnerable or unwanted service from being exploited.

How to mask a service:

sudo systemctl mask <service_name.service>

How to unmask a service:

sudo systemctl unmask <service_name.service>

Removing Services

purge

The command sudo apt purge <package-name> is used to remove a specified software package and its associated configuration files. This action is typically employed when a user intends to completely uninstall a software application, ensuring no residual settings or data remain on the system. Additionally, it is utilized to reclaim disk space after disabling a service that is no longer required.

autoremove

The command sudo apt autoremove removes packages that were automatically installed as dependencies for other packages and are no longer needed.

After purging a package, using sudo apt autoremove cleans up leftover dependencies, keeping your system lean and efficient. This practice is especially beneficial for devices with limited storage, like Raspberry Pi. Periodically running this command not only frees up valuable disk space, but also helps maintain a well-organized system, reducing the risk of conflicts between old and new configurations. By removing unused software, you also minimize potential security vulnerabilities, making your Raspberry Pi more secure.

Combining purge & autoremove

You can safely combine purge & autoremove commands in the form of sudo apt purge --auto-remove <package-name>. This combined approach improves efficiency and reduces errors compared to running separate commands.

However, in complex system environments or when requiring granular control over the removal process, consider running purge and autoremove separately for meticulous examination of each command's output. These exceptions will be noted in this guide.

Reloading Service Configs

While it's not strictly mandatory to run sudo systemctl daemon-reload after removing services, it is considered a best practice and highly recommended. Here's why:

  1. Cache Refresh: Systemd maintains a cache of unit files (service configurations). When you remove a service, the associated unit file is deleted, but systemd might still hold the old information in its cache. Running daemon-reload forces systemd to re-read the configuration files and update its internal cache. This ensures that systemd is aware of the changes and won't try to manage a service that's no longer installed.

  2. Dependency Resolution: Services often have dependencies on each other. Removing a service could potentially break those dependencies for other services. Reloading the daemon helps systemd recalculate the dependencies and ensures smooth operation of the remaining services.

  3. Error Prevention: If you don't reload the daemon, you might encounter errors when trying to interact with systemd or other tools that rely on its information. These errors could be misleading or prevent you from performing further actions related to service management.

It's a good habit to run sudo systemctl daemon-reload after making any significant changes to your system's services, especially after removing or installing new packages. It's a quick and simple command that can save you from potential headaches down the road.

Remove man pages

To free up disk space on your headless Raspberry Pi, you might want to eliminate the manual pages (also known as "man pages").

The man-db package is responsible for managing and providing access to the manual pages. Run the following command to uninstall the man-db package:

sudo apt purge --auto-remove man-db

To ensure that man-db and its associated manual pages have been successfully removed, try running the man command. You should receive an error message indicating that the command was not found. This confirms that the manual pages are no longer accessible on your system.

Remove Documentation Files

This set of commands helps free up disk space on your Raspberry Pi by removing documentation files that are not essential for headless operation:

  1. sudo find /usr/share/doc -depth -type f ! -name copyright -exec rm {} +

    • This command locates and deletes all regular files (not directories) within the /usr/share/doc directory and its subdirectories.
    • It excludes files named copyright, as those are often required for legal reasons.
    • The -depth flag ensures that empty subdirectories are handled correctly in the next step.
  2. sudo find /usr/share/doc -empty -delete

    • This command removes any empty directories that were left behind after deleting the documentation files.
  3. sudo rm -rf /usr/share/groff/* /usr/share/info/* /usr/share/lintian/* /usr/share/linda/* /var/cache/man/*

    • This command forcefully removes the contents of several directories that commonly contain documentation:
      • /usr/share/groff/: Files related to the GNU troff typesetting system.
      • /usr/share/info/: Info pages (a type of documentation format).
      • /usr/share/lintian/: Files related to the lintian package checker.
      • /usr/share/linda/: Files related to the linda parallel programming system.
      • /var/cache/man/: Cached manual pages (man pages are typically not needed in a headless setup).

Why Remove Documentation?

On a headless Raspberry Pi, you typically won't need to access documentation files directly. Removing them can free up a significant amount of disk space, which can be beneficial for devices with limited storage.

Prevent dpkg from installing documentation

  1. Create the Configuration Directory (If It Doesn't Exist):

    sudo mkdir -p /etc/dpkg/dpkg.cfg.d/
    

    This command creates the directory where you'll place the configuration file.

  2. Create the Configuration File:

    sudo nano /etc/dpkg/dpkg.cfg.d/01_nodoc
    

    The filename starting with "01" ensures that it's processed early.

  3. Add Exclusion Rules:

    Paste the following content into the file:

    path-exclude /usr/share/doc/*
    path-include /usr/share/doc/*/copyright
    path-exclude /usr/share/man/*
    path-exclude /usr/share/groff/*
    path-exclude /usr/share/info/*
    

    These lines instruct dpkg to:

    • Exclude all files within the /usr/share/doc/ directory, which typically contains documentation.
    • Include copyright files located within subdirectories of /usr/share/doc/ (for legal reasons).
    • Exclude man pages from /usr/share/man/.
    • Exclude groff files from /usr/share/groff/.
    • Exclude info pages from /usr/share/info/.
  4. Save and Exit:

    Press Ctrl+X to save the file and exit nano (follow prompts).

Now, whenever you install a package using apt, dpkg, or other package managers that rely on dpkg, the documentation files matching the specified paths will be automatically excluded from installation.

Key Points:

  • Customization: You can add or modify the path-exclude lines to customize which documentation directories to exclude.
  • Package-Specific Exclusions: For finer control, create separate files for specific packages (e.g., 01_python3-nodoc) within the dpkg.cfg.d directory, listing the paths you want to exclude for each package.
  • Copyright: It's recommended to keep copyright files (/usr/share/doc/*/copyright) for legal compliance.

By following these steps, you can effectively instruct dpkg to permanently avoid installing documentation files, saving valuable disk space on your Raspberry Pi.

Optimize Storage with localepurge

Locales are language and regional settings that can consume significant disk space, especially if you have multiple unused locales installed. localepurge simplifies the process of removing unnecessary locales, freeing up valuable storage and potentially improving system performance.

Why Remove Unused Locales?

On a headless Raspberry Pi, you typically won't need to switch between different language settings. Removing unused locales can reclaim a substantial amount of disk space, especially if you're working with a limited-capacity SD card.

  1. Installation:

    sudo apt install localepurge
    

During installation, localepurge will prompt you to select the locales you want to keep. Carefully choose the locales you actually need for your system and applications. If unsure, it's generally safe to select the locale matching your geographic location (e.g., en_US.UTF-8 for United States English).

Once configured, localepurge will run automatically during future package updates, ensuring that only the selected locales remain on your system.

By removing unnecessary locales with localepurge, you can:

  • Free up disk space: Reclaim valuable storage by removing language files you don't need.
  • Improve system performance: Potentially enhance system responsiveness by reducing the number of files the system needs to manage.
  • Streamline maintenance: Automate the process of removing unused locales during updates.

Optimize SSH for Headless Operation

By default, the SSH server (sshd) runs constantly in the background, consuming resources even when not in use. We can optimize this for better security and resource efficiency by enabling "on-demand" starting. Instead of running continuously, SSH will only start when a connection is requested. This approach offers several advantages: it reduces the potential attack surface by keeping the SSH server inactive until needed, conserves valuable system resources on your Raspberry Pi, and has minimal impact on your workflow since SSH starts quickly upon connection.

  1. Disable:

    sudo systemctl disable ssh.service
    
  2. Enable the Socket:

    sudo systemctl enable ssh.socket
    
  3. Reboot:

    sudo reboot
    

Disable Bluetooth

Disabling Bluetooth on a headless Raspberry Pi is often done for the following reasons:

  1. Resource Conservation: Bluetooth, even when not actively used, consumes some processing power and memory. Disabling it frees up these resources, which can be beneficial in resource-constrained environments or when running demanding applications.

  2. Security: While the risk might be low on a headless system, disabling unused communication interfaces like Bluetooth reduces the attack surface and minimizes potential vulnerabilities.

  3. Power Saving: In battery-powered setups, disabling Bluetooth can slightly extend the battery life, as it eliminates the power draw associated with the Bluetooth radio.

  4. Interference Reduction: In certain scenarios, Bluetooth signals might interfere with other wireless devices operating in the same frequency range. Disabling Bluetooth can help mitigate such interference issues.

Since headless Raspberry Pis are typically used for specific tasks that often don't require Bluetooth connectivity, disabling it is a common optimization step to enhance performance, security, and power efficiency.

To disable Bluetooth, follow these steps:

  1. Edit config.txt:

    sudo nano /boot/firmware/config.txt
    
  2. Add the following line under the [all] section:

    # Disable Bluetooth
    dtoverlay=disable-bt
    

    The line dtoverlay=disable-bt in the config.txt file instructs the Raspberry Pi to disable the Bluetooth device tree overlay during boot, effectively disabling the Bluetooth hardware.

  3. Save and Exit:

    Press Ctrl+X to save the file and exit nano (follow prompts).

  4. Reboot:

    sudo reboot
    

Remove Services

alsa-restore.service

The alsa-restore.service is a systemd service that saves and restores the sound card state on your Raspberry Pi. Specifically, it:

  • On boot: Reads the saved volume levels and other settings from a file (/var/lib/alsa/asound.state) and applies them to your sound card, restoring the audio configuration to how it was when the system was last shut down.
  • On shutdown: Saves the current sound card settings to the same file, so they can be restored on the next boot.

In headless Raspberry Pi setups (without audio output), the alsa-restore.service is unnecessary as it's designed to save and restore sound settings between reboots. You can safely disable and remove this service to free up resources.

Run the following to stop, disable, remove & reload systemd:

sudo systemctl stop alsa-restore.service
sudo systemctl disable alsa-restore.service
sudo apt purge --auto-remove alsa-*
sudo systemctl daemon-reload

avahi-daemon.service

avahi-daemon.service is a service that implements mDNS/DNS-SD (Multicast DNS/DNS Service Discovery). In simpler terms, it's a zero-configuration networking system that allows devices to automatically discover each other on a local network without needing to manually configure DNS servers. It's most commonly known for its compatibility with Apple's Bonjour service.

In a headless Raspberry Pi setup (meaning no monitor, keyboard, or mouse), you likely don't need Avahi running. Here's how to completely remove it:

Run the following to stop, disable, remove & reload systemd:

sudo systemctl stop avahi-daemon.service
sudo systemctl disable avahi-daemon.service
sudo apt purge --auto-remove avahi-daemon libnss-mdns
sudo systemctl daemon-reload

console-setup.service

The console-setup.service is a systemd service responsible for configuring the console (text-based interface) during the boot process. Its main tasks include:

  • Setting the Console Font: It applies the default font for the console, ensuring readability and consistency.
  • Configuring the Keyboard Layout: It sets the appropriate keyboard layout (e.g., US, UK, etc.) based on your locale settings.
  • Other Console Settings: It might also handle additional console configurations like color schemes or terminal settings.

If you're running your Raspberry Pi headless, you don't interact with the console directly, so this service isn't essential.

Note: The console-setup package is part of the keyboard-configuration package, which we will remove.

Run the following to stop, disable, remove & reload systemd:

sudo systemctl stop console-setup.service
sudo systemctl disable console-setup.service
sudo apt purge --auto-remove keyboard-configuration
sudo systemctl daemon-reload

nmbd.service

The nmbd.service is a component of the Samba software suite. Samba is an open-source implementation of the SMB/CIFS networking protocol, which allows your Raspberry Pi to share files and printers with Windows machines and other devices on your local network.

What nmbd.service Does:

  • NetBIOS Name Service: nmbd stands for NetBIOS Name Daemon. It provides NetBIOS over TCP/IP (NBT) name service and browsing functions. Essentially, it allows other devices on your network to discover your Raspberry Pi by its NetBIOS name.
  • Name Resolution: It translates NetBIOS names (e.g., RASPBERRYPI) into IP addresses and vice versa, making it easier for devices to connect to each other.
  • Browsing: It allows your Raspberry Pi to browse the network and see other devices that are sharing files and printers using SMB/CIFS.

Why You Might Need It:

  • Windows File Sharing: If you want to share files or folders on your Raspberry Pi with Windows computers, nmbd is essential for those computers to easily find and connect to your Pi.
  • Network Browsing: It enables your Raspberry Pi to appear in the network neighborhood of other devices, making it more accessible.

Why You Might Not Need It:

  • Headless Setup: If you're running your Raspberry Pi headless (without a graphical interface) and don't need to share files with Windows machines, you might not need nmbd.
  • Alternative Protocols: If you use other file-sharing protocols like NFS or FTP, you might not need Samba or its components like nmbd.
  • Resource Optimization: In a resource-constrained environment, disabling nmbd can save a small amount of system resources.

Run the following stop, disable & uninstall the Samba package:

sudo systemctl stop nmbd.service
sudo systemctl disable nmbd.service
sudo apt purge --auto-remove samba

The serial-getty@ttyAMA0.service is a systemd service that creates a login prompt on the Raspberry Pi's ttyAMA0 serial port. This port is often used for communication with external devices, like GPS modules or Arduino boards.

If you're using your RasPi in headless mode and not utilizing the serial port, you can safely disable this service to free up system resources.

Run the following to stop & mask the service:

sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl mask serial-getty@ttyAMA0.service

Masking the service is sufficient for most headless setups as it prevents it from running and consuming resources. Removing the associated agetty package is unnecessary and could disrupt other services that depend on it.

Important Note:

  • On Raspberry Pi 3 and newer models, the primary UART (serial port) is used for Bluetooth by default. If you need to use ttyAMA0 for serial communication instead, you'll need to disable Bluetooth and enable the UART in your Raspberry Pi configuration.


This guide was created with the assistance of Gemini.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment