Create a Web Server with NGINX and Secure it Using Certbot

Create a Web Server with NGINX and Secure it Using Certbot

HTTPS is not a luxury anymore. You must have it on your website.

Let’s Encrypt project has made it easier to deploy SSL certificates for free but it needs to be renewed after every few months.

Certbot saves you the trouble as it automates deploying new certificates and renewing the existing ones.

You can comfortably use certbot with Nginx. Wondering how?

In this tutorial, I will walk you through the following:

  • Installing NGINX
  • Adding server block
  • Installing and using certbot

Sure, you can skip any section if it is already configured.

⚠️
To follow this tutorial, you’d have to have a registered domain name.

In this tutorial, I will be using AWS VM. But you can use any of your favorite ones.

Just make sure to have a public IP; otherwise, you won’t be able to use it as a web server (a mistake I made previously).

So let’s start with the installation of NGINX.

1. Installing NGINX on Ubuntu

As the NGINX is available on the default repository of Ubuntu, it can easily be installed with the following command:

sudo apt install nginx

To verify the installation, check the installed version:

nginx -v
Create a Web Server with NGINX and Secure it Using Certbot

Start the NGINX service and make it start at every boot using the following:

sudo systemctl start nginx && sudo systemctl enable nginx

If you are using the UFW firewall (which you must), allow the NGINX to pass through it:

sudo ufw allow 'nginx full'

2. Setup NGINX Server Block

To set up, up the NGINX server block, use the following command and replace the sudoersagar.de with your own domain:

sudo mkdir -p /var/www/sudoersagar.de/html

Next, update the owner of the directory to the current user using the chown command:

sudo chown -R $USER:$USER /var/www/sudoersagar.de/html

And change the permissions of the directory using the chmod command:

sudo chmod -R 755 /var/www/sudoersagar.de

Now, let’s create a sample HTML index page:

nano /var/www/sudoersagar.de/html/index.html

My index page contains the following and you can use the same too:

<html>
    <head>
        <title>Greetings from Sagar Sharma</title>
    </head>
    <body>
        <h1>Success!  The sudoersagar server block is working!</h1>
    </body>
</html>

Save changes and exit from the nano text editor.

Next, you will have to make a directory named sites-enabled:

sudo mkdir /etc/nginx/sites-enabled 

Now, let’s create a simple NGINX server block:

sudo nano /etc/nginx/sites-available/sudoersagar.de
server {
        listen 80;

        root /var/www/sudoersagar.de/html;
        index index.html;

        server_name sudoersagar.de www.sudoersagar.de;

        location / {
                try_files $uri $uri/ =404;
        }
}

And in case, you have no idea what is being used on the server block, here’s a brief explanation:

Create a Web Server with NGINX and Secure it Using Certbot

Save changes and exit from the text editor.

To enable your site, you will have to create a soft link from sites-available to sites-enabled:

sudo ln -s /etc/nginx/sites-available/sudoersagar.de /etc/nginx/sites-enabled/

Finally, test the configuration file using the following command:

sudo nginx -t
Create a Web Server with NGINX and Secure it Using Certbot

If everything is done correctly, you will have the same output as shown above.

Now, reload the NGINX configuration:

sudo nginx -s reload

3. Create DNS A Record

By the DNS A record, you can map the domain with the NGINX public IP address.

The process is quite straightforward for most providers. Here, I’m using google domains.

Create a Web Server with NGINX and Secure it Using Certbot

Choose,

  • A as a type
  • 300 for TTL (Time To Live)
  • Add public IP address in data field
  • Do the same for www hostname

Save the record.

It takes time to reflect on the changes (2 mins in my case).

To check, you can use the dig command with the domain name:

dig sudoersagar.de
Create a Web Server with NGINX and Secure it Using Certbot

And if it is up and running, it will show the IP address you used with the domain.

4. Setting up certbot

To set up certbot, I will be using snaps (a package manager developed by Canonical).

And the first step is to remove any existing certbot package on the Ubuntu system:

sudo apt remove certbot 

But if you are using anything apart from Ubuntu, you will have to configure snaps manually.

And for that purpose, we have a dedicated tutorial:

How to Install and Use Snap in Various Linux Distributions
Snaps are Canonical’s way of providing a cross-distribution package management system. In this article, we will see how to install and use snaps in various Linux distributions.
Create a Web Server with NGINX and Secure it Using Certbot

Once you are done with the setup, use the following command to install certbot:

sudo snap install --classic certbot

And finally, create a symlink to the certbot directory:

sudo ln -s /snap/bin/certbot /usr/bin/certbot

To verify the installation, check the installed version of certbot:

certbot --version
Create a Web Server with NGINX and Secure it Using Certbot

5. Install certificates

⚠️
You can request 50 certificates per week (maximum).

As you can request a limited number of certificates per week, using the test certificate is the best practice to find possible errors.

To install testing certificates, use the following command:

sudo certbot --nginx --test-cert

And it will ask the following:

  • Enter your email address to receive urgent renewals and change in policies.
  • Use the link to download the PDF of the terms and conditions and press Y and hit enter if you agree.
  • It is optional to subscribe to the mailing list by which you will receive newsletters.
  • It will list available domain names for the request. You can select one or two manually. And if you want certificates for every domain listed, leave it blank and hit enter (that’s what I did).
Create a Web Server with NGINX and Secure it Using Certbot

If you find no errors, you can proceed with installing the actual certificate:

sudo certbot --nginx

It will ask the same set of questions but will add one different question.

As you already have installed the test certificates, you have two choices:

  • Reinstall the existing certificates (test certificates in my case)
  • Renew and replace certificates

Choose the 2nd option and hit enter:

Create a Web Server with NGINX and Secure it Using Certbot

That’s it! You have secured your website with HTTPS.

And now, if you check, the connection to the site will be secured:

Create a Web Server with NGINX and Secure it Using Certbot

Certbot is scheduled to run every 12 hours and will renew certificates if the existing one is expired. You can check the times using:

systemctl list-timers
Create a Web Server with NGINX and Secure it Using Certbot

And if you want to update them manually, you can use the following command:

sudo certbot renew

Want to live patch your Ubuntu server?

Being one of the most powerful OS, you can live patch your Ubuntu server without rebooting.

Yep, it’s that powerful. Want to learn how? Here you have it:

How to Enable Livepatching on Ubuntu Server
Tired of rebooting your Ubuntu server after every security upgrade? You may enable live kernel patching and forget about reboots altogether.
Create a Web Server with NGINX and Secure it Using Certbot

I hope you will find this guide helpful.

Let me know if you encounter any errors while executing the given steps.

Also, if you have any suggestions on what I should cover next, let me know in the comments.

Create Home Directory for Existing Users in Linux

Create Home Directory for Existing Users in Linux

Looking for a way to create a home directory for the existing user? Well, here’s a quick guide for you.

But before that, let’s have a look at why there was no home directory for the user in the first place.

Reason why home directory was not created

So if you used the useradd command to add the new user in Linux, it won’t add the home directory by default.

And if you insist on using the useradd command to create the new user, you just have to append the -m option and it will create a home directory by default.

Create the home directory for existing user

When the existing user does not have a home directory and tries login with the su - option, it will get you the following error:

Create Home Directory for Existing Users in Linux

Which clearly states that there is no home directory.

The first step is to log out from the user that does not have the home directory using the given command:

exit

Now, all you need to do is append the mkhomedir_helper and the username with the useradd command:

sudo mkhomedir_helper username

My user is named as Abhiman so my command would look like this:

sudo mkhomedir_helper Abhiman

And it will create a home directory for the user. For me, it will be named as /home/Abhiman:

ls -al /home/username
Create Home Directory for Existing Users in Linux

And if you are using desktop environments such as GNOME, KDE, etc. you will need to reboot your system to have sub-directories such as Downloads, Documents, and so on.

Bonus: Creating new users with the home directory

I prefer the adduser command for the reason that it allows the proper creation of a new user in Linux.

The regular useradd command is also capable of creating a new user with the home directory in this fashion:

sudo useradd -m new_user

Wrapping Up

This was a quick tutorial on how you can create a home directory for the existing user.

I won’t recommend you to go with recreating the user (shown as a bonus tip) unless the user is recently made and you got to know that there is no home directory.

I hope you will find this helpful and if you have any queries, let me know in the comments.

Want to Create a Website for Your Business? Here’s How

How can you create a website that attracts your target market and helps you grow your online presence?

Owning a business with a small budget can result in difficult times. You need to be creative about marketing your business and getting your name out to potential clients, especially online.

Here is our guide to help you learn how to create a website for your business.

Keep reading to find out everything you need to know by reading our guide.

Determine What You Want

If you are ready to create a website for your business, it is essential to determine what you want from your website. This is typically based on your overall business plan along with the needs and wants of your target market.

Determine your business’s purpose for a website to inform customers about products and services, share content, or take orders and payments. Setting goals for the website will help you create it more effectively.

This can include the number of visitors, leads, follows, and other metrics that define success for your business. Additionally, consider how users will interact with your website, such as how navigation and website design affects the experience.

Research Domain Name

Researching a domain name is critical when you want to create a website for your business. It’s essential to choose the most creative and relevant domain name that reflects the nature of your business, as it will become the physical address of your website.

Before you buy a domain name from CLDY, you must check if domain name restrictions are related to your sector or relevant laws. For example, some countries restrict using special characters in domain names, and some have special regulations for financial, medical, and government websites.

Once you find a domain name that reflects your business and is available, register the domain and set up your website. Most hosting packages include free website builder tools and easy templates.

You must also consider if other named businesses are operating in your sector. This is important to assess, as if the names are too similar, it could confuse and result in customers engaging with the wrong site.

For example, if a customer types in a similar name for your business, there is a strong chance that they will take them to another website with a similar domain name.

Design Your Website

Designing your website is one of the most critical steps when creating a website. It sets the tone and look of your website and gives your audience a sign of what your business offers.

It is essential to ensure that the design of your website is professional and appealing, as this will encourage more visitors to stay on your website. Numerous tools are available to help you design your website from scratch, such as site-building tools like WordPress or Wix.

Another essential element of website design is making sure the layout is user friendly; this will ensure visitors can navigate your website and find the information they are looking for. Additionally, there are templates available online that you can use and customize to match the look and feel of your business.

Establishing a straightforward website design will help to improve the user experience and encourage more visitors to stay and explore your business.

Think About Other Potential Needs

Think about other potential needs when creating an effective website for your business. These may include implementing a blog, an events page, and a shopping cart to help with transactions.

You may consider adding an FAQ page to answer common questions, a page for customer reviews, and a blog section for educational content. Be mindful of how the website will look on a smartphone since many people access the web from their phones.

Reviewing their feedback can help you identify potential needs, such as weak loading times or unresponsive buttons, and improve the website experience.

Choose a Hosting Service

Choosing a hosting service for your business website is an important decision that should not be taken lightly. The hosting service can be the difference between a successful website and an unvisited one.

You should select a reputable hosting service with a good track record and plenty of features. Some of the things to look out for are speed, site uptime, security features, customer support, scalability, and pricing.

Don’t forget to include meta tags, alt text, and appropriate titles to make it easier for search engines to read your website. Finally, you should test the website by having several people use it who have yet to see it.

Finally, ensure the hosting service you select is compatible with the content management system and other web development tools you intend to use. Doing your research and choosing the right hosting service will be essential in giving your business website the best possible chance of success.

Launch and Test Your Website

Once you have created and designed your website, it’s time to launch and test it. Before you share it with potential customers, it’s essential to ensure that all the backend components, such as databases, web pages, and web services are set up, working smoothly, and secured.

Make sure the website is secure, and that it works with a variety of web browsers and devices. Once you’re happy with the test findings, you may launch your website and begin online promotion once you think it’s ready.

Use online tools and check if the loading time of your website is satisfactory. If you find any potential problems, now is the time to address them. Repeat using the website to test for any speed or loading issues.

If everything functions and looks great, it’s time to let the world know about your business and launch your website!

Start Creating Your Website Now

Creating your business website can be manageable. Use these tips to help streamline the process and reap the rewards of having a website presence.

By taking each of these steps, you can ensure that your business website is ready to launch and receive its first visitors. Start creating your website today and join the thousands of businesses that have seen success online.

Did you find these reads helpful? Then check the rest of our blog posts.

How to Create Large Files in Linux

How to Create Large Files in Linux

Creating files in Linux is something we do all the time. Mostly you create an empty text file with the touch command and then add content to it.

But what about creating new files of a certain size?

When you are troubleshooting something or want to test in some particular scenario, you may require large files bigger than a certain size. Let’s say 500 MB or 2 GB.

Now, you cannot create an empty file and then start writing garbage text in it. You can never be able to create a file of 1 GB in size this way.

Thankfully, you don’t have to manually create large text files. There are various commands that allow you to create large files of predefined size. They won’t have desired tex. Just some random garbage but you’ll get the file of your desired size.

Let me show how to do that.

Creating large files using the dd command

The dd command is used for copying and converting files. Its most common use can be found in creating live Linux USBs.

Let’s say you want to create a text file named testfile.img of 2 GB size. Here’s what you can do:

dd if=/dev/zero of=testfile.img bs=2G count=1

Depending on the size of the file, the command will take some time to complete.

How to Create Large Files in Linux

Here, you created a file of 2 GB in size that has a single block (count 1) of size (bs, block size) 2 G. The file contains the NULL characters (/dev/zero).

You can change the block size and count of blocks as you per your need. For example, you could have used 1M as bs with 1024 as count to get file of 1024 Mb. You can mix and match as you like.’

💡
Since the file only contains NULL, you cannot count lines in it. If you want some text content instead of NULL, you can use /dev/random as the input in the dd command.

Using the truncate command to create huge files

The truncate command reduces or increases the size of each FILE to the desired size.

Extra data is lost if a FILE is bigger than the required size. If a FILE is too short, it is expanded, and the extra portion (hole) is accessed as zero bytes.

Let’s use the truncare command to create file of 2 GB in size.

truncate -s 2G testfile.img

You will see no output from the above command, however, the resultant file can be seen using the ls command:

ls -lh testfile.img
How to Create Large Files in Linux
💡
By default, the truncate command will create new files if the requested output file does not already exist. You can use the option -c to avoid creation of new files.

Using the fallocate command to create huge files

The fallocate command is my recommended way for creating a large file because it is the fastest.  

To create a file of 1 GB, use it like this:

fallocate -l 1G testfile1.img

Now check the output file:

ls -lh testfile1.img
How to Create Large Files in Linux

It is far quicker to use fallocate than to create a file by populating it with zeroes.

Conclusion

The files created by the dd and truncate are sparse files. In the computer world, a sparse file is a special file that tries to utilize the space on a file system in a very efficient manner when the blocks assigned to a file are mainly empty.

Sparse files have varying apparent file sizes (the largest size to which they can expand) and true file sizes (how much space is allocated for data on disk).

You can see the apparent size and the true size with the du command:

How to Create Large Files in Linux

This is why I prefer using fallocate command. It is faster and it does not create sparse files.

How to Create a Virtual Block or Loop Device in Linux

How to Create a Virtual Block or Loop Device in Linux

Linux users can have a virtual block device called a “loop device” that maps a normal file to a virtual block, making it ideal for tasks related to isolating processes.

And the best example for utilizing loop devices is snap packages, a sandboxed software solution containing every necessary dependency and mounted as a loop devices:  

How to Create a Virtual Block or Loop Device in Linux

And if you’re interested in creating your own virtual block device, here’s a simple guide.

How to Create A Loop Device

For ease of understanding, I’ve decided the entire process in the form of simple steps so it can be easier to grasp.

And if you’re interested in learning more about loop device in Linux and its use, I’ll recommend the other guide of ours that covers the basics:

What is a Loop device in Linux? – It’s FOSS
Seeing too many loop devices in Ubuntu? Learn what are these loop devices and why is it used on your Linux system.
How to Create a Virtual Block or Loop Device in Linux

1. Create a File of Desired Size

In the first step, you’re required to create a file as per your needs. For this example, I’ll be creating a file of 3 Giga bytes:

dd if=/dev/zero of=VirtBlock.img bs=100M count=30
How to Create a Virtual Block or Loop Device in Linux

Here,

  • if=/dev/zero will create a block of 0s to hold data.
  • of=VirtBlock.img is where you’ll specify the name. I went with VirtBlock.img.
  • bs=100M will set the size of a single block.
  • count=30 will create copies of single blocks for given times. Meaning 100Mb * 30 times is about 3 GB in size.

Now, let’s verify the size of the recently created block by the given command:

du -sh VirtBlock.img 
How to Create a Virtual Block or Loop Device in Linux

2.  Create the Loop Device

In this step, I’ll be utilizing the losetup utility to create a loop device mapping at a recently created file.

sudo losetup -fP VirtBlock.img

Where,

  • -f (find) will find us unused loop devices and save us from errors like “losetup: TO_BLOCK: failed to set up loop device: Device or resource busy”.
  • -P will force the kernel to scan the partition table on the newly created loop device.

Now, its time for us to print all the loop devices using the -a option with losetup as given:

sudo losetup -a
How to Create a Virtual Block or Loop Device in Linux

But your block needs to have a file system to create, store and configure files to that block and I’ll be going with ext4:

sudo mkfs.ext4 /home/sagar/VirtBlock.img
How to Create a Virtual Block or Loop Device in Linux

Make sure to use the exact path or it will throw an error. Use the reference from sudo losetup -a command.

3. Mount the Loop device

To mount created loop device, the first step should be creating a mounting directory which can be done through the given command:

sudo mkdir /loopfs

To mount the loop device (mine is loop21), I’ll be using the -o loop option as given:

sudo mount -o loop /dev/loop21 /loopfs

Now, you can verify the mounting point and size of the recently mounted loop device:

df -hP /loopfs/

To verify the file system, you can go with the given command:

mount | grep loopfs
How to Create a Virtual Block or Loop Device in Linux

And here you have it!!

How to Remove loop device

Removing a piece of software is always easy than installation/configuration and that’s the same case here!

First, you’ll have to unmount and remove the mounting directory:

sudo umount /loopfs
sudo rmdir /loopfs

Now, you’ll have to detach the loop device (mine is loop21) which was created by “losetup -d” command:

sudo losetup -d /dev/loop21

Finally, you have to remove the file (VirtBlock.img) by the given command:

sudo rm /home/sagar/VirtBlock.img

The process ends here.

Final Words

Using a loop device for isolation is a handy Linux feature.

This guide went through the configuration and removal process in an easy manner. If you encounter any issues, leave a comment and I’ll try to help you out.

Stupid Simple App to create Light & Dark Wallpapers in GNOME

Got photo images in both light and dark style? There’s a super simple application to set them as dynamic wallpapers in GNOME 42+ desktop.

As you may know, GNOME 42+ support light and dark wallpapers that change automatically depends on system color scheme. Ubuntu 22.04 does not support the feature, but in upcoming Ubuntu 22.10 you may add your own ones into wallpaper selection dialog:

It’s easy to group your light and dark photo images as a single wallpaper selection. Just create a XML file under “.local/share/gnome-background-properties” (create folder if not exist), and write following rules:

<?xml version="1.0"?>
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
<wallpapers>
  <wallpaper deleted="false">
    <name>TYPE_NAME_HERE</name>
    <filename>/PATH/TO/PICTURE_LIGHT</filename>
    <filename-dark>/PATH/TO/PICTURE_DARK</filename-dark>
    <options>zoom</options>
    <shade_type>solid</shade_type>
    <pcolor>#3465a4</pcolor>
    <scolor>#000000</scolor>
  </wallpaper>
</wallpapers>

It will then be available in the “Appearance” settings pages (Ubuntu 22.10 will merge ‘Background’ into ‘Appearance’).

To make life easier, a stupid simple application called “Dynamic Wallpaper” is created to do the job. With it, you may just type a name, select the 2 photo images and click “Create” button.

As mentioned above, it automatically creates a XML file with the name you typed, and saves to “.local/share/gnome-background-properties” directory. It also makes a copy of the photo images into “.local/share/backgrounds“, and refers to them in the XML file.

When done, you may go to “Appearance” in GNOME Control Center (aka “Settings” utility) to select that wallpapers.

How to Install the “Dynamic Wallpaper” app

The tool is available to install as Flatpak package, that works in Ubuntu 22.10+, Fedora 36+, Arch and Manjaro Linux with GNOME Desktop.

1. First, search for and open terminal from ‘Activities’ overview (or press Ctrl+Alt+T on Ubuntu). When it opens, run command to install Flatpak daemon:

sudo apt install flatpak

2. Next, run the command below to install the tool:

flatpak install https://dl.flathub.org/repo/appstream/me.dusansimic.DynamicWallpaper.flatpakref

If you’re first time installing a Flatpak package, there will be also hundred MB run-time libraries to install.

Finally, click the top-left corner ‘Activities’, then search for and open the application:

Uninstall:

To remove the tool, open terminal and run command:

flatpak uninstall --delete-data me.dusansimic.DynamicWallpaper

And clear useless libraries via flatpak uninstall --unused.

How to create a systemd service in Linux

How to create a systemd service in Linux

Since its introduction in March 2010, people have had various opinions about systemd. But one thing that you can not deny is that systemd is now present in almost all Linux distributions!

Sure, there are Linux distributions that explicitly advertise usage of a different init system other than systemd, but those are very rare. Ubuntu, Fedora, RHEL, Debian, Pop!_OS, openSUSE, Arch, all of them ship with systemd by default.

Since systemd is used so widely, it is worth taking a look and learning how to create systemd services.

What is a systemd service?

Simply put, a service is a “background” process that is started or stopped based on certain circumstances. You are not required to manually start and/or stop it. A ‘systemd service’ is a file that is written in a format such that systemd is able to parse and understand it, and later on do what you told it to do.

Technically what I am referring to as ‘systemd service’ file is actually called a ‘systemd unit’ file, but since this tutorial is about creating a service, I will continue referring to this as ‘systemd service’ file.

Understanding the basic structure of a systemd service file

The systemd service file as three important and necessary sections. They are [Unit], [Service] and [Install] sections. The systemd service file’s extension is .service and we use the pound/hash symbol (#) for comments.

Below is an example of a systemd service file. Please note that this is NOT an actual systemd service file. I have modified it so that it helps you understand.

[Unit]
Description=Apache web server
After=network.target
Before=nextcloud-web.service

[Service]
ExecStart=/usr/local/apache2/bin/httpd -D FOREGROUND -k start
ExecReload=/usr/local/apache2/bin/httpd -k graceful
Type=notify
Restart=always


[Install]
WantedBy=default.target
RequiredBy=network.target

This is the most basic structure of a systemd service file. Let us understand what each of these words mean.

The [Unit] section

The Unit sectoin contains details and description about the unit itself. In our case, it contains details about the service. Details like ‘what is it’s description’, ‘what are it’s dependencies’ and more.

Below are the fields the Unit section has:

  • Description:- Human-readable title of the systemd service.
  • After:- Set dependency on a service. For example, if you are configuring Apache web server, you want the server to start after the network is online. This typically includes targets or other services.
  • Before:- Start current service before specified service. In this example, I tell that “I want Apache web server running before the service for Nextcloud is started”. This is because, in my case, Nextcloud server depends on the Apache web server. This too, like After, includes targets or other services.

The [Service] section

The Service section contains details about the execution and termination of service.

Below are the fields the Service section has:

  • ExecStart:- The command that needs to be executed when the service starts. In our case, we want Apache server to start.
  • ExecReload:- This is an optional field. It specifies how a service is restarted. For services that perform disk I/O (especially writing to disk, like a database), it is best to gracefully kill them and start again. Use this field in case you wish to have a specific restart mechanism.
  • Type:- The process start-up type for this systemd service. Options are simple, exec, forking, oneshot, dbus, notify and idle. (more info here)
  • Restart:- This is another optional field but one that you will very likely use. This specifies if a service should be restarted–depending on circumstances–or not. The available options are no, on-success, on-failure, on-abnormal, on-watchdog, on-abort and always.

The [Install] section

The Install section, as the name says, handles the installation of a systemd service/unit file. This is used when you run either systemctl enable and systemctl disable command for enable/disable a service.

Below are the fields the Install section has:

  • WantedBy:- This is similar to the After and Before fields, but the main difference is that this is used to specify systemd-equivalent “runlevels”. The default.target is when all the system initialization is complete–when the user is asked to log in. Most user-facing services (like Apache, cron, GNOME-stuff, etc) use this target.
  • RequiredBy:- This field might feel very similar to WantedBy, but the main difference is that this field specifies hard dependencies. Meaning, if a dependency, this service will fail.

What I have listed above, is only a minimal example. There are loads of knobs that you can turn to customize your service depending on your environment and needs.

For a complete documentation about systemd, please refer to this page. This is literally has everything documented!

Creating your own systemd service

Now that you know the structure of a basic systemd service file let us dive into creating your own systemd service.

For this example, I will create a simple systemd service that executes a bash script on boot. Here is my bash script, named check-file-system.sh, placed in the ~/.scripts/ directory.

#!/usr/bin/env bash

ROOT_PARTITION=$(mount | grep '/ ' | awk '{print $1}')
PHYSICAL_DISK=$(lsblk -no pkname ${ROOT_PARTITION} | head -n 1)

if [ ${EUID} -ne 0 ]
then
	exit 1 # this is meant to be run as root
fi

fsck /dev/${PHYSICAL_DISK}
⚠️
This bash script will fail immediately since the device we are fsck-ing is mounted as rootfs. This script is meant for demonstration purposes only 😉

Let me explain what I am doing in this script. I am finding what disk partition is mounted as root (/). That can be /dev/sda1 or /dev/sdb2, or anything else. Using that, I am finding out the actual drive name (sda).

With that information, I am running a file system check with fsck command on that drive. I wish to run this script at each boot time.

For that, I will create a systemd service file, like so:

[Unit]
Description=Checking filesytems on boot
After=multi-user.target

[Service]
ExecStart=/usr/bin/bash /home/pratham/.scripts/check-file-system.sh
Type=simple

[Install]
WantedBy=multi-user.target

Excellent! Our systemd service file is ready now.

Choosing a location for our systemd service file

Now that our start-up script and systemd service files are ready… Where do I save the systemd service file, and how do I enable it?

Before I answer that question, I need to ask a different question first. “This systemd service that is going to be executed, who will execute it? Does it need superuser privilages? Does it need to be executed as a specific user?”

Below are the locations you can place a systemd service file in, depending on the user that is going to execute it.

  • root: /etc/systemd/system/
  • pratham: /home/pratham/.config/systemd/user/

For this example, my user is named pratham, but yours will most definitely be different than mine.

So, if a service needs superuser privilages, like generating a filesystem database every 6 hours, it needs to have superuser privilages. Hence, this must be placed in the /etc/systemd/system/ directory.

💡
systemd services that are executed by the normal user will need the --user option to be explicitly passed. Let’s say only user pratham has a service called greet-pratham.service, to restart it, I will use the command systemctl --user restart greet-pratham.service

For a service which doesn’t any special privialges, it is best executed by a normal user, like pratham. So that must be place in the ~/.config/systemd/user/ directory.

In our example, we are performing a file system check, which requires superuser privilages. So, I will place my systemd service file in the /etc/systemd/system/ directory. The absolute path of my systemd service file is /etc/systemd/system/fsck-on-boot.service

Final steps

Now that a systemd service file has been created and is placed in the correct location, you need to tell systemd to reload the unit files. This is because you created a new service and services are detected at boot time. You have already booted, so you need to do this manually.

To tell systemd to reload unit files, use the following command (for a service that need superuser privilages):

sudo systemctl daemon-reload

Alternatively, if you created a user service, use the following command:

systemctl --user daemon-reload

Once that is done, you can enable the service. I will enable my service fsck-on-boot.service like so:

sudo systemctl enable fsck-on-boot.service

Once you have enabled the service, check its status using the systemctl status command.

$ sudo systemctl status fsck-on-boot.service
× fsck-on-boot.service - Checking filesytems on boot
     Loaded: loaded (/etc/systemd/system/fsck-on-boot.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Tue 2022-09-06 09:57:04 IST; 8s ago
   Main PID: 130145 (code=exited, status=8)
        CPU: 82ms

Sep 06 09:57:04 vidhyaa systemd[1]: Started Checking filesytems on boot.
Sep 06 09:57:04 vidhyaa bash[130153]: fsck from util-linux 2.37.2
Sep 06 09:57:04 vidhyaa bash[130155]: e2fsck 1.46.5 (30-Dec-2021)
Sep 06 09:57:04 vidhyaa bash[130155]: /dev/sda is in use.
Sep 06 09:57:04 vidhyaa bash[130155]: e2fsck: Cannot continue, aborting.
Sep 06 09:57:04 vidhyaa systemd[1]: fsck-on-boot.service: Main process exited, code=exited, status=8/n/a
Sep 06 09:57:04 vidhyaa systemd[1]: fsck-on-boot.service: Failed with result 'exit-code'.

As I previously mentioned, the script failed. But, more importantly, the service is enabled. That’s what matters more.

Now, you can treat this service as any regular service by stopping it, starting it, restarting it, disabling it, re-enabling it, etc…

Conclusion

This article discusses some key aspects of creating your own systemd service. The anatomy of a systemd service file, where to place it, reloading systemd to make it aware of your newly created service, enabling the service and finally, checking it’s status.