공통 명령

rtCloud 컨테이너를 관리하기 위해 이 명령들을 정기적으로 사용하세요. docker-compose.production.yml이 있는 디렉토리에서 실행합니다.

  # 모든 컨테이너의 상태 및 상태 확인
docker compose -f docker-compose.production.yml ps

# 실시간 로그 보기 (모든 서비스)
docker compose -f docker-compose.production.yml logs -f

# 앱만의 로그 보기
docker compose -f docker-compose.production.yml logs -f rtcloud

# 단일 컨테이너 재시작
docker compose -f docker-compose.production.yml restart rtcloud

# 모든 서비스 중지
docker compose -f docker-compose.production.yml down

# 모든 서비스 시작
docker compose -f docker-compose.production.yml up -d

# 앱 컨테이너 내부에서 셸 열기
docker compose -f docker-compose.production.yml exec rtcloud bash
  

업그레이드

rtCloud 업데이트는 새 Docker 이미지 태그로 배포됩니다. 업그레이드는 최신 이미지를 가져와 앱 컨테이너를 재생성합니다. 데이터베이스 마이그레이션은 시작 시 자동으로 실행됩니다.

1. 최신 이미지 가져오기:

  docker compose -f docker-compose.production.yml pull
  

2. 앱 컨테이너 재생성:

  docker compose -f docker-compose.production.yml up -d
  

Docker는 이미지가 변경된 컨테이너만 교체합니다. MySQL 컨테이너와 모든 명명된 볼륨은 영향을 받지 않습니다.

버전 고정

latest 대신 특정 버전으로 업그레이드하려면 .envRTCLOUD_IMAGE를 업데이트합니다:

  RTCLOUD_IMAGE=rtawebteam/rta-smartsurvey:1.2.3
  

그런 다음 위와 같이 docker compose pullup -d를 실행합니다.

다운그레이드

데이터베이스 마이그레이션은 되돌릴 수 없으므로 다운그레이드는 일반적으로 권장되지 않습니다. 다운그레이드가 필요한 경우 업그레이드 전에 수행한 데이터베이스 백업에서 복원하세요.


백업 및 복원

데이터베이스 백업

이 명령을 실행하여 애플리케이션 데이터베이스를 SQL 파일로 내보냅니다:

  docker compose -f docker-compose.production.yml exec mysql \
  mysqldump -u root -p"$(grep MYSQL_ROOT_PASSWORD .env | cut -d= -f2)" smartsurvey \
  > backup-$(date +%Y%m%d-%H%M%S).sql
  

백업 파일은 호스트의 현재 디렉토리에 기록됩니다.

데이터베이스 복원

  docker compose -f docker-compose.production.yml exec -T mysql \
  mysql -u root -p"$(grep MYSQL_ROOT_PASSWORD .env | cut -d= -f2)" smartsurvey \
  < backup-20240101-120000.sql
  

업로드된 파일 백업

설문 제출에는 종종 명명된 Docker 볼륨에 저장된 업로드 파일(사진, 오디오, 문서)이 포함됩니다. 데이터베이스와 별도로 백업하세요:

  # 업로드 백업
docker run --rm \
  -v rtcloud_uploads:/data \
  -v "$(pwd):/backup" \
  alpine tar czf /backup/uploads-$(date +%Y%m%d).tar.gz -C /data .

# 오디오 녹음 백업
docker run --rm \
  -v rtcloud_audios:/data \
  -v "$(pwd):/backup" \
  alpine tar czf /backup/audios-$(date +%Y%m%d).tar.gz -C /data .
  

기본값을 변경한 경우 rtcloud_uploadsrtcloud_audios를 실제 볼륨 이름(COMPOSE_PROJECT_NAME으로 접두사)으로 바꾸세요.

업로드된 파일 복원

  docker run --rm \
  -v rtcloud_uploads:/data \
  -v "$(pwd):/backup" \
  alpine tar xzf /backup/uploads-20240101.tar.gz -C /data
  

자동 일일 백업

호스트에서 크론 작업을 추가하여 자동으로 백업을 실행합니다. crontab -e로 루트 크론탭을 편집합니다:

  # 오전 2시에 일일 데이터베이스 백업, 30일 이력 유지
0 2 * * * cd /opt/rtcloud && docker compose -f docker-compose.production.yml exec -T mysql \
  mysqldump -u root -p"$(grep MYSQL_ROOT_PASSWORD .env | cut -d= -f2)" smartsurvey \
  > /backups/db-$(date +\%Y\%m\%d).sql && \
  find /backups -name "db-*.sql" -mtime +30 -delete
  

문제 해결

앱 컨테이너가 시작되지 않음

오류 메시지에 대한 컨테이너 로그를 확인합니다:

  docker compose -f docker-compose.production.yml logs rtcloud
  

일반적인 원인:

  • .env에 없거나 잘못된 환경 변수
  • MySQL이 아직 준비되지 않음 (60초 기다렸다가 다시 확인)
  • 포트 충돌 — 다른 프로세스가 이미 APP_PORT를 사용 중

MySQL이 정상 상태가 아님

  docker compose -f docker-compose.production.yml logs mysql
  

일반적인 원인:

  • .envMYSQL_ROOT_PASSWORD가 설정되지 않음
  • 손상된 데이터 볼륨 (드문 경우 — df -h로 디스크 공간 확인)

MySQL은 첫 번째 부팅 시 초기화하는 데 30~60초 걸릴 수 있습니다. 실패로 판단하기 전에 기다렸다가 다시 확인하세요.

포트가 이미 사용 중

.env에서 APP_PORT 또는 SHINY_PORT를 사용 가능한 포트로 변경한 후 컨테이너를 재생성합니다:

  docker compose -f docker-compose.production.yml up -d --force-recreate
  

호스트에서 포트를 사용 중인 것을 찾으려면:

  lsof -i :8080
  

400 CSRF 토큰을 확인할 수 없음

이 오류는 요청 출처가 예상 호스트와 일치하지 않는 로컬 또는 역방향 프록시 환경에서 나타납니다. 로컬 개발에서만 CSRF 유효성 검사를 비활성화합니다:

  CSRF_VALIDATION_ENABLED=false
  

그런 다음 앱을 재시작합니다:

  docker compose -f docker-compose.production.yml up -d --force-recreate rtcloud
  

프로덕션에서 CSRF 유효성 검사를 비활성화하지 마세요. 프로덕션에서 이 오류가 발생하면 역방향 프록시가 올바른 HostX-Forwarded-For 헤더를 전달하는지 확인하세요.

관리자 비밀번호를 잊어버림

데이터베이스에서 직접 관리자 비밀번호를 재설정합니다. MySQL 컨테이너에 연결하고 비밀번호 해시를 업데이트합니다:

1단계 — 새 비밀번호 해시 생성. newpassword를 원하는 비밀번호로 교체합니다:

  docker compose -f docker-compose.production.yml exec rtcloud php -r "
  \$salt = trim(shell_exec(\"mysql -h mysql -u root -p\\\"\${MYSQL_ROOT_PASSWORD}\\\" \${MYSQL_DATABASE} -se \\\"SELECT salt FROM ss_user WHERE username='admin';\\\"\"));
  echo md5(\$salt . 'newpassword') . PHP_EOL;
"
  

2단계 — 데이터베이스의 해시 업데이트:

  docker compose -f docker-compose.production.yml exec mysql \
  mysql -u root -p"${MYSQL_ROOT_PASSWORD}" smartsurvey \
  -e "UPDATE ss_user SET password='<1단계의 해시>' WHERE username='admin';"
  

컨테이너가 계속 재시작됨

상태 확인이 실패하는지 확인합니다:

  docker compose -f docker-compose.production.yml ps
docker inspect rtcloud-app --format '{{json .State.Health}}'
  

앱 상태 확인은 /health 엔드포인트를 호출합니다. 반복적으로 실패하면 애플리케이션 로그에서 시작 오류를 확인합니다.

디스크 공간 부족

공간을 소비하는 것을 확인합니다:

  # 호스트 디스크 사용량 확인
df -h

# Docker 디스크 사용량 확인 (이미지, 컨테이너, 볼륨)
docker system df

# 사용하지 않는 이미지 및 중지된 컨테이너 제거 (안전하게 실행 가능)
docker system prune
  

애플리케이션 데이터를 삭제할 수 있으므로 docker system prune --volumes를 사용하지 마세요.


상태 확인

각 서비스에는 자동 상태 확인이 있습니다. 컨테이너 상태는 결과를 반영합니다:

컨테이너확인 방법시작 기간간격
rtcloud-appHTTP GET /health90초30초
rtcloud-mysqlmysqladmin ping30초10초
rtcloud-keycloakHTTP GET :9000/health/live120초30초

상태 확인에 실패한 컨테이너는 RESTART_POLICY 설정(기본값: unless-stopped)에 따라 자동으로 재시작됩니다.

이 페이지가 도움이 되었나요?