## [[Docker]] 데몬 전역 설정으로 팀 개발 환경 통일하기 {#sec-b2e039a7f45a} 로컬에서든 서버에서든 Docker를 쓰다 보면, 프로젝트마다 `docker-compose.yml`에 같은 설정을 계속 복붙하게 됩니다. * DNS를 항상 `1.1.1.1`, `8.8.8.8`로 맞춘다거나 * 로그 드라이버를 `json-file` + `max-size=10m`으로 고정한다거나 * 프록시, insecure registry, 기본 네트워크 대역 등… 이런 것들은 **컨테이너 개별 설정이 아니라 “호스트 전체 기본값”** 으로 빼버리면 훨씬 관리가 쉽습니다. 그 역할을 하는 게 바로 **Docker 데몬 전역 설정(`daemon.json`)** 입니다. 아래에서: * 어떤 파일을 * 어디에 만들고 * 어떻게 작성해야 하는지 * 어떤 상황에서 어떤 개발자/팀에게 유용한지 를 정리해보겠습니다.
## 1. Docker 데몬 설정 방식 두 가지 {#sec-9c4e8fa25a41} Docker 데몬(`dockerd`)은 크게 두 가지 방식으로 설정할 수 있습니다. 1. **JSON 설정 파일(`daemon.json`) 사용** ← *권장* 2. `dockerd` 실행 시 **CLI 플래그**로 옵션 전달 둘을 섞어 쓸 수는 있지만, **같은 옵션을 둘 다에서 지정하면 데몬이 아예 뜨지 않습니다.** 예를 들어 `--log-driver` 플래그와 `daemon.json` 모두에 로그 드라이버를 넣어버리면 Docker가 시작 단계에서 에러를 내고 죽습니다. 팀/서버 환경 통일을 위해서는 보통: > “가능한 한 `daemon.json`에 다 모으고, 플래그는 최소한으로만” 하는 걸 추천합니다. ## 2. `daemon.json` 위치 정리 {#sec-97a08839a2de} 파일의 위치는 **`/etc/docker/daemon.json`** 입니다. 물론 리눅스 기준입니다. Docker 를 리눅스 이외의 환경에서 사용하는 분들이 있을지 모르겠습니다만, 제가 리눅스에서만 사용하는 관계로 사실 다른 OS는 잘 모릅니다만, OS별 기본 위치를 한 번에 보기 좋게 표로 정리하면 다음과 같습니다: | 환경 | 기본 경로 | 비고 | | --- | ----- | --- | | Linux (일반 설치) | `/etc/docker/daemon.json` | 가장 흔한 케이스 | | Linux (snap으로 설치한 Docker) | `/var/snap/docker/current/config/daemon.json` | Ubuntu snap 패키지 | | Windows Server / Docker Engine | `C:\ProgramData\Docker\config\daemon.json` | | | Docker Desktop (Mac / Windows) | `~/.docker/daemon.json` | | * 이 파일은 **기본으로 없을 수 있으므로, 없으면 직접 생성**해서 사용하면 됩니다. ## 3. 기본 사용 패턴: “파일 만들고 → 데몬 재시작” {#sec-875278239b12} Linux 기준으로 일반적인 워크플로우는 이렇습니다. 1. **`daemon.json` 작성/수정** ```json { "dns": ["1.1.1.1", "8.8.8.8"], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } } ``` 1. 설정 파일이 유효한지 **미리 검증** ```bash sudo dockerd --validate --config-file=/etc/docker/daemon.json # configuration OK 가 나오면 정상 :contentReference[oaicite:7]{index=7} ``` 1. Docker 데몬 **재시작** ```bash sudo systemctl restart docker ``` 이제부터 새로 뜨는 컨테이너는 별도 설정이 없는 한 이 전역 설정들을 **기본값으로 상속** 받습니다. ## 4. 주요설정 : DNS 서버를 전역으로 고정하기 {#sec-c284419e45cd} ### 4.1 왜 DNS를 전역으로? {#sec-78011cf35f17} 컨테이너가 “이상하게 외부 API를 못 찾는다” “내부 도메인이 안 풀린다” 같은 문제를 자주 만난다면, 대부분 **호스트의 DNS 설정/환경에 의존**하고 있기 때문입니다. 예를 들어: * 팀 전체가 Cloudflare DNS( `1.1.1.1` )를 쓰고 싶다 * 회사 내부 DNS 서버를 통해서만 열리는 엔드포인트가 있다 이런 경우 **매 프로젝트마다 `docker-compose.yml`에 `dns:`를 넣기보다는**, 아예 Docker 데몬 단계에서 통일하는 게 훨씬 편합니다. ### 4.2 설정 예시 (`daemon.json`) {#sec-2a85a418cbea} ```json { "dns": ["1.1.1.1", "8.8.8.8"] } ``` 기존 `daemon.json`이 있다면, 루트 `{ ... }` 안에 `"dns": [...]` 항목을 추가하면 됩니다. > ⚠️ **주의:** DNS 설정은 컨테이너 안에서 `/etc/resolv.conf`에 반영됩니다. 이미 떠 있는 컨테이너에는 바로 적용되지 않고, **새로 띄우는 컨테이너부터 적용**됩니다. ## 5. 주요설정 2 – 로깅 드라이버 & 옵션 전역 설정 {#sec-fe09c43b83b1} 컨테이너 로그는 기본적으로 `json-file` 드라이버를 통해 `/var/lib/docker/containers/...` 아래에 쌓입니다. 이를 전역에서 바꾸면: * 로그 포맷 * 로그 저장 위치 * 로그 로테이션 정책 을 **컨테이너 전체에 일괄 적용**할 수 있습니다. ### 5.1 기본 json-file 드라이버 + 로테이션 {#sec-26c5fb9056b5} 가장 흔한 패턴은 “그냥 `json-file` 쓰되, 디스크 안 터지게 로테이션 설정”입니다. ```json { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "5" } } ``` 이렇게 해두면: * 컨테이너당 로그 파일 크기가 최대 `10MB`이고 * 최대 `5개`까지만 유지되고 * 초과분은 자동 삭제됩니다. ### 5.2 중앙 로그 수집용 드라이버 (fluentd, journald 등) {#sec-e7499afd6f5d} 플랫폼 팀/인프라 팀이라면, 모든 컨테이너의 로그를 **중앙 로깅 시스템**에 보내고 싶을 때가 많습니다. 예를 들어 Fluentd를 사용한다면: ```json { "log-driver": "fluentd", "log-opts": { "fluentd-address": "localhost:24224", "tag": "{{.Name}}" } } ``` 이렇게 해두면, 별도의 `docker run --log-driver=...` 없이도 모든 컨테이너의 로그가 자동으로 Fluentd로 전송됩니다. 개인적으로는 **`journald` 드라이버**도 꽤 좋아합니다. systemd 기반 리눅스 환경이라면 애플리케이션 로그와 Docker 컨테이너 로그를 모두 journald 한 군데로 모아서, `journalctl`만으로 조회·필터링·보존 정책을 통일할 수 있기 때문입니다. `journald`를 전역 로그 드라이버로 쓰고 싶다면 예를 들어 이렇게 설정할 수 있습니다: ```json { "log-driver": "journald", "log-opts": { "tag": "{{.Name}}" } } ``` 여기서 `tag`를 컨테이너 이름으로 쓰고 있기 때문에: * `journalctl -f | grep {container_name}` 형태로 **실시간 로그를 빠르게 훑어볼 수 있고** * `--since "10m ago"` 같은 옵션을 조합해서 **특정 시점 이후 로그만 볼 수도 있으며** * `journalctl -f -t {container_name}`처럼 `-t` 옵션(태그/식별자 기준)을 써서 **특정 컨테이너 로그만 딱 집어서** 볼 수도 있습니다. 물론 `journalctl -u docker.service` 같이 유닛 단위로 보는 것도 가능하지만, 컨테이너 이름 기준으로 필터링하는 게 더 직관적이고, 타이핑도 짧아서 실무에선 훨씬 자주 쓰게 됩니다. ### 5.3 Compose / `docker run`과의 관계 {#sec-8d284e8a0dfd} * **전역 `log-driver` + `log-opts`** 는 “기본값” 역할 * 개별 컨테이너에서 `logging:` (Compose) 혹은 `--log-driver`, `--log-opt`(CLI)를 지정하면 **그 컨테이너만 override** 전략적으로: * 공통값은 daemon.json에 * 특수한 서비스만 개별 override 하는 구성을 추천합니다. *** ## 6. 주요설정 3 – 프록시, insecure registry 등 전역 네트워크 설정 {#sec-bc2f973bcb11} 전역 설정에서 자주 쓰이는 또 다른 옵션들이 있습니다. ### 6.1 프록시 설정 {#sec-753696ea7a1f} 사내 프록시를 통해서만 외부에 나갈 수 있는 경우, 매번 환경변수를 넣기보다 **데몬 수준에서 프록시를 설정**할 수 있습니다. ```json { "proxies": { "http-proxy": "http://proxy.example.com:3128", "https-proxy": "http://proxy.example.com:3128", "no-proxy": "localhost,127.0.0.1,.corp.example.com" } } ``` 이렇게 하면 Docker 데몬이 이미지를 풀 때나, 빌드 시 네트워크를 사용할 때 이 프록시 설정을 따라갑니다. ### 6.2 insecure registry {#sec-fe7d1c14ce8d} TLS가 없는 레지스트리를 꼭 써야 하는 상황이라면(내부 개발용 등): ```json { "insecure-registries": ["my-registry.local:5000"] } ``` 보안상 위험할 수 있으니, **내부 테스트 환경에서만** 사용하도록 주의해야 합니다. *** ## 7. 주요설정 4 – 기본 네트워크 대역, 스토리지 드라이버 등 {#sec-efc333459aa9} ### 7.1 기본 bridge 네트워크 대역 커스터마이징 {#sec-00d891d2b55d} VPN이나 사내 네트워크와 IP가 겹치는 것을 피하고 싶을 때: ```json { "default-address-pools": [ { "base": "10.20.0.0/16", "size": 24 } ] } ``` 이렇게 하면 Docker가 새 bridge 네트워크를 만들 때 `10.20.x.0/24` 대역을 사용합니다. ### 7.2 스토리지 드라이버 강제 {#sec-04d867ec1442} 리눅스 배포판에 따라 기본 스토리지 드라이버가 달라질 수 있습니다. 팀에서 `overlay2`만 쓰기로 했다면: ```json { "storage-driver": "overlay2" } ``` > 실제 지원 가능한 스토리지 드라이버는 OS/커널에 따라 다르므로, `dockerd` 문서와 배포판 가이드를 꼭 확인해야 합니다. *** 무슨 말씀인지 바로 이해했습니다. "누구(Persona)"에게 집중하는 순간 글이 매뉴얼처럼 딱딱해지고, 흔한 AI 말투가 되어버리죠. 인간적인 경험과 "이런 짜증 나는 상황"에 초점을 맞춰서, 공감대를 툭 건드리는 느낌으로 다시 써봤습니다. *** ## 8. 이런 '데자뷔'를 겪고 있다면 도입하세요 {#sec-e2c8a9ca03d5} 굳이 복잡한 인프라 사정을 몰라도 좋습니다. 만약 최근에 아래와 같은 경험을 한 적이 있다면, 지금이 바로 `daemon.json`을 만져야 할 타이밍입니다. * \*\*새 프로젝트 시작할 때마다 `docker-compose.yml`을 뒤적이며 로그 설정을 복붙하고 있다:\*\*어제 짰던 코드에서 `max-size`, `max-file` 설정을 찾아와서 또다시 붙여넣고 있다면, 이미 귀한 시간을 낭비하고 계신 겁니다. 한 번만 전역으로 빼두면 모든 컨테이너가 알아서 '다이어트' 모드로 시작됩니다. * **사무실에서는 잘 되던 컨테이너가 카페나 VPN 환경만 가면 인터넷 먹통이 된다:**"내 로컬에선 됐는데?"의 전형적인 케이스죠. 호스트의 DNS 설정에 휘둘리지 않고, 어떤 네트워크 환경에서도 내 컨테이너가 일관되게 외부와 소통하게 만들고 싶다면 전역 DNS 고정이 정답입니다. * \*\*수많은 서버 노드의 설정을 하나하나 맞추느라 정신이 혼미하다:\*\*서버마다 Docker 설정이 미묘하게 달라서 생기는 '유령 버그' 때문에 삽질하고 계신가요? `daemon.json` 파일 하나만 배포하면 모든 서버가 똑같은 규칙으로 운영됩니다. *** > 반복되는 설정이 귀찮아졌거나, 환경 변화에 따른 삽질이 지긋지긋해졌을 때가 바로 이 설정을 도입할 최적의 순간입니다. ## 정리 {#sec-857c80428df3} * Docker의 전역 기본값은 **`daemon.json`** 에서 관리한다. * 위치는 보통 `/etc/docker/daemon.json` * 대표적인 전역 설정 예: * DNS: `"dns": ["1.1.1.1", "8.8.8.8"]` * 로그 드라이버: `"log-driver": "json-file"`, `"log-opts": {...}` * 프록시, insecure registry, 기본 네트워크 대역, 스토리지 드라이버… * 전역 설정은 반복되는 설정과 많은 노드를 다양한 환경에서 배포할 때 유용합니다. `docker-compose.yml`이나 `docker run`에 똑같은 옵션을 계속 쓰고 있다면, **이제 한 번쯤은 `daemon.json`으로 끌어올릴 타이밍**일지도 모릅니다. ![image of docker daemon json setting](https://blog.mikihands.com/media/editor_temp/6/00f7dbc8-f71e-485b-b9a9-e9514af1ba73.png)