프로그래밍/운영체제

systemd RuntimeDirectory와 StateDirectory 기준 정리

포도알77 2026. 6. 9. 10:18

systemd RuntimeDirectory와 StateDirectory 기준 정리

RuntimeDirectory=, StateDirectory=, CacheDirectory=, LogsDirectory=는 systemd 서비스가 직접 쓸 디렉터리를 표준 위치에 만들고 수명과 권한을 함께 관리하는 지시어다. 2026년 6월 9일 기준 systemd 공식 문서를 보면 이 네 지시어는 이름이 비슷하지만 생성 위치, 삭제 시점, 적합한 데이터 성격이 다르다.

실무에서 핵심은 "재부팅이나 서비스 중지 후에도 남아야 하는가", "캐시인지 상태 데이터인지", "tmpfiles.d보다 서비스 unit 안에서 수명을 묶는 편이 맞는가"를 먼저 구분하는 것이다. 이 글은 systemd 공식 문서 기준으로 각 지시어의 차이와 선택 기준만 정리한다.

각 지시어는 어디에 디렉터리를 만들까?

systemd.exec 문서의 표에 따르면 system service 기준 기본 위치는 다음과 같다.

지시어 기본 경로 수명 대표 용도
RuntimeDirectory= /run/ 서비스 중지 시 제거 가능, 재부팅 시 사라짐 소켓, PID 파일, 일시적 런타임 상태
StateDirectory= /var/lib/ 서비스 중지 후에도 유지 애플리케이션 상태, 영속 데이터
CacheDirectory= /var/cache/ 서비스 중지 후에도 유지 재생성 가능한 캐시
LogsDirectory= /var/log/ 서비스 중지 후에도 유지 서비스 전용 로그 파일

user service에서는 같은 지시어가 각각 $XDG_RUNTIME_DIR, $XDG_STATE_HOME, $XDG_CACHE_HOME, $XDG_STATE_HOME/log 아래로 매핑된다. 즉 같은 unit 문법이라도 system manager인지 user manager인지에 따라 실제 경로는 달라질 수 있다.

RuntimeDirectory=는 언제 써야 할까?

RuntimeDirectory=는 서비스가 실행 중일 때만 필요한 경로를 /run 아래에 만들고, 런타임 수명과 묶고 싶을 때 적합하다. 공식 문서는 권한이 없는 데몬이 직접 /run 아래 디렉터리를 만들기 어려운 경우에도 이 지시어가 유용하다고 설명한다.

대표 예시는 유닉스 소켓, lock 파일, PID 파일, 재부팅 후 남을 필요가 없는 임시 상태다. 기본적으로 RuntimeDirectory=로 만든 가장 안쪽 디렉터리는 서비스가 멈출 때 제거되며, 재부팅 후에도 유지되지 않는다.

다만 삭제 시점은 RuntimeDirectoryPreserve=로 조정할 수 있다. 공식 문서 기준 기본값은 no이고, restart는 재시작 때 보존, yes는 정지 후에도 제거하지 않는 동작이다.

StateDirectory=CacheDirectory=는 무엇이 다를까?

둘 다 서비스가 멈춰도 남는 디렉터리지만 데이터 성격이 다르다. StateDirectory=는 서비스의 지속 상태를 보관하는 경로이고, CacheDirectory=는 필요하면 다시 만들 수 있는 캐시를 두는 경로다.

예를 들어 인덱스 파일, 메타데이터 DB, 장기적으로 유지할 동기화 상태는 StateDirectory= 쪽에 가깝다. 반면 다운로드한 중간 산출물, 렌더 캐시, 다시 생성 가능한 변환 결과는 CacheDirectory= 쪽이 더 맞다.

실무적으로 이 구분이 중요한 이유는 운영자가 백업, 정리, 마이그레이션 정책을 다르게 잡기 쉽기 때문이다. systemd가 데이터 의미까지 자동 판정해 주는 것은 아니므로, 어떤 파일이 "없어져도 다시 만들 수 있는가"를 기준으로 나누는 편이 안전하다.

LogsDirectory=는 저널을 써도 필요할까?

항상 필요한 것은 아니다. 서비스 로그를 전부 journald로만 보내고 파일 기반 로그를 남기지 않는다면 LogsDirectory=가 없어도 된다. 반대로 애플리케이션이 자체 로그 파일을 굴리거나 외부 도구가 특정 로그 경로를 요구한다면 전용 로그 디렉터리를 unit에서 함께 관리할 수 있다.

LogsDirectory=는 "로그는 무조건 여기로 보내라"는 지시어가 아니라, 서비스가 직접 사용할 로그 디렉터리를 표준 위치에 준비해 주는 수단으로 보는 편이 맞다.

tmpfiles.d 대신 이 지시어를 권장할까?

tmpfiles.d 문서는 서비스 전용 런타임 디렉터리라면 RuntimeDirectory=를, /var/lib, /var/cache, /var/log, /etc 아래 디렉터리라면 각각 StateDirectory=, CacheDirectory=, LogsDirectory=, ConfigurationDirectory=를 쓰는 편이 낫다고 설명한다.

이유는 두 가지다. 첫째, 설정이 service unit 한 곳에 모여 관리가 단순해진다. 둘째, 디렉터리 수명이 서비스 수명과 직접 연결되어 tmpfiles.d 규칙이 먼저 실행됐는지 따로 신경 쓸 필요가 줄어든다.

반대로 파일 수명이 특정 서비스와 독립적이거나 더 복잡한 생성 규칙, 정리 정책, ACL, 속성 조정이 필요하다면 tmpfiles.d가 더 적합할 수 있다.

systemd는 디렉터리를 어떻게 준비할까?

공식 문서에 따르면 이 지시어들을 사용하면 systemd는 필요한 부모 디렉터리까지 함께 만들고, ConfigurationDirectory=를 제외한 가장 안쪽 디렉터리의 소유자와 그룹을 User=, Group=에 맞춘다. 이미 디렉터리가 존재하지만 소유자가 다르면, 그 아래 파일과 디렉터리까지 재귀적으로 소유권을 바꿀 수 있다.

또한 각 지시어에는 StateDirectoryMode=처럼 접근 권한 모드를 지정하는 짝 옵션이 있고 기본값은 0755다. 따라서 민감한 상태 파일을 둘 예정이라면 기본 권한이 적절한지 별도로 확인해야 한다.

이 지시어들은 필요한 마운트 유닛에 대한 Requires=After= 의존성도 자동으로 추가한다. 즉 지정한 경로가 올라오기 전에 서비스를 시작하지 않도록 기본 의존성이 보강된다.

DynamicUser=를 쓰면 무엇이 달라질까?

DynamicUser=가 켜져 있으면 StateDirectory=, CacheDirectory=, LogsDirectory=의 실제 host 쪽 생성 위치가 각각 /var/lib/private, /var/cache/private, /var/log/private 아래로 바뀐다. systemd 문서는 이것이 동적 UID 재사용으로 인한 접근 문제를 줄이기 위한 처리라고 설명한다.

다만 서비스 내부에서 보이는 경로는 여전히 /var/lib, /var/cache, /var/log 아래처럼 보이도록 심볼릭 링크가 만들어진다. 그래서 애플리케이션 입장에서는 표준 경로를 계속 쓰되, host에서는 더 안전한 실제 저장 위치를 쓰는 구조다.

선택 기준을 한 번에 정리하면?

상황 우선 검토할 지시어 이유
서비스 중지나 재부팅 후 사라져도 되는 소켓, PID, lock 파일 RuntimeDirectory= /run 기반이고 수명이 서비스 실행과 묶인다
백업하거나 마이그레이션해야 하는 영속 상태 데이터 StateDirectory= /var/lib 아래 지속 상태 저장에 맞다
지워져도 다시 만들 수 있는 캐시 데이터 CacheDirectory= 캐시 성격을 운영 정책에서 분리하기 쉽다
애플리케이션이 직접 파일 로그를 관리해야 함 LogsDirectory= /var/log 아래 전용 경로를 unit에서 준비한다
파일 수명이 서비스와 무관하거나 복잡한 tmpfiles 규칙이 필요함 tmpfiles.d 서비스 단위 지시어보다 더 유연한 규칙을 줄 수 있다

자주 헷갈리는 질문

Q. StateDirectory=를 쓰면 백업 대상이라는 뜻까지 systemd가 보장할까?

아니다. systemd는 표준 위치와 생성, 소유권, 권한을 관리할 뿐 백업 정책까지 정의하지 않는다. 다만 /var/lib 아래의 상태 데이터라는 의미를 운영자가 읽기 쉬워진다는 점이 실무상 장점이다.

Q. RuntimeDirectory=만으로 재시작 중 파일을 반드시 유지할 수 있을까?

기본값은 아니다. 기본 동작은 서비스 중지 시 제거 쪽이므로, 재시작 중 유지가 필요하면 RuntimeDirectoryPreserve=restart 또는 yes를 검토해야 한다.

Q. 이미 경로가 존재하면 그냥 재사용만 할까?

그렇게 단정할 수 없다. 공식 문서는 소유자나 그룹이 다르면 하위 파일과 디렉터리까지 재귀적으로 소유권을 조정할 수 있다고 설명한다. 운영 중인 기존 디렉터리에 붙일 때는 이 동작을 먼저 확인하는 편이 안전하다.

정리

systemd의 디렉터리 지시어는 "어디에 만들까"보다 "어떤 수명의 데이터인가"를 명확히 하게 만드는 도구다. 일시적 런타임 상태는 RuntimeDirectory=, 영속 상태는 StateDirectory=, 재생성 가능한 캐시는 CacheDirectory=, 파일 로그는 LogsDirectory=로 나누면 공식 문서의 의도와 가장 잘 맞는다.

2026년 6월 9일 기준 systemd 문서를 따르면 서비스 전용 디렉터리라면 먼저 unit 지시어로 해결할 수 있는지 보고, 서비스 수명과 독립적인 규칙이 필요할 때만 tmpfiles.d로 넘어가는 순서가 무난하다.

참고 자료

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사