본문 바로가기

서버 리뷰/홈 서버

[Troubleshooting] Apache Guacamole와 PostgreSQL Docker 연동 시 "password is an empty string" 에러 해결

728x90

1. 개요

Proxmox 환경의 LXC 컨테이너 위에서 Docker Compose를 이용해 Apache Guacamole와 PostgreSQL을 연동 구축하던 중, 네트워크 연결은 정상임에도 불구하고 웹 화면에서 내부 데이터베이스 연결 에러가 지속적으로 발생하는 문제를 겪었습니다.

이 글에서는 해당 문제의 근본적인 원인과 이를 깔끔하게 해결하는 과정을 정리합니다.

2. 증상 및 로그 확인

2.1. 네트워크 상태 점검

가장 먼저 Proxmox 데이터센터 방화벽과 로컬 네트워크 환경 설정을 점검했습니다. PowerShell의 Test-NetConnection 명령어를 통해 Guacamole 웹 포트(8080)로의 통신이 정상적으로 이루어짐(TcpTestSucceeded : True)을 확인했습니다. 즉, 네트워크 브릿지나 포트 차단 문제는 아니었습니다.

2.2. Guacamole 웹 컨테이너 에러 로그

docker logs guac-web 명령어로 로그를 확인한 결과, 다음과 같은 치명적인 에러가 발생하고 있었습니다.

Plaintext
 
Cause: org.postgresql.util.PSQLException: The server requested SCRAM-based authentication, but the password is an empty string.

데이터베이스는 SCRAM 방식의 인증을 요구하는데, 정작 연결을 시도하는 웹 서버 측에서 비밀번호로 '빈 문자열(empty string)'을 전달하고 있다는 내용입니다.

3. 원인 분석

이 문제는 크게 두 가지 설정 오류가 겹쳐서 발생했습니다.

3.1. 공식 환경 변수명 오타 (핵심 원인)

docker-compose.yml 파일 작성 시 공식 문서의 환경 변수명을 정확히 인지하지 못한 것이 가장 큰 원인이었습니다.

  • PostgreSQL 컨테이너(DB): POSTGRES_ 접두사를 사용합니다. (예: POSTGRES_PASSWORD)
  • Guacamole 컨테이너(Web): 반드시 POSTGRESQL_ 접두사를 사용해야 합니다. (예: POSTGRESQL_PASSWORD)

Guacamole 웹 컨테이너의 환경 변수에도 DB와 동일하게 POSTGRES_PASSWORD라고 기입하는 바람에, 애플리케이션이 변수를 인식하지 못하고 비밀번호를 빈 값으로 치환하여 DB에 전달한 것입니다.

3.2. 제거되지 않은 좀비 데이터

오류를 인지하고 docker compose down과 디렉토리 삭제를 시도했으나, Docker가 root 권한으로 생성한 초기화 불량 데이터가 호스트의 바인딩 디렉토리에 계속 남아있었습니다. 이로 인해 설정을 고치고 재실행해도 PostgreSQL은 기존 데이터베이스가 존재한다고 판단하여 잘못 설정된 초기 상태를 그대로 유지했습니다.

4. 해결 방법

환경 변수명을 정확히 수정하고, 로컬 디렉토리 바인딩 대신 Docker 자체 관리 볼륨을 사용하여 간섭 없는 클린 설치를 진행합니다.

4.1. docker-compose.yml 수정

기존 내용을 지우고 아래 내용으로 교체합니다. Guacamole 서비스의 환경 변수에 QL이 포함되어 있는지 반드시 확인해야 합니다.

YAML
 
services:
  guacd:
    image: guacamole/guacd:latest
    container_name: guacd
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro

  postgres:
    image: postgres:15-alpine
    container_name: guac-db
    restart: always
    environment:
      # DB 컨테이너는 POSTGRES_ 사용
      - POSTGRES_DB=guacamole_db
      - POSTGRES_USER=guac_user
      - POSTGRES_PASSWORD=설정할_비밀번호
    volumes:
      - guac_db_volume:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro

  guacamole:
    image: guacamole/guacamole:latest
    container_name: guac-web
    restart: always
    depends_on:
      - guacd
      - postgres
    ports:
      - "8080:8080"
    environment:
      - GUACD_HOSTNAME=guacd
      # 웹 컨테이너는 반드시 POSTGRESQL_ 사용
      - POSTGRESQL_HOSTNAME=guac-db
      - POSTGRESQL_DATABASE=guacamole_db
      - POSTGRESQL_USER=guac_user
      - POSTGRESQL_PASSWORD=설정할_비밀번호
    volumes:
      - /etc/localtime:/etc/localtime:ro

# Docker 자체 관리 볼륨 선언
volumes:
  guac_db_volume:

4.2. 기존 컨테이너 및 데이터 초기화

Bash
 
# 1. 기존 컨테이너 완전 중지 및 삭제
docker compose down

# 2. 새로운 볼륨을 적용하여 DB 컨테이너만 먼저 실행
docker compose up -d postgres

# 3. DB 초기화를 위해 10초 대기 후 초기화 SQL 임포트
sleep 10
cat initdb.sql | docker exec -i guac-db psql -U guac_user -d guacamole_db

# 4. 전체 서비스 실행
docker compose up -d

5. 결론

Docker Compose를 이용해 여러 컨테이너를 연동할 때는 각 공식 이미지에서 요구하는 정확한 환경 변수명(Prefix 포함)을 공식 문서를 통해 꼼꼼하게 확인하는 습관이 필요합니다. 또한, 설정이 꼬여서 알 수 없는 에러가 지속될 때는 로컬 파일 시스템에 남은 좀비 데이터를 의심하고, Docker 관리 볼륨으로 깨끗하게 격리하여 새로 구성하는 것이 가장 확실한 돌파구입니다.

반응형