SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-13

Planka 셀프 호스팅: Docker Compose 배포 가이드

Docker Compose와 Traefik을 사용하여 Planka를 VPS에 직접 배포하는 방법을 알아봅니다. Postgres 설정부터 로그인 오류를 유발하는 BASE_URL 환경 변수 구성 및 관리자 계정 생성까지 실무적인 배포 과정을 상세히 설명합니다.

Planka를 직접 호스팅하여 얻는 이점

Planka를 직접 호스팅하면 Trello에서 이미 익숙한 카드, 리스트, 라벨 모델을 갖춘 칸반 보드를 직접 제어하는 VPS에서 운영할 수 있습니다. 서버 비용 외에 추가 비용이 발생하지 않으므로 사용자 수 제한이나 인당 과금 정책이 없습니다. 이 가이드에서는 Docker Compose와 Traefik을 사용하여 Planka를 배포하며, 데이터베이스로는 Postgres를 사용하고 사용자가 업로드하는 모든 파일은 명명된 볼륨(named volume)에 저장합니다.

이 가이드는 Trello 무료 플랜에서 벗어나려는 2~5명 규모의 팀을 대상으로 합니다. 어떤 보드 서비스를 사용할지 아직 결정하지 않았다면 먼저 직접 호스팅 가능한 Trello 대안 비교를 읽어보시기 바랍니다. 이 가이드는 이미 Planka를 선택했다고 가정하며 배포 과정만 다룹니다.

Docker Engine과 Compose 플러그인이 설치된 VPS와 해당 서버를 가리키는 DNS A 레코드가 필요합니다. 또한 해당 서버에서 이미 TLS(전송 계층 보안)를 종료(terminate)하고 있는 Traefik 인스턴스가 있어야 합니다. Traefik이 아직 설정되지 않았다면 먼저 여러 Compose 앱 앞단에 Traefik 리버스 프록시 설정하기를 진행하십시오. 아래 파일 형식이 익숙하지 않다면 VPS를 위한 Docker Compose 기초를 먼저 읽어보시기 바랍니다.

Planka는 어느 정도 사양의 VPS가 필요한가?

이 프로젝트는 공식적인 하드웨어 최소 사양을 명시하지 않으므로, 어디서든 읽게 되는 수치는 측정값이 아닌 시작점 정도로 간주해야 합니다. 호스팅 페이지에서 반복적으로 언급하는 2 vCPU와 4 GB라는 수치는 프로젝트가 측정한 요구 사항이 아니라, 제공업체에서 권장하는 여유로운 기본값일 뿐입니다. 5명이 사용하는 보드라면 이 사양은 매우 넉넉한 편입니다.

실제로 실행되는 프로세스는 작습니다. API와 빌드된 프론트엔드를 제공하는 Node.js 프로세스 하나와 데이터를 저장하는 Postgres 프로세스 하나가 전부입니다. Planka 컨테이너 내부에서는 나가는 요청을 필터링하기 위해 세 번째 작은 프록시 프로세스가 실행됩니다. 1 vCPU와 2 GB 플랜으로도 2명에서 5명 규모의 보드를 운영할 수 있으며, 남는 메모리의 대부분은 Postgres 캐시로 활용됩니다.

메모리보다 디스크 크기를 먼저 산정하십시오. 첨부 파일이 용량을 차지하는 주된 원인이기 때문입니다. 이 문단의 내용을 맹신하지 말고 직접 자신의 인스턴스를 측정하십시오.

docker stats --no-stream
docker system df -v

첫 번째 명령은 컨테이너별 실시간 메모리 및 CPU 사용량을 출력합니다. 두 번째 명령은 각 볼륨이 차지하는 공간을 보여줍니다. 설치 직후가 아닌, 일반적인 업무 주간을 보낸 뒤에 측정하십시오. 유휴 상태의 보드 데이터는 팀의 실제 사용 현황을 알려주지 않기 때문입니다.

Compose 파일 작성

디렉터리를 생성하고 소유권을 변경하여 sudo를 통해 파일을 편집할 필요가 없도록 합니다.

sudo mkdir -p /opt/planka
sudo chown "$USER":"$USER" /opt/planka
cd /opt/planka

Compose 파일 옆에 .env 파일을 생성하여 비밀 값을 저장합니다. Compose는 이 파일을 자동으로 읽어 값을 치환합니다.

umask 077
{
  printf 'SECRET_KEY=%s\n' "$(openssl rand -hex 64)"
  printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)"
  printf 'ADMIN_PASSWORD=%s\n' "$(openssl rand -hex 12)"
} > .env
chmod 600 .env

openssl rand -hex을 사용하는 것은 의도적인 선택입니다. 16진수 문자열은 숫자와 a부터 f까지의 문자로만 구성되므로, 이를 붙여넣는 DATABASE_URL 연결 문자열을 손상시키지 않습니다. 슬래시나 골뱅이 기호가 포함된 base64 비밀번호는 잘못된 호스트 이름처럼 보이는 연결 오류를 유발하며, 이를 해결하는 데 한 시간이 소요될 수 있습니다. 더 넓은 범위의 패턴은 Compose 파일에서 비밀 정보 제외하기에서 다룹니다.

이제 docker-compose.yml을 실행합니다. kanban.example.com가 나타나는 두 곳 모두를 본인의 호스트 이름으로 변경하십시오.

services:
  planka:
    image: ghcr.io/plankanban/planka:2.1.1
    restart: unless-stopped
    volumes:
      - planka-data:/app/data
    environment:
      - BASE_URL=https://kanban.example.com
      - DATABASE_URL=postgresql://planka:${POSTGRES_PASSWORD}@postgres/planka
      - SECRET_KEY=${SECRET_KEY}
      - TRUST_PROXY=true
      - DEFAULT_ADMIN_EMAIL=you@example.com
      - DEFAULT_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - DEFAULT_ADMIN_NAME=Your Name
      - DEFAULT_ADMIN_USERNAME=admin
    networks:
      - proxy
      - internal
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.planka.rule=Host(`kanban.example.com`)"
      - "traefik.http.routers.planka.entrypoints=websecure"
      - "traefik.http.routers.planka.tls.certresolver=default"
      - "traefik.http.services.planka.loadbalancer.server.port=1337"
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=planka
      - POSTGRES_USER=planka
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    networks:
      - internal
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U planka -d planka"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  planka-data:
  db-data:

networks:
  proxy:
    external: true
  internal:

해당 파일의 네 가지 결정 사항은 설명할 가치가 있습니다. 사용자가 이를 임의로 변경한 뒤 후회하는 경우가 많기 때문입니다.

  • Planka 서비스에는 ports: 블록이 없습니다. Traefik은 proxy 네트워크를 통해 컨테이너에 도달하므로, 1337 포트는 호스트에 공개되지 않습니다. 포트를 공개하면 누구나 프록시와 인증서를 우회할 수 있게 됩니다.
  • loadbalancer.server.port=1337는 컨테이너 내부의 포트를 지정합니다. Planka는 1337 포트에서 대기하지만, 업스트림 예제는 포트를 호스트에 매핑하기 때문에 3000 포트로만 접근합니다. 여기서는 호스트 매핑을 사용하지 않으므로 Traefik에 컨테이너 포트를 알려주어야 합니다.
  • condition: service_healthy은 Postgres 상태 확인(healthcheck)과 함께 작동합니다. 이 설정이 없으면 Planka는 데이터베이스가 연결을 수락하기 전에 시작되어 첫 번째 쿼리에서 실패하고 종료되는데, 이는 마치 크래시 루프처럼 보입니다. 자세한 메커니즘은 Compose 상태 확인 및 시작 순서를 참조하십시오.
  • 데이터베이스 서비스의 이름을 postgres로 지정한 것은 의도적입니다. Planka 2는 기본 차단 목록이 localhost,postgres인 내부 필터를 통해 나가는 요청을 라우팅합니다. 서비스 이름을 변경하면 해당 목록에서 데이터베이스가 자동으로 제외됩니다.

시작하기 전에 Compose가 비밀 정보를 인식하는지 확인하십시오.

docker compose config | grep -E 'image:|BASE_URL|POSTGRES_USER'

이 명령은 .env 값이 이미 치환된 파일을 출력합니다. 값이 비어 있다면 Compose가 .env 파일을 읽지 못하는 상태이며, 이는 주로 다른 디렉터리에서 명령을 실행했을 때 발생합니다.

관리자 부트스트랩 변수의 실제 동작 방식

Planka 1.13 버전부터는 관리자 계정이 자동으로 생성되지 않으므로, 데이터베이스를 새로 구성하면 로그인할 수 있는 사용자가 아무도 없습니다. DEFAULT_ADMIN_* 그룹은 이 문제를 해결하는 두 가지 방법 중 하나입니다.

Planka는 시작 시 DEFAULT_ADMIN_EMAIL와 일치하는 사용자가 있는지 확인합니다. 만약 없다면, 함께 설정된 비밀번호, 표시 이름, 사용자 이름을 사용하여 계정을 생성합니다. 이 작업은 빈 데이터베이스를 대상으로 하는 첫 번째 부팅 시에만 수행되므로, 이 변수들은 계정을 관리하는 것이 아니라 부트스트랩하는 용도입니다.

DEFAULT_ADMIN_EMAIL은 사용자가 자주 혼동하는 두 번째 역할을 수행합니다. 이 변수가 설정되어 있는 동안에는 해당 계정을 인터페이스에서 수정하거나 삭제할 수 없습니다. 이는 잠금 방지 장치이며, UI에서 해당 계정의 이름을 변경하거나 이메일 주소를 수정할 수 없는 이유이기도 합니다. 변수를 제거하고 재시작하면 해당 계정은 다른 계정과 마찬가지로 수정 가능한 일반 관리자 계정이 됩니다.

비밀번호 설정 시에는 주의가 필요합니다. environment: 아래에 있는 모든 내용은 컨테이너에서 docker inspect를 실행할 수 있는 사람이라면 누구나 읽을 수 있으므로, DEFAULT_ADMIN_PASSWORD을 영구적으로 유지해서는 안 됩니다. 로그인 후 인터페이스에서 비밀번호를 변경하고, 해당 줄을 삭제한 뒤 docker compose up -d를 다시 실행하십시오.

더 깔끔한 방법은 변수를 전혀 사용하지 않는 것입니다. DEFAULT_ADMIN_* 그룹 전체를 주석 처리한 다음, 대화형 방식으로 계정을 생성하십시오.

docker compose run --rm planka npm run db:create-admin-user

이 명령은 이메일, 비밀번호, 표시 이름, 선택 사항인 사용자 이름을 입력받아 데이터베이스에 직접 기록합니다. 비밀번호는 Compose 파일이나 컨테이너 환경 변수에 노출되지 않습니다. VPS에 대한 셸 접근 권한을 가진 사람이 여러 명이라면 이 방법을 사용하십시오. depends_on 설정 덕분에 명령 실행 시 Postgres가 먼저 시작되므로, 한 번도 실행된 적 없는 스택에서도 정상적으로 작동합니다.

어떤 방법을 선택하든 Planka 비밀번호는 직접 관리해야 합니다. 만약 팀이 관리해야 할 자격 증명이 이미 많다면, Planka는 로그인을 OIDC 제공자에게 위임할 수 있습니다. 예를 들어 직접 운영하는 싱글 사인온 서버인 Authentik을 사용할 수 있으며, 부트스트랩 관리자 계정은 제공자가 다운되었을 때를 대비한 비상용 계정으로 유지하면 됩니다.

BASE_URL이 호스트 이름과 일치하지 않을 때 로그인이 실패하는 이유

BASE_URL은 사용자가 브라우저에 입력하는 정확한 주소이며, 스킴을 포함하고 마지막에 슬래시를 붙이지 않습니다. 이 스택의 경우 https://kanban.example.com이 해당합니다. Planka는 이 값을 기반으로 자체 링크와 WebSocket 연결을 생성하므로, BASE_URL가 잘못 설정되면 명확한 오류 메시지가 표시되지 않습니다. 대신 페이지가 로드되다가 완료되지 않은 상태로 멈추게 됩니다.

흔히 발생하는 사례는 업스트림 예제를 복사하면서 BASE_URL=http://localhost:3000을 그대로 두는 경우입니다. 이 상태에서 실제 도메인의 HTTPS로 사이트에 접속하면 로그인 폼은 정상적으로 제출되고 자격 증명도 승인됩니다. 하지만 보드 화면은 나타나지 않습니다. 브라우저 개발자 도구를 열어보면 /socket.io/로 향하는 요청이 실패하는 것을 확인할 수 있는데, 이는 클라이언트가 localhost:3000로 실시간 연결을 시도하도록 지시받았으나 사용자의 환경에서는 해당 주소가 존재하지 않기 때문입니다.

TRUST_PROXY=true은 동일한 문제의 나머지 절반을 차지합니다. Planka는 Traefik 뒤에서 동작하므로, 모든 요청은 Docker 네트워크 내부에서 프록시의 주소를 통해 일반 HTTP로 전달됩니다. TRUST_PROXY가 없으면 애플리케이션은 Traefik이 설정한 X-Forwarded-ProtoX-Forwarded-For 헤더를 무시합니다. 그 결과 연결이 안전하지 않다고 판단하여 모든 클라이언트를 하나의 공유 IP 주소로 취급하게 됩니다. 이 값을 설정하면 애플리케이션이 해당 헤더를 읽어 브라우저와 동일한 스킴을 사용하게 됩니다.

Traefik은 별도의 추가 설정 없이 WebSocket을 프록시하므로 이 환경에서 선호되는 이유 중 하나입니다. nginx를 사용할 경우 socket.io는 proxy_set_header Upgrade $http_upgradeproxy_set_header Connection "upgrade"를 포함하는 별도의 location 블록이 필요하며, 그렇지 않으면 다른 원인으로 인해 동일하게 로딩 아이콘이 멈추는 현상이 발생합니다.

나중에 보드를 새로운 호스트 이름으로 옮기려면 BASE_URL 값과 Traefik Host() 규칙을 함께 변경해야 합니다. 하나만 변경하고 나머지를 잊으면 다시 로딩 아이콘이 멈추는 현상을 겪게 됩니다. https://example.com/planka와 같은 하위 경로에서 Planka를 서비스하는 것은 2026년 3월에 릴리스된 버전 2.1.0부터 지원됩니다. 이전 태그를 사용 중이라면 별도의 서브도메인을 할당하십시오.

Planka가 첨부 파일과 아바타를 저장하는 위치

Planka 2는 사용자가 업로드한 모든 데이터를 컨테이너 내부의 단일 경로인 /app/data 아래에 저장합니다. 첨부 파일, 사용자 아바타, 보드 배경 이미지가 모두 이 경로에 위치합니다. 버전 1에서는 세 개의 별도 디렉터리를 사용했으므로, 이전 문서에서 복사한 Compose 파일은 더 이상 존재하지 않는 경로를 마운트하게 되며 실제 데이터 디렉터리는 마운트되지 않은 상태로 남게 됩니다.

이 단일 마운트 설정은 업그레이드 후에도 보드가 정상적으로 유지되는지, 아니면 데이터가 모두 사라지는지를 결정하는 중요한 차이를 만듭니다. 만약 /app/data가 볼륨으로 설정되어 있지 않으면, 업로드된 파일은 컨테이너의 쓰기 가능 레이어(writable layer)에 저장됩니다. 이 레이어는 컨테이너가 재생성될 때 파괴되며, 이미지 태그를 변경할 때마다 컨테이너는 재생성됩니다. 보드는 정상적으로 돌아온 것처럼 보이고 카드도 그대로 남아 있지만, 데이터베이스 행은 더 이상 존재하지 않는 파일을 가리키고 있으므로 모든 첨부 파일 링크는 작동하지 않게 됩니다.

위의 Compose 파일에 포함된 네임드 볼륨(named volume)은 이러한 문제를 방지합니다. 바인드 마운트(bind mount)를 사용해도 동일한 효과를 얻을 수 있으며 일반적인 도구로 파일을 백업하기 더 쉽지만, 추가적인 단계가 필요합니다. 컨테이너 내부의 Node 프로세스는 UID 1000으로 실행되므로, root가 소유한 호스트 디렉터리를 사용하면 첫 업로드 시 권한 오류가 발생합니다.

sudo chown -R 1000:1000 /opt/planka/data

이 두 방식 사이의 장단점은 바인드 마운트와 네임드 볼륨 비교에서 다룹니다.

플랜의 디스크 용량보다 첨부 파일이 더 커질 경우, Planka는 S3_ENDPOINT, S3_BUCKET 및 관련 키 변수를 통해 S3 호환 스토리지에 파일을 저장할 수 있습니다. 이는 호스팅된 버킷이나 다른 서버에 구축한 자체 호스팅 MinIO 오브젝트 스토어를 가리킬 수 있습니다. 이 설정은 새로운 업로드에만 적용되므로, 팀이 보드를 사용하기 전에 미리 결정해야 합니다.

스택을 시작하고 정상 작동 여부 확인

docker compose pull
docker compose up -d
docker compose ps

docker compose ps 명령을 실행하면 postgres이(가) healthy(으)로, planka이(가) running(으)로 표시되어야 합니다. Planka가 재시작을 반복한다면 애플리케이션보다 데이터베이스 연결 상태를 먼저 확인해야 합니다.

docker compose logs -f planka

정상적인 첫 부팅 시에는 데이터베이스 마이그레이션이 실행된 후 서버가 1337 포트에서 대기 중이라는 메시지가 출력됩니다. 로그만 신뢰하지 말고 Postgres에 직접 질의하여 스키마가 실제로 생성되었는지 확인하십시오.

docker compose exec postgres psql -U planka -d planka -c '\dt'

boardcard을(를) 포함한 테이블 목록이 출력되면 마이그레이션이 성공한 것입니다. "Did not find any relations"라는 메시지가 나타나면 Planka가 연결되지 않은 것이므로, DATABASE_URL의 값과 .env 내의 POSTGRES_USERPOSTGRES_PASSWORD 값을 비교하십시오.

그다음 VPS 내부가 아닌 로컬 머신에서 경로를 확인하십시오.

curl -I https://kanban.example.com

HTTP/2 200 응답은 Traefik이 인증서를 보유하고 컨테이너에 도달하고 있음을 의미합니다. Traefik이 404 오류를 반환한다면 라우터 레이블이 일치하지 않는 것이며, 이는 주로 컨테이너가 proxy 네트워크에 연결되지 않았을 때 발생합니다. 이제 사이트를 열고 관리자 계정으로 로그인하십시오.

버전 업데이트 전에는 항상 pg_dump를 수행하십시오

게시판 데이터는 두 개의 독립된 저장소에 보관되므로, 백업은 Postgres 데이터베이스와 planka-data 볼륨 두 곳 모두를 포함해야 합니다. 스택이 실행 중인 상태에서 데이터베이스를 덤프하십시오.

docker compose exec -T postgres pg_dump -U planka -d planka > "planka-db-$(date +%F).sql"

-T 옵션은 필수입니다. 이 옵션이 없으면 Compose는 의사 터미널(pseudo-terminal)을 할당하며, 터미널 계층이 스트림 내의 줄 바꿈 문자를 재작성하게 됩니다. 이로 인해 복원 도중 실패하는 덤프 파일이 생성됩니다. 이러한 실패는 몇 주 뒤에야 드러나며, 이는 가장 최악의 상황입니다.

다음은 업로드 파일입니다. Compose는 프로젝트 디렉터리 이름을 볼륨 이름 앞에 접두사로 붙이므로, 먼저 실제 볼륨 이름을 확인하십시오.

docker volume ls | grep planka
docker run --rm -v planka_planka-data:/data -v "$PWD":/backup alpine \
  tar czf /backup/planka-files-$(date +%F).tgz -C /data .

이 프로젝트는 저장소에 docker-backup.shdocker-restore.sh를 포함하여 제공하며, 공식 문서에서는 이를 매일 밤 cron 작업으로 설정하도록 안내합니다. 두 방식 모두 괜찮습니다. 하지만 한 번도 복원해 보지 않은 백업은 의미가 없습니다. 테스트용 VPS에 백업을 복원해 보고, 로그인하여 첨부 파일을 열 수 있는지 반드시 확인하십시오.

버전 변경 직전에 즉시 덤프를 수행하십시오. 어젯밤에 수행한 백업은 지금 실행하려는 마이그레이션 직전의 백업과 동일하지 않습니다.

태그 고정 및 릴리스 노트 확인

해당 파일의 두 이미지 태그는 의도적으로 고정되어 있습니다.

ghcr.io/plankanban/planka:2.1.1는 2026년 8월 기준 최신 버전인 특정 릴리스입니다. latest는 업스트림에서 배포할 때마다 변경되므로, 일상적인 docker compose pull을 수행하면 예상치 못한 시점에 스키마 마이그레이션이 발생할 수 있습니다. 해당 숫자를 변경하기 전에 릴리스 노트를 확인하십시오. 주요 변경 사항과 보안 수정 사항이 그곳에 기술되어 있기 때문입니다. 버전 2.0.3은 보안 릴리스로 배포되었으며, 이는 우연히 적용되기보다는 미리 읽어두어야 할 중요한 정보입니다.

postgres:16-alpine이 메이저 버전에 고정된 이유는 더 명확합니다. Postgres는 메이저 버전과 연동된 형식으로 데이터 디렉터리를 기록하며, 서버는 다른 버전으로 작성된 디렉터리를 여는 것을 거부합니다. postgres:latest을 작성하여 태그가 17로 변경되도록 두면 컨테이너는 시작되지 않습니다.

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.

데이터가 손실되는 것은 아니며, 재시작한다고 해서 해결되지도 않습니다. 새로운 Postgres 메이저 버전으로 이동하려면 이전 버전에서 덤프를 생성하고 새로운 데이터 디렉터리에 복원해야 합니다. 이는 스택을 내린 상태에서 계획적으로 수행해야 하는 작업이며, 이미지 풀(pull)의 부수 효과로 발생해서는 안 됩니다.

새로 설치하는 것이 아니라 기존 Planka 1.x 설치 환경을 이전하는 경우, 해당 업그레이드에는 프로젝트 문서에 기술된 별도의 절차가 있습니다. 사전에 백업을 받아두지 않으면 버전 1로 되돌릴 방법은 없습니다.

실패 유형과 확인되는 메시지

Planka가 반복적으로 재시작되며 로그에 데이터베이스 관련 오류가 나타납니다. DATABASE_URL에 설정된 자격 증명이 Postgres 환경 설정과 일치하지 않는 경우입니다. POSTGRES_PASSWORD은 데이터 디렉터리가 처음 초기화될 때만 적용된다는 점에 유의하십시오. 따라서 잘못된 첫 부팅 이후에 변수를 수정해도 아무런 변화가 없습니다. db-data 볼륨을 삭제하고 다시 시작해야 합니다.

로그인은 성공하지만 보드가 로드되지 않습니다. BASE_URL가 브라우저 주소창의 주소와 일치하지 않거나 TRUST_PROXY이 누락된 경우입니다. 브라우저 콘솔을 확인하면 /socket.io/로 향하는 요청이 실패하는 것을 볼 수 있습니다.

다른 기능은 정상이나 파일 업로드가 실패합니다. 바인드 마운트된 디렉터리의 소유자가 root로 되어 있기 때문입니다. 호스트 디렉터리에서 sudo chown -R 1000:1000를 실행한 뒤 컨테이너를 재시작하십시오.

업그레이드 후 첨부 파일이 사라졌습니다. /app/data이 볼륨으로 설정되지 않아 파일이 컨테이너 레이어에 저장되었고, 업그레이드 과정에서 해당 레이어가 교체되었기 때문입니다. 백업에서 파일을 복구한 뒤, 이미지 태그를 다시 변경하기 전에 볼륨을 추가하십시오.

Traefik이 404 오류를 반환합니다. 컨테이너가 proxy 네트워크에 연결되어 있지 않거나, Host() 규칙이 DNS 레코드와 일치하지 않는 경우입니다. docker compose config를 확인하면 치환된 레이블을 볼 수 있으며, 여기서 오타를 발견할 수 있습니다.

알림이나 웹훅이 도착하지 않습니다. Planka 2는 내부 필터를 통해 나가는 HTTP 요청을 전송하며, 기본 차단 목록에는 localhostpostgres이 포함되어 있습니다. 같은 호스트에 있는 다른 컨테이너로 향하는 웹훅은 설계상 차단될 수 있습니다. 필터를 제거하는 대신 OUTGOING_ALLOWED_HOSTS를 조정하십시오.

일단 실행되면 운영 부담은 적습니다. 릴리스 노트를 확인하고, 업그레이드 전에는 항상 데이터베이스를 덤프하십시오. Docker 서비스 자체가 부팅 시 활성화되어 있다면 restart: unless-stopped 설정 덕분에 재부팅 후 스택이 자동으로 복구됩니다. 자동으로 복구되지 않는 경우에 대해서는 재부팅 후 자동으로 시작되는 Compose 스택을 참조하십시오.

FAQ

로그인 후 Planka가 무한 로딩되는 이유는 무엇입니까?

자격 증명은 승인되었으나 실시간 연결이 실패한 경우입니다. Planka는 BASE_URL를 기반으로 WebSocket URL을 생성합니다. 따라서 사이트에는 https://kanban.example.com으로 접속하는데 해당 변수가 여전히 http://localhost:3000로 설정되어 있다면, 브라우저는 존재하지 않는 주소로 소켓 연결을 시도하게 됩니다. 개발자 도구 콘솔을 확인하면 /socket.io/에 대한 요청 실패가 나타납니다. BASE_URL을 끝에 슬래시가 없는 정확한 공용 주소로 설정하고, TRUST_PROXY=true를 추가하여 애플리케이션이 리버스 프록시로부터 전달된 X-Forwarded-Proto 헤더를 인식하도록 한 뒤 docker compose up -d을 실행하십시오.

첫 번째 Planka 관리자 계정은 어떻게 생성합니까?

버전 1.13부터는 관리자가 자동으로 생성되지 않습니다. DEFAULT_ADMIN_EMAIL와 그에 대응하는 비밀번호, 이름, 사용자명 변수를 설정하고 스택을 시작하거나, docker compose run --rm planka npm run db:create-admin-user을 실행하여 안내에 따라 입력하십시오. 대화형 명령은 공유 서버에서 더 안전합니다. 비밀번호가 docker inspect가 읽을 수 있는 컨테이너 환경 변수로 노출되지 않기 때문입니다. 작업 후에도 DEFAULT_ADMIN_EMAIL를 설정된 상태로 유지하면 해당 계정은 인터페이스에서 수정하거나 삭제할 수 없게 잠깁니다.

Planka는 첨부 파일과 아바타를 어디에 저장합니까?

Planka 2에서 업로드된 모든 파일은 컨테이너 내부의 /app/data 경로에 저장됩니다. 여기에는 첨부 파일, 사용자 아바타, 보드 배경이 포함됩니다. 해당 경로를 명명된 볼륨(named volume)으로 마운트하십시오. 마운트하지 않으면 파일이 컨테이너의 쓰기 가능 레이어에 저장되며, 이미지 업그레이드 시 컨테이너가 재생성될 때 모두 삭제됩니다. 바인드 마운트(bind mount)도 가능하지만, Node 프로세스가 UID 1000으로 실행되므로 호스트 디렉터리에 sudo chown -R 1000:1000을 실행해야 권한 오류로 인한 업로드 실패를 방지할 수 있습니다.

자가 호스팅 Planka에는 어느 정도의 RAM이 필요합니까?

프로젝트에서 공식적으로 정한 최소 사양은 없습니다. 호스팅 페이지에 자주 언급되는 2 vCPU 및 4 GB 사양은 측정값이 아니라 제공업체의 기본 설정이며, 소규모 보드 운영에는 매우 넉넉한 수준입니다. 전체 작업 부하는 하나의 Node 프로세스와 하나의 Postgres 프로세스가 전부이므로, 1 vCPU 및 2 GB 플랜으로도 2~5명 규모의 팀을 충분히 지원할 수 있습니다. 일주일 정도 정상 운영한 뒤 docker stats --no-stream을 실행하여 실제 사용량을 확인하고 규모를 산정하십시오. 첨부 파일 용량이 계속 증가하므로 메모리보다 디스크 사용량을 더 주의 깊게 모니터링해야 합니다.

데이터를 잃지 않고 Planka를 업그레이드하려면 어떻게 해야 합니까?

업그레이드 직전에 데이터베이스를 덤프하고 업로드 볼륨을 아카이브하십시오. 어젯밤의 백업 스케줄에 의존해서는 안 됩니다. docker compose exec -T postgres pg_dump -U planka -d planka > planka-db.sql를 사용하되, -T을 유지하여 의사 터미널(pseudo-terminal)이 리다이렉트된 출력 내용을 손상시키지 않도록 하십시오. 건너뛰는 모든 버전에 대한 릴리스 노트를 읽고, 이미지 태그를 latest 대신 특정 릴리스 버전으로 변경한 뒤 docker compose pulldocker compose up -d을 실행하여 마이그레이션 로그를 확인하십시오. Postgres 태그는 메이저 버전에 고정해 두어야 합니다. 메이저 버전이 다르면 서버가 데이터 디렉터리를 열지 못하기 때문입니다.