Backend Development 6 min read

How to Run Rust Server Programs as Daemons with Fork or Daemonize

This article explains how to add a daemon flag to a Rust server, showing two implementations—one using the fork crate and another using the daemonize crate—so the service can keep running after the shell exits.

JD Cloud Developers
JD Cloud Developers
JD Cloud Developers
How to Run Rust Server Programs as Daemons with Fork or Daemonize

When deploying a server program written in Rust, it is often necessary to run it as a daemon so that it continues after the shell exits.

Traditionally, applications are started with

nohup … &

or use container‑specific scripts; tools like nginx and Redis also provide daemon options.

This article demonstrates how to add a command‑line flag that starts a Rust service in daemon mode and how to stop it gracefully, using an example from the interactcli‑rs project.

Two implementations are shown:

Fork‑based daemon

<code>pub fn start(prefix: String) {
    for i in 0..1000 {
        println!("{}", &amp;prefix.clone() + &amp;i.to_string());
        thread::sleep(Duration::from_secs(1));
    }
}
</code>

The

fork

crate’s

daemon

function creates a child process, the code removes the

-d

/

-daemon

flag, spawns the child, writes its PID to a file, and exits the parent.

Daemonize‑based daemon

<code>if let Some(startbydaemonize) = server.subcommand_matches("bydaemonize") {
    println!("start by daemonize");
    let base_dir = env::current_dir().unwrap();
    if startbydaemonize.get_flag("daemon") {
        let stdout = File::create("/tmp/daemon.out").unwrap();
        let stderr = File::create("/tmp/daemon.err").unwrap();
        let daemonize = Daemonize::new()
            .pid_file("/tmp/test.pid")
            .chown_pid_file(true)
            .working_directory(base_dir.as_path())
            .umask(0o777)
            .stdout(stdout)
            .stderr(stderr)
            .privileged_action(|| "Executed before drop privileges");
        match daemonize.start() {
            Ok(_) => println!("Success, daemonized"),
            Err(e) => eprintln!("Error, {}", e),
        }
    }
    println!("pid is:{}", std::process::id());
    fs::write("pid", process::id().to_string()).unwrap();
    start("by_daemonize:".to_string());
}
</code>

This version sets the working directory to the current directory, redirects output to temporary files, creates a PID file, and records the daemon’s PID.

Both approaches keep the service running after the shell closes. They rely on unsafe calls to libc and work on Unix‑like systems; Windows has not been verified.

The tutorial concludes with a brief recap and a promise of future topics.

Backend DevelopmentRustDaemonForkDaemonize
JD Cloud Developers
Written by

JD Cloud Developers

JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.