리눅스 서버를 운영하다 보면 프로그램 파일은 /opt에 있고, PostgreSQL이나 Docker의 데이터는 /var/lib에 있으며, 로그는 /var/log에 저장되는 모습을 자주 볼 수 있습니다.
세 디렉터리는 모두 애플리케이션과 관련되어 있지만 역할은 서로 다릅니다. Filesystem Hierarchy Standard(FHS)를 기준으로 보면 /opt는 추가 애플리케이션의 정적 파일을 설치하는 영역이고, /var/lib는 프로그램이 실행되는 동안 변경하면서 다음 실행까지 유지해야 하는 상태 정보 영역이며, /var/log는 시스템과 애플리케이션의 로그를 보관하는 영역입니다.
핵심적으로 다음과 같이 구분할 수 있습니다.
- /opt
- 추가 애플리케이션을 독립된 디렉터리 형태로 설치할 때 사용하는 위치입니다.
- 주로 실행 파일, 라이브러리, 정적 리소스가 들어갑니다.
- 예:
/opt/myapp/bin,/opt/google/...
- /var/lib
- 일반적인 시스템 서비스나 애플리케이션이 실행하면서 생성하고, 재시작 후에도 계속 사용하는 데이터를 저장합니다.
- 예: PostgreSQL 데이터, Docker 데이터, Gitea 운영 데이터
- /var/log
- 시스템과 애플리케이션의 실행 기록과 오류, 접속 기록 등을 저장합니다.
- 예: PostgreSQL 로그, nginx 로그, systemd journal
- /etc
- 시스템과 애플리케이션의 설정 파일을 저장합니다.
- 예:
postgresql.conf,nginx.conf
- /var/opt
- FHS 기준으로
/opt에 설치된 프로그램이 실행하면서 생성하고 계속 사용하는 데이터를 저장하는 위치입니다. - 예:
/var/opt/myapp
- FHS 기준으로
/var/lib 에 저장되는 데이터
FHS에서는 /var/lib를 Variable state information을 저장하는 위치로 정의합니다.
여기서 state information은 프로그램이 실행되는 동안 수정하며, 특정 시스템의 현재 상태를 다음 실행에서도 이어가기 위해 필요한 데이터입니다. 일반적으로 재부팅 이후에도 유효해야 하며, 로그나 spool 데이터와는 구분됩니다.
따라서 /var/lib를 단순히 "영구 데이터 저장소"라고 표현하기보다는 애플리케이션이나 시스템이 관리하는 지속적인 상태 데이터 저장소 또는 간단히 설치된 애플리케이션이 사용하는 데이터 라고 정의할 수 있습니다.
대표적인 예는 다음과 같습니다.
| 경로 예 | 역할 |
|---|---|
/var/lib/postgresql/ |
PostgreSQL 패키지가 사용하는 데이터 영역 |
/var/lib/docker/ |
Docker daemon의 기본 데이터 루트 |
/var/lib/dpkg/ |
Debian 패키지 관리 상태 정보 |
/var/lib/apt/ |
APT가 관리하는 상태 정보 |
/var/lib/systemd/ |
systemd가 유지하는 일부 상태 정보 |
/var/lib/gitea/ |
설치 방식에 따라 Gitea의 저장소·첨부 파일·세션 등 운영 데이터 |
Ubuntu에서 PGDG 또는 Debian 계열 패키지 방식으로 PostgreSQL을 설치했다면 데이터 디렉터리는 일반적으로 다음과 같은 구조를 사용합니다.
/var/lib/postgresql/<버전>/<클러스터명>예를 들어 PostgreSQL 18의 기본 클러스터가 main이라면 다음과 같은 경로를 볼 수 있습니다.
/var/lib/postgresql/18/main실제 PostgreSQL 서버가 어느 데이터 디렉터리를 사용 중인지 확인하려면 파일 경로를 추측하기보다 PostgreSQL에 직접 조회하는 것이 정확합니다.
sudo -u postgres psql -c "SHOW data_directory;"Docker Engine도 Linux에서 지속 데이터를 기본적으로 /var/lib/docker에 저장합니다.
docker info --format '{{.DockerRootDir}}'일반적인 출력 예:
/var/lib/docker다만 Docker의 저장 경로는 data-root 설정으로 변경할 수 있습니다. 또한 최근 Docker Engine에서 containerd image store를 사용하는 구성이라면 이미지 콘텐츠와 snapshot 일부는 /var/lib/containerd에 저장될 수 있으므로, 모든 Docker 데이터가 항상 /var/lib/docker 하나에만 있다고 단정하면 안 됩니다.
/var/lib내부 파일은 해당 프로그램이 직접 관리하는 경우가 많습니다. 데이터베이스 파일이나 Docker 내부 파일을 서비스 중 임의로 수정하거나 삭제하면 데이터 손상이나 서비스 장애가 발생할 수 있으므로, 삭제·이동은 해당 프로그램의 공식 절차에 따라 수행해야 합니다.
APT와 관련해서도 상태 정보와 캐시는 구분해야 합니다.
/var/lib/apt → APT 상태 정보
/var/lib/dpkg → 설치된 Debian 패키지 상태 정보
/var/cache/apt → 다시 내려받을 수 있는 패키지 캐시즉, 캐시 데이터까지 모두 /var/lib에 저장되는 것은 아닙니다. FHS에서는 재생성 가능한 캐시를 /var/cache에 두도록 구분합니다.
/opt, /var/opt, /var/lib 의 관계
/var/lib와 /var/opt는 모두 프로그램이 실행하면서 만들고 계속 사용하는 데이터를 저장할 수 있기 때문에 처음 보면 거의 같은 용도로 보입니다.
실제로 데이터의 성격은 비슷합니다. 차이는 FHS에서 어느 프로그램의 데이터를 위한 위치로 구분했느냐에 있습니다.
/var/lib는 일반적인 시스템 서비스와 애플리케이션이 계속 사용하는 데이터를 위한 위치입니다.
예를 들어 Ubuntu에서 APT로 PostgreSQL을 설치하면 일반적으로 다음처럼 구성됩니다.
/usr/lib/postgresql/18/ → PostgreSQL 프로그램 파일
/etc/postgresql/18/main/ → PostgreSQL 설정
/var/lib/postgresql/18/main/ → PostgreSQL 데이터
/var/log/postgresql/ → PostgreSQL 로그반면 FHS에서 /opt는 추가 애플리케이션을 설치하기 위한 위치입니다.
어떤 프로그램을 다음과 같이 /opt/myapp에 설치했다고 가정할 수 있습니다.
/opt/myapp/
├── bin/
├── lib/
└── share/FHS는 이 프로그램의 설정과 계속 변경되는 데이터를 다음과 같이 분리할 수 있도록 경로를 정의합니다.
/opt/myapp/ → 프로그램 본체
/etc/opt/myapp/ → 프로그램 설정
/var/opt/myapp/ → 프로그램이 실행하면서 생성하고 계속 사용하는 데이터
/var/log/myapp/ → 프로그램 로그를 별도로 기록하는 경우 사용할 수 있는 일반적인 로그 위치여기서 /var/opt/myapp에 들어가는 데이터는 임시 데이터라는 뜻이 아닙니다.
예를 들어 프로그램에 따라 다음과 같은 데이터가 들어갈 수 있습니다.
/var/opt/myapp/
├── data/
├── jobs/
├── index/
├── state.db
└── queue/이 파일들은 프로그램을 종료하거나 서버를 재부팅했다고 해서 사라져야 하는 파일이 아니라, 다음 실행에서도 계속 사용할 수 있는 데이터입니다.
따라서 가장 쉽게 구분하면 다음과 같습니다.
/var/lib
→ 일반적인 시스템 서비스와 애플리케이션이 계속 사용하는 데이터
/var/opt
→ /opt에 설치된 프로그램이 계속 사용하는 데이터중요한 점은 이것이 설치 프로그램이 반드시 지켜야 하는 강제 규칙은 아니라는 것입니다.
예를 들어 PostgreSQL 자체를 /opt/postgresql에 직접 설치하더라도 실제 데이터 디렉터리를 /var/lib/postgresql, /var/opt/postgresql, /data/postgresql 등으로 지정할 수 있습니다.
/opt/postgresql
→ PostgreSQL 프로그램
/var/lib/postgresql
→ PostgreSQL 데이터이런 구성도 기술적으로 가능합니다.
PostgreSQL은 프로그램 설치 경로와 데이터 저장 경로가 분리되어 있으며, 실제 데이터 경로는 initdb -D 또는 PostgreSQL 설정으로 결정할 수 있습니다.
현재 PostgreSQL이 실제 사용하는 데이터 디렉터리는 다음과 같이 확인할 수 있습니다.
sudo -u postgres psql -c "SHOW data_directory;"따라서 /var/lib와 /var/opt는 다음처럼 이해하는 것이 좋습니다.
/var/lib와/var/opt는 데이터의 종류가 완전히 다른 것이 아니라, Linux 파일시스템을 일관되게 구성하기 위해 FHS에서 용도를 구분해 둔 경로입니다. 실제 저장 위치는 각 애플리케이션과 관리자의 설정이 우선합니다.
배포판 패키지와 /opt 설치 프로그램 비교
Ubuntu의 일반적인 배포판 패키지와 /opt에 설치한 추가 프로그램을 비교하면 다음과 같습니다.
배포판 패키지로 설치한 프로그램
/usr/bin 또는 /usr/lib/<app> → 프로그램
/etc/<app> → 설정
/var/lib/<app> → 프로그램 데이터
/var/log/<app> → 로그/opt에 설치한 추가 프로그램
/opt/<app> → 프로그램
/etc/opt/<app> → 설정
/var/opt/<app> → 프로그램 데이터
/var/log/<app> → 로그를 파일로 분리해서 관리하는 경우의 일반적인 위치이 비교는 이해를 돕기 위한 전형적인 구조입니다.
/usr/local은 APT 같은 배포판 패키지 관리자가 사용하는 위치라고 보면 안 됩니다. /usr/local은 시스템 관리자가 직접 설치한 프로그램을 배포판이 관리하는 /usr 영역과 분리하기 위해 사용하는 영역입니다.
예를 들어 관리자가 직접 설치한 실행 파일은 다음과 같은 위치를 사용할 수 있습니다.
/usr/local/bin/myapp이 경우에도 데이터가 반드시 /var/opt로 가는 것은 아닙니다. 프로그램의 정책에 따라 /var/lib/myapp, 별도의 데이터 디스크, 사용자 홈 디렉터리 등을 사용할 수 있습니다.
즉 설치 방법만으로 데이터 위치를 결정하는 것이 아니라, 프로그램의 패키징 방식과 설정을 함께 확인해야 합니다.
/var/log 에 저장되는 데이터
FHS에서 /var/log는 로그 파일과 로그 디렉터리를 저장하는 영역입니다.
시스템이나 애플리케이션이 어떤 작업을 수행했는지, 어떤 오류가 발생했는지, 누가 접속했는지와 같은 기록을 저장합니다.
대표적인 예는 다음과 같습니다.
| 경로 예 | 역할 |
|---|---|
/var/log/syslog |
Ubuntu 계열에서 볼 수 있는 시스템 로그 중 하나 |
/var/log/auth.log |
Ubuntu에서 SSH, sudo 등 인증 관련 로그 |
/var/log/nginx/ |
nginx access/error log |
/var/log/postgresql/ |
Debian/Ubuntu PostgreSQL 패키지 구성에서 사용하는 로그 디렉터리 |
/var/log/apt/ |
APT 설치·업데이트 관련 로그 |
/var/log/journal/ |
systemd-journald의 영구 journal 저장 경로로 사용할 수 있는 위치 |
systemd-journald는 항상 /var/log/journal에 로그를 저장하는 것은 아닙니다.
journald.conf의 Storage= 설정에 따라 영구 저장 또는 휘발성 저장 방식이 달라질 수 있습니다.
/var/log/journal → 영구 journal 저장
/run/log/journal → 휘발성 journal 저장현재 journal 사용량은 다음 명령으로 확인할 수 있습니다.
journalctl --disk-usagePostgreSQL도 로그 위치를 무조건 /var/log/postgresql이라고 단정해서는 안 됩니다. Debian/Ubuntu 패키지 구성에서는 해당 경로를 흔히 사용하지만, PostgreSQL 설정의 logging_collector, log_directory 값이나 systemd journal 사용 여부에 따라 달라질 수 있습니다.
설정값은 다음과 같이 확인할 수 있습니다.
sudo -u postgres psql -c "SHOW logging_collector;"
sudo -u postgres psql -c "SHOW log_directory;"systemd 서비스 로그를 확인할 때는 다음 명령도 사용할 수 있습니다.
journalctl -u postgresql애플리케이션 로그는 지속적으로 증가할 수 있으므로 운영 서버에서는 디스크 사용량과 보존 정책을 함께 관리해야 합니다.
sudo du -sh /var/log/*텍스트 로그를 파일로 기록하는 서비스라면 logrotate를 이용해 오래된 로그를 회전·압축·삭제하도록 구성하는 경우가 많습니다. systemd journal은 자체 보존 및 용량 제한 기능을 사용합니다.
서버에서 실제 경로 확인하기
리눅스 디렉터리의 용도를 이해하는 것도 중요하지만, 운영 중인 서버에서는 해당 서비스가 실제로 어느 경로를 사용하고 있는지 확인하는 것이 더 중요합니다.
전체 용량을 간단히 확인하려면 다음 명령을 사용할 수 있습니다.
sudo du -sh /opt /var/lib /var/log 2>/dev/null각 디렉터리의 하위 항목별 사용량은 다음과 같이 확인할 수 있습니다.
sudo du -sh /var/lib/* 2>/dev/null | sort -h
sudo du -sh /var/log/* 2>/dev/null | sort -h
sudo du -sh /opt/* 2>/dev/null | sort -h디렉터리가 어느 파일시스템에 있는지도 확인할 수 있습니다.
findmnt /opt
findmnt /var/lib
findmnt /var/logPostgreSQL, Docker처럼 데이터가 크게 증가할 수 있는 서비스는 기본 경로만 믿기보다 애플리케이션 설정을 직접 확인하는 것이 안전합니다.
# PostgreSQL 실제 데이터 디렉터리
sudo -u postgres psql -c "SHOW data_directory;"
# Docker 실제 데이터 루트
docker info --format '{{.DockerRootDir}}'세 디렉터리의 관계를 PostgreSQL 같은 서버 프로그램에 적용하면 다음과 같이 이해할 수 있습니다.
실행 파일 → /usr/bin, /usr/lib 또는 /opt 등
설정 파일 → /etc
상태/DB 데이터 → /var/lib 또는 별도 데이터 디스크
로그 → /var/log 또는 systemd journal예를 들어 Ubuntu의 PostgreSQL 패키지 구성에서는 보통 다음과 같은 형태가 됩니다.
/usr/lib/postgresql/18/bin/ → PostgreSQL 실제 바이너리
/usr/bin/psql → psql 실행을 위한 사용자 명령 경로
/etc/postgresql/18/main/ → PostgreSQL 설정
/var/lib/postgresql/18/main/ → PostgreSQL 데이터
/var/log/postgresql/ → 패키지 구성에 따른 PostgreSQL 로그이 구조를 알고 있으면 /opt 아래에 PostgreSQL 관련 디렉터리가 보인다고 해서 그것만으로 PostgreSQL이 정상 설치되어 있다고 판단하거나, /var/lib/postgresql이 있다고 해서 현재 PostgreSQL 서비스가 그 경로를 실제 사용 중이라고 단정하는 실수를 줄일 수 있습니다.
정리
/opt, /var/lib, /var/log는 모두 애플리케이션과 관련된 파일을 저장할 수 있지만 목적이 다릅니다.
/opt는 추가 애플리케이션의 실행 파일과 정적 리소스를 설치하는 위치입니다. /var/lib는 프로그램이나 시스템이 실행 중 변경하며 다음 실행까지 유지해야 하는 상태 정보를 저장합니다. /var/log는 시스템과 애플리케이션의 실행 기록을 저장합니다.
간단히 기억하면 다음과 같습니다.
/usr/lib 또는 /usr/bin
→ 배포판 패키지로 설치한 프로그램 파일이 주로 위치
/opt
→ 별도로 설치하는 추가 프로그램 본체
/etc
→ 설정
/var/lib
→ 일반적인 서비스와 프로그램이 계속 사용하는 데이터
/var/opt
→ /opt에 설치된 프로그램이 계속 사용하는 데이터
/var/log
→ 로그/var/lib와 /var/opt의 데이터 성격이 완전히 다른 것은 아닙니다. 둘 다 프로그램이 계속 사용하는 데이터를 저장할 수 있습니다. /var/opt가 특별한 이유는 FHS에서 /opt에 설치된 프로그램의 데이터 영역으로 구분해 놓았다는 점입니다.
로그는 설치 방식에 따라 /var/lib와 /var/opt처럼 크게 나뉘는 개념이 아닙니다. 파일 로그로 관리한다면 일반적으로 /var/log 아래에서 서비스별 디렉터리를 사용하는 구조를 많이 볼 수 있으며, systemd journal이나 애플리케이션 자체 설정을 사용하는 경우도 있습니다.
실제 운영 서버에서는 이 기본 원칙에 더해 애플리케이션 설정을 직접 확인해야 합니다. PostgreSQL의 data_directory, Docker의 DockerRootDir처럼 실제 사용 경로를 조회하면 심볼릭 링크, 별도 디스크 마운트, 사용자 지정 경로 때문에 생기는 혼동을 줄일 수 있습니다.
참고 자료
- Linux Foundation Filesystem Hierarchy Standard 3.0: https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html
- FHS
/opt정의: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html - FHS
/var/lib정의: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s08.html - FHS
/var/log정의: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s10.html - FHS
/var/opt정의: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s12.html - FHS
/var/cache정의: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s05.html - Docker daemon data directory: https://docs.docker.com/engine/daemon/
- Docker
dockerdreference: https://docs.docker.com/reference/cli/dockerd/ - systemd
journald.conf: https://www.freedesktop.org/software/systemd/man/latest/journald.conf.html - PostgreSQL 공식 문서: https://www.postgresql.org/docs/
'운영체제(OS) > Linux' 카테고리의 다른 글
| Ubuntu 24.04 AppImage SUID sandbox 실행 오류 해결 (1) | 2026.07.18 |
|---|---|
| 리눅스 /usr/bin과 /usr/local/bin의 차이 (0) | 2026.07.17 |
| Ubuntu 24.04에서 AppImage 파일 실행하기 (0) | 2026.07.09 |
| [Ubuntu 24.04] PostgreSQL 18 + Gitea 설치 및 설정 가이드 (0) | 2026.07.03 |
| [Ubuntu 24.04] Gitea + PostgreSQL 완전 삭제 및 확인 방법 (0) | 2026.07.01 |
댓글