Planka Docker Compose 배포 및 설정 가이드
Docker Compose와 Traefik을 사용하여 Planka를 직접 호스팅하는 방법을 설명합니다. Postgres 연동은 물론 로그인 오류를 유발하는 BASE_URL 설정과 관리자 계정 생성 시 주의해야 할 환경 변수 값을 상세히 안내합니다.
Planka를 직접 호스팅하여 얻는 이점
Planka를 직접 호스팅하면 Trello에서 이미 익숙해진 카드, 리스트, 라벨 모델을 갖춘 칸반 보드를 직접 제어하는 VPS에서 운영할 수 있습니다. 서버 비용 외에 별도의 사용자당 요금이나 계정 수 제한이 없습니다. 이 가이드에서는 Docker Compose를 사용하여 Traefik 뒤에 Planka를 배포하며, 데이터 저장소로 Postgres를 사용하고 사용자가 업로드하는 모든 파일을 위해 명명된 볼륨(named volume)을 사용합니다.
이 가이드는 Trello 무료 플랜에서 벗어나려는 2~5명 규모의 팀을 대상으로 합니다. 아직 어떤 보드 서비스를 운영할지 결정하지 못했다면 먼저 직접 호스팅 가능한 Trello 대안 비교를 읽어보시기 바랍니다. 이 가이드는 이미 선택을 마쳤다고 가정하며 배포 과정만 다룹니다.
Compose 플러그인이 포함된 Docker Engine이 실행 중인 VPS와 해당 서버를 가리키는 DNS A 레코드가 필요합니다. 또한 해당 서버에서 이미 TLS(전송 계층 보안)를 종료하고 있는 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 캐시로 활용됩니다. 보드는 리소스를 적게 점유하는 서비스입니다. 만약 같은 VPS에서 팀의 문서를 함께 관리할 계획이라면, 해당 애플리케이션의 사양을 먼저 고려하십시오. Notion 스타일의 워크스페이스로 AFFiNE 실행하기와 같은 서비스는 Planka가 리소스를 사용하기 전부터 이미 수 기가바이트의 메모리를 필요로 합니다.
첨부 파일은 시간이 지날수록 용량이 늘어나므로 메모리보다 디스크 크기를 먼저 산정하십시오. 이 글의 내용을 맹신하기보다 직접 인스턴스를 측정하는 것이 좋습니다.
docker stats --no-stream
docker system df -v첫 번째 명령은 컨테이너별 실시간 메모리 및 CPU 사용량을 출력합니다. 두 번째 명령은 각 볼륨이 차지하는 공간을 보여줍니다. 설치 직후가 아닌, 일주일 정도 정상적으로 업무를 수행한 뒤에 두 측정값을 확인하십시오. 유휴 상태의 보드로는 팀의 실제 사용량을 파악할 수 없기 때문입니다.
Compose 파일 작성
디렉터리를 생성하고 소유권을 변경하여, sudo를 통해 이 파일들을 수정할 필요가 없도록 만듭니다.
sudo mkdir -p /opt/planka
sudo chown "$USER":"$USER" /opt/planka
cd /opt/plankaCompose 파일 옆에 .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 .envopenssl 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는 로그인을 직접 운영하는 싱글 사인온 서버인 Authentik과 같은 OIDC 제공자에게 위임할 수 있습니다. 이때 부트스트랩으로 생성한 관리자 계정은 제공자 서비스가 중단될 때를 대비한 비상용 계정으로 유지하십시오.
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-Proto 및 X-Forwarded-For 헤더를 무시합니다. 이로 인해 애플리케이션은 연결이 안전하지 않다고 판단하며, 모든 클라이언트를 하나의 공유 IP 주소로 취급합니다. 이 설정이 적용되면 애플리케이션은 해당 헤더를 읽고 브라우저와 동일한 스킴을 사용하게 됩니다.
Traefik은 별도의 추가 설정 없이 WebSocket을 프록시하므로 이 환경에서 선호되는 이유 중 하나입니다. nginx의 경우 socket.io는 proxy_set_header Upgrade $http_upgrade 및 proxy_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 psdocker 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'board 및 card을(를) 포함한 테이블 목록이 출력된다면 마이그레이션이 성공한 것입니다. "Did not find any relations"라는 메시지가 나타나면 Planka가 연결되지 않은 것이므로, DATABASE_URL의 값을 .env 내의 POSTGRES_USER 및 POSTGRES_PASSWORD 값과 비교하십시오.
그다음 VPS 내부가 아닌 본인의 로컬 머신에서 경로를 확인하십시오.
curl -I https://kanban.example.comHTTP/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.sh와 docker-restore.sh을 함께 제공하며, 공식 문서에서는 이를 매일 밤 cron 작업으로 실행하도록 권장합니다. 두 방식 모두 적절합니다. 다만, 한 번도 복원해 본 적 없는 백업은 의미가 없으므로, 테스트용 VPS에 복원하여 로그인 및 첨부 파일 열기가 가능한지 반드시 확인하십시오. 업로드를 지원하는 모든 Compose 애플리케이션은 동일한 두 저장소를 사용하므로, 나중에 지원 데스크와 동일한 서버에 Chatwoot을 설치하더라도 여기서 구축한 루틴을 볼륨 이름만 변경하여 그대로 적용할 수 있습니다.
버전 변경 직전에 덤프를 실행하십시오. 어젯밤에 수행한 백업은 지금 수행하려는 마이그레이션 직전의 백업과 동일하지 않습니다.
태그 고정 및 릴리스 노트 확인
해당 파일의 두 이미지 태그는 의도적으로 고정되어 있습니다.
ghcr.io/plankanban/planka:2.1.1는 2026년 8월 기준 최신 버전인 특정 릴리스입니다. latest는 업스트림이 배포할 때마다 변경되므로, 일상적인 docker compose pull을 수행하면 예상치 못한 시점에 스키마 마이그레이션이 발생할 수 있습니다. 해당 숫자를 변경하기 전에 릴리스 노트를 확인하십시오. 주요 변경 사항과 보안 수정 사항이 그곳에 기술되어 있기 때문입니다. 버전 2.0.3은 보안 릴리스로 배포되었으며, 이는 우연히 적용되기보다 미리 읽어두어야 할 중요한 정보입니다. 업스트림이 이미지를 배포하는 경우 태그 고정은 간단합니다. 프로젝트에서 이미지를 제공하지 않는다면 체크아웃한 git 태그를 기반으로 빌드된 openGym의 사례처럼 추가적인 단계를 거쳐 동일한 수준의 관리를 수행해야 합니다.
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 요청을 처리하며, 기본 차단 목록에는 localhost 및 postgres이 포함되어 있습니다. 동일한 호스트의 다른 컨테이너로 향하는 웹훅은 설계상 차단될 수 있습니다. 필터를 제거하는 대신 OUTGOING_ALLOWED_HOSTS를 조정하십시오.
일단 실행되면 운영 부담은 적습니다. 릴리스 노트를 주기적으로 확인하고, 업그레이드 전에는 항상 데이터베이스를 덤프하십시오. Docker 서비스 자체가 부팅 시 활성화되어 있다면 restart: unless-stopped 설정 덕분에 재부팅 후 스택이 자동으로 다시 시작됩니다. 재부팅 후에도 스택이 올라오지 않는 경우에 대해서는 재부팅 후 자동으로 시작되는 Compose 스택을 참조하십시오.
FAQ
로그인 후 Planka가 무한 로딩되는 이유는 무엇입니까?
자격 증명은 수락되었으나 실시간 연결이 실패한 경우입니다. Planka는 BASE_URL를 기반으로 WebSocket URL을 생성합니다. 따라서 해당 변수가 여전히 http://localhost:3000로 설정되어 있는데 사용자가 https://kanban.example.com으로 접속하면, 브라우저는 존재하지 않는 주소로 소켓 연결을 시도합니다. 개발자 도구 콘솔을 확인하면 /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를 사용하되, 리다이렉트된 출력값이 의사 터미널(pseudo-terminal)로 인해 손상되지 않도록 -T 옵션을 유지하십시오. 건너뛰는 모든 버전에 대한 릴리스 노트를 읽고, 이미지 태그를 latest 대신 특정 릴리스 버전으로 변경한 뒤 docker compose pull 및 docker compose up -d을 실행하여 마이그레이션 로그를 모니터링하십시오. Postgres 태그는 메이저 버전에 고정해야 합니다. 서버는 다른 메이저 버전으로 작성된 데이터 디렉터리를 열 수 없기 때문입니다.