이 글은 핵심 개념과 실제 적용 방법을 단계별로 안내합니다. 본문을 통해 독자는 실무에 바로 적용할 수 있는 구체적인 설정법과 확실한 해결책을 얻게 됩니다.
초보자부터 전문가까지 누구나 쉽게 따라 할 수 있도록 구성되었습니다. 핵심 원리를 이해하고 실제 환경에 적용해 보세요.
각 단계별로 상세한 설명과 예시 코드가 포함되어 있습니다. 이를 통해 시행착오를 줄이고 빠르게 목표를 달성할 수 있습니다.
재부팅 후 서비스가 안 올라온다면 — 새벽 호출의 원인 무엇인가요?
VPS에 Node.js 앱·DB·웹서버를 직접 띄워놓고, 보안 패치 때문에 서버가 재부팅됐는데 서비스가 자동으로 올라오지 않아 새벽에 장애 알림을 받은 적이 있나요? 서비스가 자동으로 시작되지 않으면 결국 사람이 직접 접속해서 재시작해야 합니다. systemd로 서비스를 등록하면 이 문제가 사라집니다.

이 튜토리얼에서는 systemd unit 파일을 직접 작성해서 서비스를 등록하고, 자동 시작·크래시 복구·통합 로그 관리까지 설정하는 전체 과정을 다룹니다. Ubuntu, Debian, CentOS 등 대부분의 현대 Linux 배포판에서 그대로 적용됩니다.
1. systemd란? — PID 1에서 모든 서비스를 관리 무엇인가요?
systemd는 Linux 부팅 시 가장 먼저 시작되는 PID 1 프로세스로, 이후 실행되는 모든 시스템 서비스를 통합 관리합니다. 과거의 SysV init 스크립트를 대체하며, 의존성 기반 병렬 부팅, 온디맨드 서비스 활성화, 통합 로그(journald) 등을 제공합니다.
핵심 장점은 서비스가 죽어도 자동으로 재시작하고, 서버가 재부팅돼도 자동으로 시작한다는 점입니다. 더 이상 nohup이나 screen에 의존할 필요가 없습니다.
2. unit 파일 구조 — [Unit]/[Service]/[Install] 무엇인가요?
systemd 서비스는 /etc/systemd/system/ 아래 .service 확장자의 unit 파일로 정의합니다. 기본 구조는 세 섹션입니다:
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js Application
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/home/deploy/myapp
ExecStart=/usr/bin/node /home/deploy/myapp/server.js
Restart=always
RestartSec=3
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
[Unit] 섹션은 서비스의 메타데이터와 의존성을 정의합니다. [Service]는 실제 실행 명령과 동작 방식을, [Install]은 enable 시 어떤 target에 연결될지를 지정합니다.

3. 서비스 등록 — daemon-reload, enable, start, status 무엇인가요?
unit 파일을 만들었으면 systemd가 인식하도록 reload하고, 활성화합니다:
sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
sudo systemctl status myapp.service
daemon-reload는 unit 파일 변경사항을 반영하는 명령입니다. 파일을 수정할 때마다 반드시 실행해야 합니다. enable은 부팅 시 자동 시작을 등록하고, start는 지금 당장 서비스를 시작합니다.
4. 자동 시작 — enable vs disable, multi-user.target 무엇인가요?
systemctl enable은 [Install]의 WantedBy=multi-user.target에 따라 심볼릭 링크를 생성합니다. multi-user.target은 런레벨 3(멀티유저 모드)에 해당하므로, 일반적인 서버 부팅 시 자동으로 서비스가 시작됩니다.
sudo systemctl enable myapp // 자동 시작 ON
sudo systemctl disable myapp // 자동 시작 OFF
is-enabled로 현재 상태를 확인할 수 있습니다:
sudo systemctl is-enabled myapp
5. 자동 재시작 — Restart=always, RestartSec 무엇인가요?
서비스가 크래시로 종료됐을 때 systemd가 자동으로 재시작하게 하려면 Restart=always를 설정합니다. RestartSec는 재시작 사이의 대기 시간입니다:
[Service]
Restart=always
RestartSec=3
Restart 옵션의 종류:
always— 종료 이유와 무관하게 항상 재시작 (권장)on-failure— 비정상 종료(0이 아닌 exit code, 시그널) 시에만 재시작no— 재시작 안 함 (기본값)
크래시 루프 방지를 위해 StartLimitBurst와 StartLimitIntervalSec으로 재시작 횟수 제한을 걸 수도 있습니다.

6. journalctl 로그 — -u, -f, –since, 영속 로그 무엇인가요?
systemd는 journald라는 통합 로그 시스템을 사용합니다. journalctl 명령으로 모든 서비스 로그를 통합 조회할 수 있습니다:
// 특정 서비스 로그 (follow)
sudo journalctl -u myapp -f
// 최근 100줄
sudo journalctl -u myapp -n 100
// 오늘 로그만
sudo journalctl -u myapp --since today
// 특정 시간 이후
sudo journalctl -u myapp --since "2026-07-05 00:00:00"
// 에러만
sudo journalctl -u myapp -p err
주의: 기본적으로 journald 로그는 /run/log/journal/에 저장되어 재부팅 시 삭제됩니다. 영속 로그를 원하면 디렉토리를 만들어줍니다:
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
7. 의존성과 순서 — After, Requires, Wants 무엇인가요?
서비스 간 의존성을 정의하면 올바른 순서로 시작됩니다. 예를 들어 DB가 필요한 앱이라면:
[Unit]
Description=My App
After=network.target postgresql.service
Requires=postgresql.service
After=— 지정한 서비스 이후에 시작 (순서만)Requires=— 강한 의존성. 지정한 서비스가 실패하면 이 서비스도 실패Wants=— 약한 의존성. 지정한 서비스 실패와 무관하게 진행
마무리 — systemd로 서버 운영을 자동화하자 무엇인가요?
systemd unit 파일 하나로 서비스 자동 시작, 크래시 복구, 통합 로그 관리가 모두 해결됩니다. 더 이상 새벽에 서버 접속해서 수동으로 재시작할 필요가 없습니다. VPS에 서비스를 직접 운영한다면 systemd 등록은 선택이 아닌 필수입니다.
다음 단계로는 Fail2ban으로 SSH 무차별 대입 공격을 차단하는 설정을 추천합니다. VPS 보안의 핵심입니다.
자주 묻는 질문 (FAQ)
Q1. nohup이나 screen으로 띄우는 것과 뭐가 다른가요?
systemd에 등록하면 프로세스가 죽어도 자동으로 재시작되고 서버가 재부팅돼도 자동으로 올라옵니다. nohup·screen은 이 두 가지를 보장하지 못해 결국 사람이 접속해 다시 띄워야 합니다.
Q2. unit 파일을 고쳤는데 반영이 안 됩니다.?
sudo systemctl daemon-reload를 실행해야 systemd가 변경된 unit 파일을 다시 읽습니다. 파일을 수정할 때마다 daemon-reload 후 restart 하세요.
Q3. enable과 start는 뭐가 다른가요?
start는 지금 당장 서비스를 시작하는 명령이고, enable은 [Install]의 WantedBy=multi-user.target에 심볼릭 링크를 만들어 부팅 시 자동 시작을 등록하는 명령입니다. 지금도 뜨고 재부팅 후에도 뜨게 하려면 둘 다 필요합니다.
Q4. 재부팅하면 로그가 사라집니다.?
journald 로그는 기본적으로 /run/log/journal/에 저장되어 재부팅 시 삭제됩니다. sudo mkdir -p /var/log/journal 후 systemd-journald를 재시작하면 영속 로그로 전환됩니다.



















