chore(docker): DB 메모리 한도를 1g · 공유 버퍼를 256MB 로 올린다(14단계 검색 색인)

1만 통 측정에서 색인 찾기는 표 · 색인이 메모리에 있을 때만 1초 안이었고 캐시가 비면
3~8배 느렸다(사용자 결정 2026-11-05). 8GB 서버의 한도 합은 6.65GB · 백업 때 7.65GB 다.
복원 연습 때는 8.15GB 로 8GB 를 넘는다 — 사실만 적고 다룰 방법은 따로 정한다.
mail/README 에 운영에 올리는 차례(db 만 먼저 up · 한도 · shared_buffers 확인)를 적었다.
docker 스킬의 연습 주기를 기준 문서(README — 한 달에 한 번)에 맞췄다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 22:00:44 +09:00
parent 0fc5735959
commit d57e6bfe6c
3 changed files with 22 additions and 6 deletions
+9 -4
View File
@@ -826,10 +826,15 @@ sudo docker exec "${PROJECT_NAME}-backend" node -e "const s=require('net').conne
| clamav-updater (freshclam) | 1g | 수십 MB | 처음 기동(서명 전체를 받아 읽어 봄) 0.7GB, 평소 갱신은 daily 만 |
| mail | 1g | 0.1~0.3GB (큰 메일 뒤 0.4GB 남짓까지 쌓인다 — 2026-11-03) | 메일 한 통을 받을 때 그 크기 × 5.5 쯤 더 — 받는 한도 50MiB(setup)면 +0.3GB 남짓. 운영에서 106.4MB 한 통이 1g 를 넘었다(2026-11-03 — 개발 104MB 는 984/1024MiB · 서버 B 는 이전하는 동안만 2g, [큰 메일](#큰-메일-운영-2026-11-03) · [받는 메일 크기](#엔진-한도)) |
| backend | 1g | 0.3~0.5GB | 조각 · 받기는 스트림이라 파일 크기와 상관없다 |
| db · frontend · mail-resolver | 512m · 512m · 128m | 작다 | |
| **합** | **6.15GB** | 2.5~3GB | 나머지 1.8GB 남짓을 커널 · dockerd · 페이지 캐시가 쓴다 |
| restic (백업 — 13단계, compose 밖) | 1g | 돌 때만 — 매일 03:30 몇 분 | 0.63GB (데이터 1.2GB — 2026-10-31 MinIO). 그때는 합이 7.15GB — 사용이 적은 새벽이라 둔다. 복원 연습은 엔진 1g · DB 512m 를 더 띄운다(한 달에 한 번 — 낮에 하지 않는다) |
| db | 1g (14단계에 512m 에서) | 0.16GB 안팎(색인을 채우는 동안도) · 찾기 시험 동안 최대 0.24GB (2026-11-05 · 그때는 공유 버퍼 128MB · 한도 512m) | 공유 버퍼(`shared_buffers` 256MB — compose 의 `command`)가 차고 그 위로 표 · 색인의 페이지 캐시(한도 안에서 줄여 쓴다). 메일 검색은 이것이 메모리에 있을 때만 1초 안이다 — 캐시가 비면 3~8배(1만 통 · 색인 121MB) |
| frontend · mail-resolver | 512m · 128m | 작다 | |
| **합** | **6.65GB** | 2.5~3GB (14단계 전 — db 는 공유 버퍼가 찬 만큼 는다) | 나머지 1.3GB 남짓을 커널 · dockerd · 페이지 캐시가 쓴다 |
| restic (백업 — 13단계, compose 밖) | 1g | 돌 때만 — 매일 03:30 몇 분 | 0.63GB (데이터 1.2GB — 2026-10-31 MinIO). 그때는 합이 7.65GB — 사용이 적은 새벽이라 둔다. 복원 연습은 엔진 1g · DB 512m(스크립트에 고정 — compose 의 db 한도를 따르지 않는다)를 더 띄워 합이 8.15GB 로 8GB 를 넘는다(14단계부터 — 그 전은 7.65GB. 한 달에 한 번 — 낮에 하지 않는다) |
- **db 1g · 공유 버퍼 256MB 를 운영에 올릴 때**(14단계 배포와 함께 — 한 번): 다음 `up` 이 db 를 다시 만든다 — 수 초 멈추고(데이터는 `DB_DATA_DIR` 그대로) 떠 있는 backend 는 다시 붙는다(그동안의 요청은 실패).
퇴근 뒤 · 백업(03:30) · 복원 연습을 피해 `git pull` → `sudo docker compose --env-file .env.production up -d db`(db 만 먼저) → `sudo docker stats --no-stream "${PROJECT_NAME}-db"` 의 한도 `1GiB` ·
`sudo docker exec "${PROJECT_NAME}-db" sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Atc "show shared_buffers"'` 가 `256MB` → 14단계의 `up -d --build`.
mail 이 이전 때의 2g(`docker update`)로 남아 있으면 먼저 되돌린다([큰 메일](#큰-메일-운영-2026-11-03) 3. — 그대로면 합이 7.65GB · 백업 때 8.65GB).
- **ClamAV 의 `ConcurrentDatabaseReload` 를 켜지 않는다**(기본은 켬) — 켜면 서명을 다시 읽는 동안(하루 몇 번) 두 벌(2GB 남짓)을 들어 2g 한도에서 죽는다.
한도를 올려 켜려면 합이 8GB 를 넘지 않는지 다시 본다.
- 서명은 해마다 는다 — `docker stats` 의 clamav 가 한도의 80%(1.6GB)를 넘으면 한도를 올리거나(합을 다시 본다) 서버를 키운다.
@@ -1722,7 +1727,7 @@ sudo rm -f /root/imapsync/mailcow-master.pass /root/imapsync/migration.pass
`[변경]` · `[유지]` 줄은 저장한 값이고, 엔진에 걸린 값은 리로드 뒤의 이 `[확인]` 줄이다(리로드가 실패하면 엔진은 옛 한도로 받는다).
3. 메모리를 compose 의 값으로 — `sudo docker update --memory 1g --memory-swap 2g <PROJECT_NAME>-mail`.
받는 한도를 낮추기 전에 1g 로 돌리면 바깥 큰 메일 한 통에 엔진이 죽을 수 있다([엔진 한도](#엔진-한도) "받는 메일 크기"). 올린 채 두면 엔진에 2g 가 들고, [메모리 예산](#메모리-예산)의 합이 7.15GB, 백업이 도는 동안은 8.15GB 로 8GB 를 넘는다.
받는 한도를 낮추기 전에 1g 로 돌리면 바깥 큰 메일 한 통에 엔진이 죽을 수 있다([엔진 한도](#엔진-한도) "받는 메일 크기"). 올린 채 두면 엔진에 2g 가 들고, [메모리 예산](#메모리-예산)의 합이 7.65GB, 백업이 도는 동안은 8.65GB 로 8GB 를 넘는다(14단계의 db 1g 부터 — 그 전은 7.15 · 8.15GB).
#### 개발에서 확인한 것 (imapsync — 2026-11-02)