지난 편에서 두 번째 워드프레스 스택을 만들었습니다. 빌드는 성공했는데 사이트에 들어가니 이 화면이 떴습니다.
Error establishing a database connection
앞 편에서 말한 대로 초기화 중일 수 있으니 30초를 기다렸습니다. 그대로였습니다. 5분이 지나도 그대로였습니다.
결론부터 말씀드리면 폴더 권한 문제였습니다. 그런데 권한을 아무리 풀어줘도 해결되지 않는 종류의 것이었습니다.
워드프레스는 멀쩡한데 DB만 죽었습니다
먼저 두 폴더를 확인했습니다. 워드프레스 파일이 들어갈 폴더와 데이터베이스가 들어갈 폴더입니다.
워드프레스 폴더에는 파일이 21개 정상적으로 풀려 있었습니다. 데이터베이스 폴더는 완전히 비어 있었습니다.
이게 결정적인 단서였습니다. 같은 곳에 같은 방식으로 만든 두 폴더인데 한쪽만 실패했다면, 폴더 자체보다 쓰는 쪽이 다르다는 뜻이니까요.
Container Manager에서 데이터베이스 컨테이너의 로그를 열었습니다. 거기 답이 있었습니다.
[ERROR] mariadbd: Can't create/write to file './ddl_recovery.log'
(Errcode: 13 "Permission denied")
[Warning] Can't create test file '/var/lib/mysql/....lower-test'
(Errcode: 13 "Permission denied")
권한 거부였습니다.
권한을 다 열어줬는데도 거부당했습니다
권한 문제라니 간단해 보였습니다. 폴더 권한을 전부 열고 소유자도 데이터베이스가 쓰는 계정으로 맞췄습니다.
확인해 보니 이렇게 나왔습니다.
drwxrwxrwx+ 1 999 synopkgs 0 db_data
권한은 rwxrwxrwx, 소유자는 999. 데이터베이스가 쓰는 계정 번호가 999니까 맞습니다. 누가 봐도 쓸 수 있어야 합니다.
그런데도 계속 거부당했습니다.
여기서 한참 헤맸습니다. 권한 숫자만 계속 들여다보고 있었거든요.
범인은 권한 뒤의 플러스 기호였습니다
정상 동작하던 기존 블로그의 폴더와 나란히 놓고 보니 차이가 보였습니다.
| 폴더 | 권한 표시 | 결과 |
|---|---|---|
| 기존 블로그 (정상) | drwxrwxrwx |
DB 정상 동작 |
| 새 블로그 (실패) | drwxrwxrwx+ |
권한 거부 |
권한 끝에 붙은 + 하나가 차이의 전부였습니다.
이 기호는 그 폴더에 시놀로지 ACL이 걸려 있다는 표시입니다. ACL은 시놀로지가 별도로 관리하는 접근 권한 목록입니다. 그리고 ACL이 걸려 있으면 일반 권한 숫자보다 ACL이 우선합니다.
즉 777로 보이는 건 껍데기였고, 실제 판단은 ACL이 하고 있었던 겁니다. 그리고 컨테이너 안의 데이터베이스 계정은 DSM에 등록된 사용자가 아니라 ACL 목록에 없으니 거부당했습니다.
왜 이 폴더에만 ACL이 붙었나
제가 그 폴더를 윈도우에서 네트워크 드라이브로 만들었기 때문입니다.
NAS 공유폴더를 윈도우에 연결해두고 거기서 폴더를 만들면, 공유폴더에 설정된 ACL을 그대로 물려받습니다. 반면 기존 블로그의 폴더는 다른 경로로 만들어져서 ACL이 없었습니다.
같은 NAS, 같은 공유폴더 안인데 만든 방법 하나로 갈린 겁니다.
워드프레스는 왜 멀쩡했을까
이 부분이 이 문제의 가장 헷갈리는 지점입니다. 두 폴더 모두 ACL이 걸려 있었는데 워드프레스만 파일을 잘 썼거든요.
답은 로그에 있었습니다. 데이터베이스 로그를 위로 올려 보면 시작 부분에 이런 줄이 있습니다.
[Entrypoint]: Switching to dedicated user 'mysql'
데이터베이스는 권한을 낮춘 뒤에 파일을 씁니다. 보안을 위해 최고 권한을 버리고 전용 계정으로 내려간 다음 작업하는 겁니다. 그 계정이 ACL 목록에 없으니 막혔습니다.
반면 워드프레스 이미지는 파일을 풀 때 최고 권한 상태에서 작업합니다. ACL을 그냥 통과합니다.
같은 폴더 조건인데 한쪽은 권한을 낮췄고 한쪽은 안 낮췄다는 차이가 결과를 갈랐습니다.
해결 — 데이터베이스만 도커 볼륨으로
ACL을 지우는 방법도 있지만, 더 확실한 건 ACL이 닿지 않는 곳에 데이터베이스를 두는 것입니다. 도커가 자체적으로 관리하는 볼륨을 쓰면 됩니다.
컴포즈 파일에서 이렇게 바꿉니다.
myblog_db:
volumes:
- myblog_db_data:/var/lib/mysql # 폴더 대신 도커 볼륨
volumes:
myblog_db_data:
워드프레스 폴더는 그대로 뒀습니다. 최고 권한으로 쓰니 문제가 없고, 설정 파일을 직접 열어 고칠 일이 있어서 파일로 보이는 편이 낫습니다.
다시 빌드하니 데이터베이스가 정상적으로 초기화됐고, 사이트가 열렸습니다.
백업 방식이 달라집니다
도커 볼륨을 쓰면 데이터베이스가 폴더로 보이지 않습니다. 파일을 복사하는 방식으로는 백업할 수 없다는 뜻입니다.
대신 덤프를 뜹니다.
docker exec myblog_db mariadb-dump -u root -p"비밀번호" DB이름 > backup.sql
사실 이게 원래 정석입니다. 돌아가고 있는 데이터베이스의 파일을 그대로 복사하는 건 원래 안전하지 않습니다. 복사하는 도중에 내용이 바뀌면 깨진 백업이 됩니다. 폴더로 보이지 않게 된 덕분에 오히려 제대로 된 방법을 쓰게 된 셈입니다.
정리
Errcode: 13 Permission denied인데 권한이777이라면 권한 끝의+를 확인하십시오. 시놀로지 ACL이 걸려 있다는 표시입니다.- ACL이 있으면 권한 숫자보다 ACL이 우선합니다. 숫자를 아무리 열어도 소용없습니다.
- 윈도우에서 네트워크 드라이브로 만든 폴더는 ACL을 물려받습니다.
- 워드프레스는 되는데 데이터베이스만 죽는 이유는, 데이터베이스가 권한을 낮춘 뒤 파일을 쓰기 때문입니다.
- 데이터베이스는 도커 볼륨을 쓰면 이 문제를 통째로 피할 수 있습니다. 워드프레스 폴더는 그대로 둬도 됩니다.
- 도커 볼륨을 쓰면 백업은 파일 복사가 아니라 덤프로 합니다. 원래 그게 맞는 방법이기도 합니다.
NAS 복구·재구축 연재 — 전 11편 중 9편
1막 · 잃음
2막 · 다시 지음
3막 · 그 위에 블로그를 올림
- 나스 한 대로 블로그 두 개, 병목은 CPU가 아니었습니다
- 도커로 워드프레스 스택 분리하기, 멀티사이트를 안 쓴 이유
- MariaDB가 Permission denied로 죽는다, 시놀로지 ACL 함정 — 지금 읽는 글
- 포트포워딩 없이 도메인 붙이기, 관리자 화면은 숨기기
- 같은 일을 두 번 겪지 않으려고, RAID는 백업이 아닙니다