How to enable rc.local in Ubuntu, CentOS and AlmaLinux and launch it on reboot
In this article, we will examine the step-by-step method of enabling the rc.local file in Linux distributions.

How to enable rc.local in Ubuntu, CentOS and AlmaLinux and launch it on reboot

This article is a step-by-step guide to enabling rc.local on Ubuntu, CentOS, and AlmaLinux systems. Using this tutorial, system administrators and DevOps can easily run scripts at system boot.
0 Shares
0
0
0
0

 

Do you still need rc.local?

In this step-by-step guide, we will learn how to create a traditional file. rc.local in common Linux distributions such as Ubuntu, CentOS and AlmaLinux Enable and run the required scripts or commands at boot time.

Although systemd It has become common as the default init, rc.local It is still useful for quickly and easily executing short scripts at boot time. Below are methods, examples, security tips, and modern alternatives.

 

Enabling rc.local in Ubuntu (18.04, 20.04, 22.04 and higher)

In new Ubuntu releases that systemd rc.local can be enabled as follows. The general steps include creating the file, setting permissions, and creating/enabling a unit for systemd compatibility.

General steps

  1. Create file /etc/rc.local And add the desired shebang and commands.
  2. Granting executable permission to the file.
  3. Create or enable the rc.local unit in systemd (if it doesn't exist).
  4. Loading, activating, and checking service status.

Example of a sample file /etc/rc.local (Always at the end) exit 0 Place):

#!/bin/bash
# Example: start Docker container named myapp
docker start myapp || docker run -d --name myapp myimage
# simple sysctl
/sbin/sysctl -w net.ipv4.ip_forward=1
exit 0

Then set the permission:

sudo chmod +x /etc/rc.local

If the corresponding unit does not exist, create it:

sudo tee /etc/systemd/system/rc-local.service > /dev/null <<'EOF'
[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

And finally:

sudo systemctl daemon-reload
sudo systemctl enable rc-local.service
sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
sudo journalctl -u rc-local.service -b

 

Enabling rc.local on CentOS 7/8 and AlmaLinux 8/9

RHEL-based distributions have different paths; the traditional path is usually /etc/rc.d/rc.local The general steps are similar to Ubuntu, but pay attention to the SELinux path and notes.

Common routes

  • /etc/rc.d/rc.local The traditional path is in RHEL/CentOS.
  • On some systems, the link may /etc/rc.local To exist.

Activation steps (CentOS / AlmaLinux)

Create/Edit File:

sudo nano /etc/rc.d/rc.local
#!/bin/bash
# Example: mount NFS or start a container
mount -a
/usr/bin/my-startup-script.sh &
exit 0

Executive license:

sudo chmod +x /etc/rc.d/rc.local

If unit does not exist, create it:

sudo tee /etc/systemd/system/rc-local.service > /dev/null <<'EOF'
[Unit]
Description=/etc/rc.d/rc.local Compatibility
ConditionPathExists=/etc/rc.d/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

And then:

sudo systemctl daemon-reload
sudo systemctl enable rc-local.service
sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
sudo journalctl -u rc-local.service -b
sudo restorecon -v /etc/rc.d/rc.local
# or temporarily change context
sudo chcon -t bin_t /etc/rc.d/rc.local

It is also better to use absolute paths in scripts like /usr/bin/docker Use to reduce dependency on PATH.

 

Practical examples and practical tips

Example — Running the Docker launcher script

#!/bin/bash
# start redis container at boot
/usr/bin/docker run -d --name redis-cache --restart unless-stopped redis:6
exit 0

Note: Use the option --restart unless-stopped Makes Docker handle container rollback.

Example — Network mount before running the service

If the script requires NFS mounts, modify the systemd unit with the appropriate dependencies:

[Unit]
After=network-online.target remote-fs.target
Wants=network-online.target remote-fs.target

Running a long script or permanent service — a better way

For long-running or service-oriented tasks, it is better to create a dedicated systemd unit to use features like Restart and monitoring:

sudo tee /etc/systemd/system/myjob.service > /dev/null <<'EOF'
[Unit]
Description=My Long Running Job
After=network-online.target

[Service]
Type=simple
User=myuser
ExecStart=/usr/local/bin/my-long-script.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now myjob.service

 

Common debugging

  • Service in failed state: From sudo journalctl -u rc-local.service -b Use to view the log.
  • Permissions: Make sure the file is executable (chmod +x) and the shebang exists at the beginning.
  • Relative paths: Always use absolute paths for binaries.
  • Environmental variables: rc.local has a limited environment; explicitly define variables like PATH or write the full path.
  • SELinux: Check AVC errors and set context.
  • Dependencies: If the script is network or filesystem dependent, unit should be After= and Wants= It should be suitable.

 

Alternatives and best practices

  • Dedicated systemd unit: It is the best option for services.
  • crontab @reboot: Suitable for simple user tasks:
    @reboot /usr/local/bin/myscript.sh
  • cloud-init: Suitable for initial configuration in cloud environments.
  • Configuration management tools like Ansible: It is used to make repeatable and manageable changes.

 

Security and operational tips

From executing sensitive commands in rc.local Avoid. It is better to run scripts with specific ownership or use the User= Used in systemd.

Always log script output and use limited permissions. Example:

/usr/local/bin/myscript.sh >> /var/log/rc.local.log 2>&1
chmod 700 /usr/local/bin/myscript.sh

For production environments, test in a staging environment before applying changes to critical servers.

 

The relationship of this training to the company's services

Our company's services in over 85 global locations including VPS, cloud server, graphics server (GPU), dedicated server and networking enable you to:

  • Run startup scripts quickly on trading or gaming VPSs.
  • On GPU servers, use systemd units to start heavy services so that processing starts properly after reboot.
  • On network and anti-DDoS servers, create custom systemd units to run network scripts and iptables.
  • The support team is available for SELinux, mount paths, and dependencies.

 

Conclusion and final suggestions

Despite systemd, rc.local It's still a simple way to run custom commands at boot, but for stability and monitoring it's better to use systemd units.

Always pay attention to permissions, SELinux, and service dependencies, and use logs for debugging.

If you have a specific need (e.g., automated trading robot execution, GPU environment preparation, or game server network configuration), our technical team is ready to assist in various locations.

 

Frequently Asked Questions

You May Also Like