- Do you still need rc.local?
- Enabling rc.local in Ubuntu (18.04, 20.04, 22.04 and higher)
- Enabling rc.local on CentOS 7/8 and AlmaLinux 8/9
- Practical examples and practical tips
- Common debugging
- Alternatives and best practices
- Security and operational tips
- The relationship of this training to the company's services
- Conclusion and final suggestions
- Frequently Asked Questions
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
- Create file /etc/rc.local And add the desired shebang and commands.
- Granting executable permission to the file.
- Create or enable the rc.local unit in systemd (if it doesn't exist).
- 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 0Then set the permission:
sudo chmod +x /etc/rc.localIf 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
EOFAnd 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 0Executive license:
sudo chmod +x /etc/rc.d/rc.localIf 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
EOFAnd 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 -bsudo restorecon -v /etc/rc.d/rc.local
# or temporarily change context
sudo chcon -t bin_t /etc/rc.d/rc.localIt 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 0Note: 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.targetRunning 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
EOFsudo systemctl daemon-reload
sudo systemctl enable --now myjob.service
Common debugging
- Service in failed state: From
sudo journalctl -u rc-local.service -bUse 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.shFor 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.









