이 시리즈는 Zabbix 7.0을 처음부터 구축하고, 실제 인프라(Proxmox, iLO, iDRAC, OPNsense, TrueNAS)를 모니터링하기까지의 전 과정을 다룹니다. 설치 튜토리얼보다는 실제 운영 중 겪은 문제와 판단 근거에 초점을 맞춥니다.
1편에서는 Docker Compose로 Zabbix 서버를 구성하는 방법을 다룹니다.
왜 Docker로 설치하는가
Zabbix를 패키지로 직접 설치하면 OS 의존성, DB 버전 충돌, 업그레이드 부담이 따릅니다. Docker로 구성하면 몇 가지 실용적인 이점이 있습니다.
- 버전 고정:
zabbix/zabbix-server-mysql:7.0-ubuntu-latest처럼 명확하게 버전을 지정 - 환경 분리: DB, 서버, 웹, 에이전트가 각각 독립된 컨테이너로 격리
- 이식성: docker-compose.yml 하나로 동일한 환경을 재현 가능
- 로그 관리: Docker 로그 드라이버로 통합 관리
다만 zabbix_sender를 외부(cron 스크립트 등)에서 호출할 때 docker exec를 경유해야 한다는 점은 설계 시 고려해야 합니다. 이 부분은 2편에서 다시 다룹니다.
디렉토리 구조 설계
설치 전에 데이터 경로를 먼저 결정합니다. 실행 파일과 데이터를 분리하는 것이 핵심입니다.
/app/zabbix/ # 실행 설정 (docker-compose, env)
├── docker-compose.yml
├── env/
│ ├── db.env
│ ├── server.env
│ └── web.env
/data/zabbix/ # 영구 데이터
├── scripts/ # 외부 스크립트 (externalscripts, alertscripts)
├── snmptraps/
├── export/
├── enc/
├── mibs/
└── modules/
/data/mariadb/ # DB 데이터
├── data/
├── log/
└── backup/
/app은 설정과 코드, /data는 상태 데이터로 분리하면 백업 범위가 명확해집니다.
docker-compose.yml 구성
전체 구성은 다섯 개 서비스입니다.
services:
mariadb:
image: mariadb:${MARIADB_VERSION}
container_name: zabbix-mariadb
restart: unless-stopped
env_file:
- ./env/db.env
volumes:
- /data/mariadb/data:/var/lib/mysql
- /data/mariadb/log:/var/log/mysql
- /data/mariadb/backup:/backup
- /app/mariadb/my.cnf:/etc/mysql/conf.d/zabbix.cnf:ro
networks:
- zabbix-net
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_bin
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
zabbix-server:
image: zabbix/zabbix-server-mysql:${ZABBIX_VERSION}
container_name: zabbix-server
hostname: zabbix-server
restart: unless-stopped
env_file:
- ./env/server.env
ports:
- "10051:10051"
volumes:
- /data/zabbix/scripts:/usr/lib/zabbix/externalscripts:ro
- /data/zabbix/scripts:/usr/lib/zabbix/alertscripts:ro
- /data/zabbix/snmptraps:/var/lib/zabbix/snmptraps:rw
- /data/zabbix/export:/var/lib/zabbix/export:rw
networks:
- zabbix-net
depends_on:
mariadb:
condition: service_healthy
zabbix-web:
image: zabbix/zabbix-web-nginx-mysql:${ZABBIX_VERSION}
container_name: zabbix-web
restart: unless-stopped
env_file:
- ./env/web.env
ports:
- "8080:8080"
- "8443:8443"
networks:
- zabbix-net
depends_on:
- zabbix-server
zabbix-agent2:
image: zabbix/zabbix-agent2:${ZABBIX_VERSION}
container_name: zabbix-agent2
restart: unless-stopped
environment:
ZBX_HOSTNAME: zabbix-server
ZBX_SERVER_HOST: zabbix-server
ZBX_ACTIVE_ALLOW: "true"
privileged: true
pid: host
networks:
- zabbix-net
depends_on:
- zabbix-server
zabbix-java-gateway:
image: zabbix/zabbix-java-gateway:${ZABBIX_VERSION}
container_name: zabbix-java-gateway
restart: unless-stopped
networks:
- zabbix-net
networks:
zabbix-net:
driver: bridge
몇 가지 설계 포인트를 짚겠습니다.
depends_on: condition: service_healthy
MariaDB가 실제로 준비된 뒤에 zabbix-server가 기동되도록 healthcheck를 조건으로 걸었습니다. 단순 depends_on만 쓰면 DB 컨테이너가 시작됐지만 아직 초기화 중일 때 서버가 연결 실패로 종료될 수 있습니다.
scripts 볼륨을 두 경로에 마운트
/data/zabbix/scripts를 externalscripts와 alertscripts 양쪽에 모두 마운트합니다. 스크립트를 한 곳에서 관리하면서 두 가지 용도로 모두 쓸 수 있습니다.
zabbix-agent2의 privileged: true + pid: host
에이전트가 호스트 프로세스 정보를 수집하려면 필요합니다. 보안이 엄격한 환경이라면 대신 Passive 모드로 외부 에이전트를 별도 설치하는 방법을 고려하세요.
환경 변수 파일
민감한 설정은 .env 파일로 분리합니다.
env/db.env
MYSQL_DATABASE=zabbix
MYSQL_USER=zabbix
MYSQL_PASSWORD=your_db_password
MYSQL_ROOT_PASSWORD=your_root_password
env/server.env
DB_SERVER_HOST=mariadb
DB_SERVER_PORT=3306
MYSQL_DATABASE=zabbix
MYSQL_USER=zabbix
MYSQL_PASSWORD=your_db_password
ZBX_JAVAGATEWAY=zabbix-java-gateway
ZBX_JAVAGATEWAY_ENABLE=true
ZBX_JAVAGATEWAYPORT=10052
ZBX_STARTJAVAPOLLERS=5
ZBX_ENABLE_SNMP_TRAPS=true
env/web.env
DB_SERVER_HOST=mariadb
DB_SERVER_PORT=3306
MYSQL_DATABASE=zabbix
MYSQL_USER=zabbix
MYSQL_PASSWORD=your_db_password
ZBX_SERVER_HOST=zabbix-server
ZBX_SERVER_PORT=10051
PHP_TZ=Asia/Seoul
PHP_TZ=Asia/Seoul은 웹 UI의 시간대를 결정합니다. 빠뜨리면 UTC로 표시되어 알림 시간이 9시간 어긋납니다.
버전 관리 (.env)
docker-compose.yml에서 ${ZABBIX_VERSION} 같은 변수를 쓰면 버전 관리가 편합니다. 같은 디렉토리에 .env 파일을 만들어 두세요.
ZABBIX_VERSION=7.0-ubuntu-latest
MARIADB_VERSION=10.11
업그레이드할 때 이 파일만 수정하고 docker compose pull && docker compose up -d를 실행하면 됩니다.
기동 및 확인
# 디렉토리 생성
mkdir -p /data/zabbix/{scripts,snmptraps,export,enc,mibs,modules}
mkdir -p /data/mariadb/{data,log,backup}
# 기동
cd /app/zabbix
docker compose up -d
# 상태 확인
docker compose ps
초기 기동 시 MariaDB가 스키마를 초기화하는 데 약 1~2분 걸립니다. zabbix-server 컨테이너 로그에서 진행 상황을 확인할 수 있습니다.
docker logs -f zabbix-server
server #0 started [main process] 메시지가 보이면 정상 기동입니다.
초기 웹 설정
브라우저에서 http://서버IP:8080 으로 접속합니다.
초기 계정
- ID:
Admin - PW:
zabbix

로그인 직후 반드시 비밀번호를 변경하세요.

언어 및 타임존 설정
Zabbix 7.0은 웹 UI에서 개별 사용자의 언어와 타임존을 설정합니다.

시스템 전체 기본값은 별도 설정합니다.

호스트 그룹 설계
모니터링 대상이 여러 환경(개발/운영)에 걸쳐 있다면 호스트 그룹으로 분리하는 것이 나중에 권한 관리와 알림 분리에 유리합니다. 이 시리즈에서는 아래 두 그룹을 기준으로 구성합니다.
| 그룹 | 용도 |
|---|---|
| DEV | 개발/테스트 환경 |
| PRD | 운영 환경 |

그룹 생성 후에는 사용자 권한과 알림 Action에서 이 그룹을 필터로 활용하게 됩니다. 이 부분은 2편에서 다룹니다.
마치며
이번 편에서는 Docker Compose로 Zabbix 7.0 서버를 구성하는 전체 구조를 살펴봤습니다.
핵심 포인트를 정리하면:
- MariaDB healthcheck를
depends_on조건으로 연결해 초기화 타이밍 문제 방지 - scripts 볼륨을 externalscripts와 alertscripts 양쪽에 마운트
PHP_TZ=Asia/Seoul설정으로 시간대 일치- 데이터 경로(
/data)와 설정 경로(/app)를 분리하여 백업 단순화
다음 편에서는 Slack Webhook 알림 연동과 DEV/PRD 채널 분리, 그리고 알림이 실제로 동작하지 않는 흔한 실수(미디어 타입 비활성화)를 다룹니다.