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

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

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

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());
}

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

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

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.