-
[Linux]Nginx Proxy Manager(NPM)에서 DB 오류 날때 해결 방법HomeLAB/Linux 2025. 1. 24. 16:24
오라클 클라우드를 사용하면서 Nginx Proxy Manager(NPM)를 잘 사용하고 있습니다. 홈랩 쪽은 OPNsense에서 HAProxy를 리버스 프록시로 사용하지만, 오라클 클라우드는 ARM에 CLI로 conf 파일을 설정해야 하는 게 좀 귀찮아서 NPM을 Docker로 설치해서 사용하고 있습니다. 올리고 싶은 서비스의 docker-compose.yaml 파일에 대충 네트워크만 맞춰주고 컨테이너 올려주고 웹에서 "딸깍" 몇 번만 하면 그리 어렵지 않게 설정할 수 있어 많은 사람들이 사용하는 리버스 프록시 프로그램입니다.
Let's Encrypt 인증서가 6일 이내에 만료된다는 이메일 - 현재는 해결했다. NPM에서는 자동으로 인증서를 갱신하기에 딱히 신경 쓸 필요는 없습니다. 그런데 얼마 전에 Let's Encrypt 측에서 인증서가 곧 만료된다는 메일이 왔는데, 왜 이런 메일이 왔는가 싶어서 확인해 봤습니다. 확인해 보니 오랜 기간 도커 이미지의 업데이트를 못해서 컨테이너 내부에 Certbot 패키지 버전을 사용할 수 없게 되면서 인증서를 재발급받을 수 없게 되는 것이 원인인 것으로 결론을 내렸습니다. 그런데 작년에 최신 버전으로 업데이트를 시도했다가 DB 오류로 실패하고 원복 했는데, 이제 인증서를 갱신하지 못하면 잘 돌아가던 서비스를 전부 사용할 수 없게 되니 어쩔 수 없이 업데이트를 미룰 수 없게 되었습니다.
그 시도 중에 하나를 해결하면 문제가 하나 생겨서 2가지 문제를 해결했다. 검색해 보니까 선발대가 Github에 잘 정리해 놔서 생각보다 빠르게 해결할 수 있었습니다.
0. 시스템 사양
오라클 클라우드 Ampere A1
CPU: ARM 4 Core vCPU
RAM: 24GB
OS: Ubuntu 22.04 LTS
1. 기존의 NPM의 docker-compose.yaml 구성
NPM은 역사와 전통의 X86 시스템뿐만이 아니라 ARM 시스템도 지원합니다. yaml 파일이 좀 길어서 접어놨는데 잘못된 파일이라서 볼 필요는 없습니다. 나중에 수정된 yaml 파일이 나오니 이 부분은 구경만 하시면 되겠습니다.
NPM 서비스는 메인 NPM과 MariaDB로 구동됩니다.
더보기version: "3.1" services: npm: image: 'jc21/nginx-proxy-manager:${NPM_VERSION}' container_name: NPM_main restart: unless-stopped ports: - '80:80' # http - '443:443' # https - '81:81' # management page environment: DB_MYSQL_HOST: "npm_db" DB_MYSQL_PORT: 3306 DB_MYSQL_USER: ${NPM_USER} DB_MYSQL_PASSWORD: ${NPM_PASSWD} DB_MYSQL_NAME: ${NPM_DBNAME} volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt networks: - artemis_net - npm_net depends_on: - npm_db npm_db: image: 'jc21/mariadb-aria:${DB_VERSION}' container_name: NPM_DB tty: true expose: - 3306 restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${NPM_ROOT_PASSWD} MYSQL_DATABASE: ${NPM_DBNAME} MYSQL_USER: ${NPM_USER} MYSQL_PASSWORD: ${NPM_PASSWD} MARIADB_AUTO_UPGRADE: 1 volumes: - ./data/mysql:/var/lib/mysql networks: - npm_net networks: artemis_net: external: true npm_net: external: true
.env 파일에 나머지 구성을 저장했습니다.
2. 문제 상황 해결 방법
1) npm 'Can\'t create table `NPM_DB`.`migrations`
기존의 yaml 파일에서 NPM과 MariaDB의 버전을 최신 버전으로 업데이트하기 위해 버전 부분만 "latest"로 지정하고 docker copmose pull && docker compose up으로 도커 컨테이너를 실행했을 때 만난 문제입니다. 상세 내역은 아래의 이미지를 참고해 주세요.
이런 로그가 NPM에서 나타나게 되는데, 이 오류는 NPM 웹은 열리나 제대로 된 인증 정보를 넣더라도 로그인이 불가능한 문제가 생깁니다. DB를 마이그레이션 할 수 없는 문제인 것으로 파악했습니다. 해결 방법을 찾아보니 이 부분은 DB가 버전 마이그레이션을 못하는 게 아니라 DB 파일에 대한 권한 문제인 것이라며 권한을 컨테이너 내부에서 수정하는 방법을 사용했습니다.
하지만 그 방법을 사용한 결과 해결은 했으나 컨테이너를 새로 시작하는 순간 문제가 다시 발생했습니다. 그래서 해결 방법에 관해서 좀 더 살펴본 결과 아예 DB 디렉터리를 NPM 디렉터리에서 분리해야 한다고 했습니다. 즉, 제 docker-compose.yaml 파일에는 NPM 컨테이너에 할당되어 있는 디렉터리 경로 내부에 DB 컨테이너의 디렉터리가 포함되어 있었고 DB 컨테이너가 실행되면서 DB 파일의 권한을 수정한다고 해도 depends_on으로 NPM이 다시 그 DB 파일의 권한을 수정해 버렸던 것으로 보입니다.
제가 예전에 어떤 글을 참고해서 docker-compose.yaml 파일을 작성했는지는 잘 모르겠지만, 혹시나 싶어 확인해 본 공식 문서에서는 확실히 분리가 되어있었습니다. 아마 그때 당시에는 잘 되었으니 그냥 사용한 것으로 보입니다.
해결 방법은 그리 어렵지 않습니다.
https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1499#issuecomment-1494593464
NPM 컨테이너에 할당되어 있던 디렉터리 내부에 DB 컨테이너에 할당된 디렉터리가 있는데 그 디렉터리를 외부로 이동시키고 docker-compose.yaml에서도 그 부분을 수정해 줬습니다.
디렉터리 이동
# 도커 컨테이너에서 생성된 디렉터리라서 root 권한으로 실행해야함. sudo mv data/mysql ./
NPM 컨테이너 볼륨 할당
volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data:/data - ./letsencrypt:/etc/letsencrypt
MariaDB 컨테이너 볼륨
volumes: - ./mysql:/var/lib/mysql
2) npm Incorrect definition of table mysql.column_stats: expected column 'hist_type' at position 9 to have type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB'), found type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB').
DB 파일의 권한 문제를 해결했지만 아직 문제는 남아있었습니다. 로그인은 잘 되나 로그인할 때 DB에 로그가 쌓이기 시작했습니다. 상세 내역은 아래 이미지를 참고해 주세요.
이런 로그가 DB에서 나타나게 되는데, 이 오류는 작동 자체는 제대로 되는데 로그인할 때마다 로그가 계속 쌓이게 되는 부분도 있고 억지로 돌아가는 느낌이라 더 큰 문제가 생기기 전에 잡으면 좋을 것 같았습니다. 해결 방법을 찾아보니 DB 버전이 꽤나 구버전이라 그런지 DB를 수동으로 업그레이드시켜줘야 하는 것으로 보입니다.
해결 방법은 어렵지 않습니다.
https://github.com/NginxProxyManager/nginx-proxy-manager/issues/3428#issuecomment-1885421270
실행되어 있는 DB 컨테이너에 명령어를 날려서 DB를 수동으로 업그레이드시키면 됩니다.
DB는 중요하니까 꼭 백업을 해놔야 합니다.
# DB는 중요하니까 꼭 백업을 해놓고 시도하세요. # 명령어 docker exec -it [DB 컨테이너의 이름] mysql_upgrade -u root -p [DB 이름] # 제 시스템의 경우 docker exec -it NPM_DB mysql_upgrade -u root -p npm_db
3. 결론
제가 겪었던 문제의 경우에는 대부분 DB에 관련된 문제였습니다. 이 부분을 좀 더 잘 살피고 제대로 했다면 좋았을 텐데 해결 방법을 찾기가 그리 어렵지 않았고 해결이 100% 안 되는 경우도 가끔 있는데 이 문제는 완전하게 해결할 수 있어서 다행이었습니다.
최종 수정된 docker-compose.yaml 파일
더보기version: "3.1" services: npm: image: 'jc21/nginx-proxy-manager:latest' container_name: NPM_main restart: unless-stopped ports: - '80:80' # http - '443:443' # https - '81:81' # management page environment: DB_MYSQL_HOST: "npm_db" DB_MYSQL_PORT: 3306 DB_MYSQL_USER: ${NPM_USER} DB_MYSQL_PASSWORD: ${NPM_PASSWD} DB_MYSQL_NAME: ${NPM_DBNAME} volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro networks: - artemis_net - npm_net depends_on: - npm_db npm_db: image: 'jc21/mariadb-aria:latest' container_name: NPM_DB tty: true expose: - 3306 restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${NPM_ROOT_PASSWD} MYSQL_DATABASE: ${NPM_DBNAME} MYSQL_USER: ${NPM_USER} MYSQL_PASSWORD: ${NPM_PASSWD} MARIADB_AUTO_UPGRADE: 1 volumes: - ./mysql:/var/lib/mysql networks: - npm_net networks: artemis_net: external: true npm_net: external: true
.env 파일은 별도 작성되었습니다.
레퍼런스
https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1499
https://github.com/NginxProxyManager/nginx-proxy-manager/issues/3428
'HomeLAB > Linux' 카테고리의 다른 글
[Linux] 도커로 Cloudflare Tunnel + Nginx Proxy Manager + Authelia 구성으로 포트 공개하지 않고 안전하게 외부로 서비스 공개하기 (1) 2025.02.16 [Linux]리눅스에서 NVIDIA GPU 전력 제한하기 (0) 2024.12.03 [Linux]리눅스에서 NVIDIA GPU 팬 속도 설정하기 (1) 2024.12.02