SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-22

셀프 호스팅 인보이스 소프트웨어 5종 비교 분석

Invoice Ninja, InvoiceShelf, InvoicePlane, Kimai, ERPNext의 기능을 비교합니다. 정기 결제, 세금 설정, 결제 게이트웨이 연동 및 라이선스 정책을 분석하여 VPS 환경에 가장 적합한 소프트웨어를 선택하는 기준을 제시합니다.

어떤 셀프 호스팅 인보이스 소프트웨어를 선택해야 할까요?

셀프 호스팅 인보이스 소프트웨어는 하나의 VPS에서 운영할 수 있는 5가지 현실적인 선택지로 압축되며, 이들은 서로 완벽하게 대체 가능한 관계가 아닙니다. Invoice Ninja는 가장 완성도가 높은 제품으로, 정기 인보이스 발행, 고객 포털, 결제 게이트웨이, 전자 인보이스 형식 등 모든 기능이 설치 첫날부터 정상 작동합니다. InvoiceShelf는 더 가볍고 완전한 오픈 소스 옵션입니다. InvoicePlane은 별도의 오케스트레이션이 필요 없는 단순한 PHP 애플리케이션입니다. Kimai는 항목별 청구가 아닌 추적된 시간 단위로 비용을 청구합니다. ERPNext는 인보이스 발행 기능을 포함한 완전한 회계 시스템입니다.

셀프 호스팅 인보이스 환경을 구축할 때 기능 부족보다 훨씬 더 자주 발생하는 문제는 두 가지입니다. 첫 번째는 이메일입니다. 스팸 메일함에 들어간 인보이스는 미납 인보이스와 다름없으며, 이 사실을 알려주는 시스템도 없습니다. 두 번째는 백업입니다. 이는 데이터가 손실될 경우 단순한 불편함을 넘어 세무 문제로 직결되는 유일한 셀프 호스팅 데이터베이스입니다.

기능 목록을 읽기 전에 라이선스를 먼저 확인하십시오. 이 5가지 소프트웨어 중 3개는 카피레프트(copyleft) 라이선스이며, 1개는 허용적(permissive) 라이선스, 나머지 1개는 사용 범위에 실질적인 제한이 있는 소스 가용(source-available) 라이선스를 따릅니다.

다섯 가지 옵션과 각 대상 사용자

Invoice Ninja

Laravel 기반 애플리케이션으로 현재 v5 버전을 사용합니다. 자체 호스팅은 무료이며 반복 청구서, 견적서, 프로젝트 관리, 시간 추적, 비용 관리, 고객 포털, Stripe 및 PayPal을 포함한 결제 게이트웨이 등 모든 기능을 제한 없이 사용할 수 있습니다. 이 프로젝트는 스스로를 "Laravel로 구축된 소스 공개형 청구서, 견적서, 프로젝트 및 시간 추적 앱"이라고 정의합니다. 유일한 유료 항목은 브랜딩 제거입니다. 프로젝트 측 설명에 따르면 "고객 대면 화면에서 Invoice Ninja 브랜딩을 제거하기 위해 연간 40달러의 화이트 라벨 라이선스를 제공합니다." 이 가격은 2026년 8월 기준입니다.

가장 완벽한 기능을 원하고 규모가 큰 스택을 운영할 의향이 있다면 이 제품을 선택하십시오.

InvoiceShelf

Crater의 포크 버전으로 GNU Affero General Public License 버전 3(AGPL-3.0)을 따릅니다. 청구서, 견적서, 반복 청구, 비용 관리, 세금, 다중 통화, 고객 포털 및 다중 회사 기능을 지원합니다. 결제 및 화이트 라벨링 기능은 별도의 공식 모듈 저장소에 있으며, 모두 AGPL-3.0 라이선스로 무료 제공됩니다. 카드 결제는 Stripe checkout을 통해 처리됩니다.

소규모의 완전한 오픈 소스 애플리케이션을 원하고 수십 개의 결제 게이트웨이가 필요하지 않다면 이 제품을 선택하십시오.

InvoicePlane

CodeIgniter 기반의 PHP 애플리케이션으로 MIT 라이선스로 배포됩니다. 이 목록에서 유일하게 웹 루트 디렉터리에 파일 압축을 푸는 방식으로 설치하는 옵션입니다. Docker나 Node 빌드 단계가 필요 없습니다. PDF는 mPDF를 통해 생성되므로 템플릿은 HTML과 CSS로 작성합니다. 고객은 게스트 링크를 통해 청구서를 확인하고 결제할 수 있습니다.

문제는 결제 기능입니다. 문서에 따르면 InvoicePlane 1.6은 기본적으로 Stripe만 지원하며, 다른 결제 제공업체는 해당 버전에서 제거되었습니다. 1.6 버전의 요구 사항은 PHP 8.0~8.1과 MySQL 5.5 또는 이에 상응하는 MariaDB입니다. 1.7 버전이 계속 개발 중이므로 다운로드하는 릴리스의 노트를 반드시 확인하십시오.

공용 호스팅이나 512 MB VPS 환경이라면 이 제품을 선택하십시오.

Kimai

타임시트에서 청구서를 생성하는 AGPL-3.0 기반 시간 추적 도구입니다. 시간을 단위로 청구하는 모든 사용자에게 적합한 솔루션입니다. 청구서 템플릿은 DOCX, ODS 또는 XLSX 파일로 업로드하며, 문서에 따르면 이 형식들만 지원됩니다. 이후 PDF나 HTML로 렌더링됩니다. CSS를 작성하는 대신 워드 프로세서에서 청구서 레이아웃을 구성하므로 대부분의 사용자에게 더 쉽습니다.

Kimai는 고객 포털이나 결제 게이트웨이가 없으므로 PDF를 이메일로 전송해야 합니다. 구조화된 전자 청구서 기능은 E-Invoice Plus라는 유료 스토어 플러그인으로 제공됩니다. 2026년 8월 기준 자체 호스팅 설치 시 연간 99 EUR(VAT 별도)이며, EN16931, XRechnung, ZUGFeRD, Factur-X 및 Peppol 프로필을 지원합니다.

청구서가 시간 추적의 결과물이라면 이 제품을 선택하십시오.

ERPNext

GPL-3.0 라이선스를 따르며, 앞선 소프트웨어들과는 범주가 다릅니다. 판매 청구서는 계정과목표, 분개장, 재고 및 급여 관리를 포함한 전체 회계 시스템 내의 문서 유형 중 하나입니다. 청구서 발행이 업무의 전부가 아닐 때 적합한 솔루션입니다. 8개의 고객을 둔 프리랜서 한 명에게는 너무 방대한 소프트웨어입니다. 설치 과정 자체가 하나의 프로젝트이며, 자세한 내용은 VPS에서 ERPNext 운영하기를 참조하십시오.

반복 청구서는 눈에 보이지 않는 스케줄러에 의존합니다

Invoice Ninja, InvoiceShelf, InvoicePlane, ERPNext는 모두 반복 청구서를 생성합니다. Kimai는 핵심 기능에 반복 청구서 기능이 없는데, 이는 해당 서비스의 청구서가 특정 기간의 타임시트 항목을 기반으로 작성되기 때문입니다.

Laravel 기반 애플리케이션에서 발생하는 실패 유형은 모두 동일하며, 조용하게 나타납니다. 반복 청구서는 애플리케이션 외부에서 1분마다 호출해야 하는 php artisan schedule:run이라는 예약된 작업에 의해 생성됩니다. 이를 호출하는 프로세스가 없으면 반복 청구서 목록에는 다음 발송 예정일이 표시되지만, 해당 날짜가 지나도 아무 일도 일어나지 않습니다. 코드가 실행되지 않았으므로 오류 로그도 남지 않습니다.

따라서 첫 번째 반복 청구서를 생성한 후, 다음 발송 예정일을 몇 분 뒤로 설정하고 기다려 보십시오. 아무것도 도착하지 않는다면 스케줄러가 실행되지 않는 것입니다. Docker 설치 환경에서 이는 보통 compose 파일의 cron 또는 스케줄러 서비스가 시작되지 않았거나 종료되었음을 의미합니다.

docker compose ps
docker compose logs --tail 50

파일 내의 모든 서비스는 running 상태를 보고해야 합니다. exited 상태에 머물러 있는 서비스가 있다면 해당 서비스의 로그를 확인해야 합니다.

다중 통화 및 세금: 커밋 전 확인 사항

기능 목록에 기재된 "다중 통화"는 제품마다 의미하는 바가 크게 다릅니다. 데모 인스턴스에서 귀사의 실제 수치를 사용하여 다음 네 가지 항목을 확인하십시오. 이 부분에서 발생하는 실수는 본인이 아닌 회계사가 발견하게 되기 때문입니다.

  1. 송장에 발행일 기준 환율이 저장됩니까? 반드시 저장되어야 합니다. 애플리케이션이 실시간 환율로 합계를 재계산하면 지난 분기 보고서가 열 때마다 변경되며, 장부가 이미 신고한 내용과 일치하지 않게 됩니다.
  2. 세금이 품목별로 적용됩니까, 송장 전체에 적용됩니까, 아니면 둘 다 가능합니까? 송장 단위의 단일 세율은 한 품목이라도 면세 대상이 되는 순간 문제가 발생합니다.
  3. 가격을 세금 포함 및 세금 별도 방식으로 모두 입력할 수 있습니까? 사후에 변환하면 품목당 1센트 단위의 반올림 오차가 발생하며, 이러한 오차는 1년 동안 누적됩니다.
  4. 부가가치세(VAT) 납부 의무가 없는 타국 고객에게 발행하는 문서에는 무엇이 표시됩니까? 세금 열에 단순히 0을 표시하는 것이 아니라, 송장에 면세 사유 문구가 인쇄되어야 합니다.

Invoice Ninja와 ERPNext는 위 네 가지 사항을 모두 처리합니다. InvoiceShelf는 기능 목록에 세금 및 다중 통화를 포함하고 있습니다. InvoicePlane과 Kimai는 상대적으로 단순하므로, 가장 쉬운 송장이 아닌 가장 까다로운 송장을 기준으로 테스트하십시오.

클라이언트 포털 및 결제 게이트웨이

클라이언트 포털은 고객이 자신의 청구서를 확인하고, PDF를 다운로드하며, 결제를 진행할 수 있는 페이지입니다. 이메일로 결제를 독촉하는 것이 청구서를 작성하는 것보다 더 많은 시간을 소모하기 때문에, 이는 생각보다 훨씬 중요합니다.

Invoice Ninja는 이 분야에서 가장 강력한 기능을 제공합니다. 완전한 포털, 다양한 게이트웨이, 결제 수단 저장 기능, 그리고 반복 청구서에 대한 자동 결제 기능을 갖추고 있습니다. InvoiceShelf는 고객 포털을 제공하며 결제 모듈을 통해 Stripe checkout을 추가할 수 있습니다. InvoicePlane은 각 청구서에 게스트 링크를 제공하며 Stripe를 지원합니다. Kimai는 두 기능 모두 제공하지 않으므로, PDF를 첨부 파일로 발송해야 합니다.

한 가지 자주 혼동되는 점이 있습니다. 청구 애플리케이션을 직접 호스팅한다고 해서 카드 번호를 직접 보관하는 것은 아닙니다. Stripe checkout을 사용하면 클라이언트는 Stripe 페이지로 리다이렉트되어 그곳에 카드 정보를 입력하게 되며, 사용자의 VPS는 카드 번호를 전혀 볼 수 없습니다. 결제 폼을 직접 구축하지 않았기 때문에 PCI(결제 카드 산업) 준수 범위가 작게 유지되는 것입니다. 만약 추후에 하나 이상의 결제 프로세서가 필요하거나 국가별로 결제를 라우팅해야 한다면, 이는 Hyperswitch를 이용한 자체 호스팅 결제 오케스트레이션과 같은 별도의 계층에서 처리해야 합니다.

PDF 품질 및 편집할 템플릿

템플릿을 직접 편집하게 됩니다. 기본 설정은 사용자의 국가와 맞지 않는 위치에 주소를 표시합니다.

Invoice Ninja는 이미지에 포함된 헤드리스 Chromium을 사용하여 HTML 및 CSS 템플릿을 PDF로 렌더링하며, 이 때문에 컨테이너 용량이 큽니다. 메모리 할당 시 주의하십시오. 헤드리스 브라우저는 스택에서 가장 무거운 프로세스이므로 1 GB VPS에서는 자원이 부족할 수 있습니다. InvoicePlane은 순수 PHP 기반의 mPDF를 사용하여 가볍지만, 최신 CSS 일부를 지원하지 않는다는 단점이 있습니다. Kimai는 이와 반대로 DOCX 또는 ODS 파일을 업로드하는 방식을 취하므로, 스타일시트를 작성해 본 적 없는 사용자도 LibreOffice나 Word를 사용하여 레이아웃을 구성할 수 있습니다.

디자인된 청구서가 중요하고 CSS는 중요하지 않다면 Kimai 방식이 유리합니다. 템플릿을 버전 관리 시스템에 포함하고 변경 사항을 비교해야 한다면 HTML 방식이 더 적합합니다.

상업적 용도로 사용할 수 있는 라이선스인가요?

다섯 가지 소프트웨어 모두 고객에게 청구서를 발행하는 용도로 사용할 수 있습니다. 그 이상의 작업을 수행할 때 차이점이 발생합니다.

Invoice Ninja는 Elastic License 2.0을 따릅니다. 다음 두 조항이 중요합니다.

귀하는 소프트웨어의 상당한 기능이나 기능을 사용자에게 제공하는 호스팅 또는 관리형 서비스로서 제3자에게 소프트웨어를 제공할 수 없습니다.
귀하는 소프트웨어의 라이선스 키 기능을 이동, 변경, 비활성화하거나 우회할 수 없습니다.

따라서 자신의 사업을 위해 운영하는 것은 괜찮지만, 고객을 위한 제품으로 인스턴스를 운영하는 것은 허용되지 않습니다. 두 번째 조항 때문에 브랜딩을 제거하려면 소스 코드를 수정하는 대신 40달러의 라이선스를 구매해야 합니다.

InvoiceShelf, Kimai, Crater는 AGPL-3.0을 따릅니다. 상업적 이용은 무료이며 상위 등급은 존재하지 않습니다. 13조에 따른 의무가 있는데, 코드를 수정하고 수정된 버전을 네트워크를 통해 다른 사람들이 사용하게 할 경우 해당 변경 사항의 소스 코드를 제공해야 합니다. 수정하지 않은 인스턴스는 이미 업스트림의 공개 소스에 포함되므로, 대부분의 자가 호스팅 사용자는 이 조항에 해당하지 않습니다.

InvoicePlane은 MIT 라이선스를 따르며, 이 그룹에서 의무 사항이 가장 적습니다. 다만 README에 명시된 대로 이름과 로고는 프로젝트의 소유로 남습니다.

ERPNext는 GPL-3.0을 따릅니다. 배포하는 수정 사항은 공유해야 하지만, 비공개로 운영하는 경우에는 아무런 의무가 없습니다.

위 내용은 라이선스 텍스트에 대한 설명일 뿐 법률적 조언이 아닙니다.

프로젝트가 여전히 유지보수되고 있습니까? 커밋 로그를 확인하십시오

Crater는 수년간 인기 있는 오픈 소스 인보이스 애플리케이션이었으며, 여전히 많은 가이드에서 이를 추천합니다. 기본 브랜치(default branch)에는 741일 동안 커밋이 없었습니다.

ChartGap since the last commit on the default branch, in days, checked 21 August 2026
The data behind this chart
[
  {
    "label": "ERPNext",
    "commit_gap": 0
  },
  {
    "label": "Invoice Ninja",
    "commit_gap": 1
  },
  {
    "label": "Kimai",
    "commit_gap": 1
  },
  {
    "label": "InvoicePlane",
    "commit_gap": 3
  },
  {
    "label": "InvoiceShelf",
    "commit_gap": 4
  },
  {
    "label": "Crater",
    "commit_gap": 741
  }
]

해당 블록에 있는 6개의 프로젝트 중 5개는 지난주 내에 커밋이 있었습니다. InvoiceShelf는 Crater의 작업을 이어받은 포크(fork)이며, 동일한 AGPL-3.0 라이선스를 사용하고 데이터 모델도 같습니다. 따라서 전환 시 재작성이 아닌 데이터 마이그레이션만 수행하면 됩니다. Crater가 아닌 InvoiceShelf를 설치하십시오.

VPS에 각각 설치하기

InvoicePlane을 제외한 모든 서비스는 Docker Compose를 사용하는 것이 가장 간편합니다. Docker Compose가 생소하다면 VPS에서 첫 Docker Compose 스택 구성하기를 먼저 읽고 돌아오십시오.

Invoice Ninja는 자체 compose 저장소를 제공합니다.

git clone https://github.com/invoiceninja/dockerfiles.git
cd dockerfiles
docker run --rm -it invoiceninja/invoiceninja php artisan key:generate --show

해당 키를 저장소 내의 env 파일에 실제 APP_URL와 함께 복사하십시오. 그 후 이미지에서 요구하는 소유권을 설정하고 서비스를 시작합니다.

chmod 755 docker/app/public
sudo chown -R 1500:1500 docker/app
docker compose up -d

1500:1500 소유권은 컨테이너 내부 사용자와 일치해야 합니다. 이 단계를 건너뛰면 애플리케이션이 캐시나 생성된 PDF 파일을 기록할 수 없습니다. 설정 마법사에서 데이터베이스 호스트로 db을 입력하십시오. 이는 compose 네트워크상의 서비스 이름이기 때문입니다. 그곳의 localhost은 애플리케이션 컨테이너 자체를 가리킵니다.

InvoiceShelf는 데이터베이스 엔진별로 준비된 compose 파일을 제공합니다.

curl -fLO https://raw.githubusercontent.com/InvoiceShelf/docker/master/docker-compose.mysql.yml
mv docker-compose.mysql.yml docker-compose.yml

시작하기 전에 해당 파일을 여십시오. 파일 내의 모든 비밀번호는 자리 표시자이며, 파일 내 주석에도 명시되어 있습니다. APP_URL, SESSION_DOMAIN, SANCTUM_STATEFUL_DOMAINS은 모두 기본값이 localhost로 설정되어 있으므로, 첫 로그인 전에 세 항목 모두 실제 호스트네임으로 변경해야 합니다. 그 후 서비스를 실행하십시오.

docker compose up -d

이 서비스는 호스트의 8090 포트를 게시하고 컨테이너 내부에서는 8080 포트로 서비스합니다. 클라이언트가 접속하기 전에 반드시 TLS(전송 계층 보안)가 적용된 리버스 프록시를 앞단에 배치하십시오.

프로젝트 문서에서 가져온 Kimai 프로덕션 compose 파일
services:

  sqldb:
    image: mysql:8.3
    volumes:
      - mysql:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=kimai
      - MYSQL_USER=kimaiuser
      - MYSQL_PASSWORD=kimaipassword
      - MYSQL_ROOT_PASSWORD=changemeplease
    command: --default-storage-engine innodb
    restart: unless-stopped
    healthcheck:
      test: mysqladmin -uroot -p$$MYSQL_ROOT_PASSWORD ping -h 127.0.0.1 --silent
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  kimai:
    image: kimai/kimai2:stable
    depends_on:
      sqldb:
        condition: service_healthy
        restart: true
    volumes:
      - data:/opt/kimai/var/data
      - plugins:/opt/kimai/var/plugins
    ports:
      - 8001:8001
    environment:
      - APP_SECRET=your-fantastic-long-random-and-ultra-secure-secret
      - TRUSTED_HOSTS=kimai.example.com
      - ADMINMAIL=admin@example.com
      - ADMINPASS=changemeplease
      - DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8mb4&serverVersion=8.3.0
    restart: unless-stopped

volumes:
  data:
  mysql:
  plugins:

APP_SECRET을 길고 무작위인 문자열로 설정하고, TRUSTED_HOSTS를 실제로 사용할 도메인으로 변경하십시오. ADMINMAILADMINPASS은 첫 부팅 시 최초 관리자 계정을 생성하므로, 이후 인터페이스에서 비밀번호를 변경하고 파일에서 해당 정보를 제거하십시오.

InvoicePlane은 컨테이너를 지원하지 않습니다. 먼저 빈 데이터베이스를 생성하십시오.

sudo mysql -e "CREATE DATABASE invoiceplane CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

프로젝트 릴리스 페이지에서 아카이브를 다운로드하여 웹 루트에 압축을 해제한 뒤, ipconfig.php.exampleipconfig.php로 복사하십시오. 파일 내 주석을 따라 URL을 설정한 후, https://your-domain.example/index.php/setup에 접속하여 설치 과정을 진행하십시오.

청구서가 스팸 메일함으로 분류되는 이유

이 문제는 금전적 손실을 야기하지만, 애플리케이션은 청구서가 성공적으로 발송되었다고 보고할 것입니다.

VPS의 IP 주소에서 직접 청구서 메일을 발송하지 마십시오. 새로운 VPS IP는 발송 이력이 없으며, 대형 메일 서비스 제공업체는 호스팅 대역의 알 수 없는 주소에서 온 첫 메시지를 기본적으로 의심스러운 메일로 간주합니다. 인증된 도메인의 SMTP(simple mail transfer protocol) 릴레이를 통해 메일을 발송하십시오. 이 과정을 처음부터 끝까지 수행하는 것은 별도의 가이드가 필요하며, 자체 호스팅 애플리케이션에서 안정적으로 메일 발송하기 문서에서 릴레이 설정, DNS 레코드 구성 및 테스트 방법을 다룹니다.

대부분의 청구 시스템에서 가장 흔히 발생하는 실수는 From 주소 설정입니다. From 주소는 반드시 본인이 관리하는 도메인이어야 하며, 릴레이 서버가 DKIM(domainkeys identified mail)으로 서명할 수 있는 도메인이어야 합니다. 고객의 이메일 주소를 From에 넣는 것은 예의 바르게 보일 수 있으나 메일 전달을 방해합니다. 수신 서버는 From 도메인과 메시지를 인증한 도메인이 일치하는지 확인하기 때문입니다. Gmail은 이러한 불일치를 즉시 거부합니다.

550 5.7.1 Unauthenticated email from example.com is not accepted due to domain's DMARC policy

본인의 주소를 From에 유지하고 고객의 주소는 Reply-To에 넣으십시오. 실제 메일을 발송하기 전에 게시된 레코드를 확인하십시오.

dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com

첫 번째 명령은 릴레이 서버를 지정하는 SPF(sender policy framework) 레코드를 반환해야 합니다. 두 번째 명령은 DMARC(domain-based message authentication, reporting and conformance) 정책을 반환해야 합니다. 세 번째 명령은 릴레이 서버가 제공한 셀렉터에 따라 달라지며, 결과가 비어 있다면 DKIM 레코드가 누락되었거나 잘못된 이름으로 게시된 것이므로 발송하는 모든 메시지의 서명 검사가 실패하게 됩니다.

그 후 대형 메일 서비스 제공업체에 소유한 계정으로 실제 청구서를 발송하고 원본 헤더를 확인하십시오. Authentication-Results 헤더의 dkim=passspf=pass 항목만이 유효한 증거입니다. 애플리케이션 자체의 "발송됨" 상태는 메시지가 릴레이 서버로 전달되었다는 의미일 뿐입니다.

백업: 절대 잃어버려서는 안 될 데이터베이스

미디어 서버의 데이터를 잃어버리면 파일을 다시 다운로드하면 그만입니다. PhotoPrism이나 Immich와 같은 셀프 호스팅 사진 서버조차도 보통은 사진을 촬영한 휴대폰에 원본이 남아 있는 경우가 많습니다. 하지만 청구서 데이터베이스를 잃어버리면 무엇을 청구했고, 무엇을 입금받았으며, 무엇이 미납 상태인지 증명할 수 없게 됩니다. 따라서 데이터베이스는 그에 걸맞은 수준으로 관리해야 합니다.

다음 네 가지를 반드시 백업하십시오. 데이터베이스, 로고와 생성된 PDF 및 비용 영수증이 저장된 스토리지 볼륨, 애플리케이션의 환경 파일, 그리고 일반 파일로 보관된 렌더링 완료된 PDF입니다. PDF는 이를 생성한 애플리케이션이 없어도 10년 뒤에 열어볼 수 있기 때문입니다.

환경 파일은 생각보다 훨씬 중요합니다. Laravel은 해당 파일에 포함된 APP_KEY를 사용하여 결제 게이트웨이 자격 증명을 포함한 민감한 저장 값을 암호화합니다. 새로 생성된 키와 함께 데이터베이스를 복원하면 기존 값들을 복호화할 수 없습니다. 청구서 데이터는 모두 남아 있더라도 게이트웨이 설정은 읽을 수 없는 상태가 됩니다.

InvoiceShelf 스택의 덤프는 다음과 같은 형태입니다. 데이터베이스 서비스는 mariadb:10를 실행하므로, 컨테이너 내부의 도구는 mariadb-dump입니다.

docker compose exec -T database mariadb-dump \
  --user=root --password=YOUR_ROOT_PASSWORD \
  --single-transaction --databases invoiceshelf > invoiceshelf.sql

--single-transaction는 InnoDB 테이블을 잠그지 않고 일관된 스냅샷을 생성하므로, 덤프가 실행되는 동안에도 애플리케이션은 정상적으로 서비스를 제공합니다. -T은 Docker가 터미널을 할당하지 않도록 하여, 리다이렉트된 출력값이 손상되어 가져오기(import)가 불가능한 덤프 파일이 생성되는 것을 방지합니다.

암호화된 restic 백업을 외부 저장소로 전송하는 작업을 스케줄에 따라 서버 밖으로 수행하고, 회계사가 요구하는 기간을 충족할 수 있도록 보관 주기를 충분히 길게 설정하십시오.

그런 다음 복원을 테스트하십시오. 일회용 컨테이너에 덤프를 올리고, 로그인한 뒤 지난달 청구서를 열어보십시오. 이 과정을 한 번이라도 수행해 보기 전까지는 백업이 제대로 작동하는지 알 수 없습니다.

회계사가 요청할 사항

이 튜토리얼을 세무 조언으로 받아들이지 마십시오. 아래 내용은 본 소프트웨어가 생성할 수 있는 데이터이며, 이를 귀하의 자문가에게 전달하여 확인받으시기 바랍니다.

내보내기 가능한 데이터. 데이터베이스 클라이언트를 사용하거나 지원 티켓을 열지 않고도 인터페이스에서 직접 송장과 결제 내역을 CSV로 내보낼 수 있어야 합니다. SQL 덤프는 백업일 뿐 내보내기가 아니며, 회계사가 이를 직접 열어볼 수 없기 때문입니다.

변경 불가능한 번호 체계. 송장 번호는 순차적으로 부여되어야 하며, 절대 재사용되거나 중간에 누락되어서는 안 됩니다. 송장을 삭제하면 공백이 발생하며, 이에 대한 소명이 필요합니다. 대신 취소(Cancel) 또는 대변(Credit) 처리를 해야 하며, 여기에 소개된 모든 애플리케이션은 이 기능을 지원합니다. 번호의 연속성이 필수적인지는 귀하가 등록된 지역에 따라 다르므로 미리 확인하는 것이 좋습니다.

보관. 데이터베이스 덤프와 생성된 PDF는 귀하의 규정에서 요구하는 기간만큼 보관하십시오. PDF는 실제로 발송된 문서이며, 송장과 관련한 분쟁 발생 시 가장 중요한 증거 자료가 됩니다.

변경 이력. 누가 언제 송장을 수정했는지 확인할 수 있는 기능은 유용하며, 애플리케이션마다 차이가 큽니다. Invoice Ninja는 레코드별 활동 로그를 유지합니다.

구조화된 전자 송장(e-invoicing)은 EU 일부 지역에서 선택 사항이 아닌 필수 요건이 되었습니다. Invoice Ninja는 ZUGFeRD, XRechnung, Facturae, FatturaPA 및 일반적인 EN16931을 포함한 공통 형식을 생성합니다. 자체 호스팅 인스턴스에서 Peppol 네트워크를 통한 전송은 Invoice Ninja의 자체 액세스 포인트를 거칩니다. 2026년 8월 기준으로, 해당 서비스에 법인을 등록하고 제출 건당 크레딧을 구매해야 하는 유료 서비스입니다. Kimai는 유료 플러그인을 통해 동일한 형식을 지원합니다. 나머지 세 가지 애플리케이션은 현재 구조화된 전자 송장을 전혀 생성하지 않으므로, EU 내에서 송장을 발행해야 한다면 Invoice Ninja를 선택해야 하는 가장 강력한 이유가 됩니다.

FAQ

Crater와 InvoiceShelf 중 무엇을 설치해야 합니까?

InvoiceShelf를 선택하십시오. 2026년 8월 21일 기준으로 Crater의 기본 브랜치는 741일 동안 커밋이 없었으며, 프로젝트 이슈 트래커에서도 포크된 프로젝트를 사용하도록 안내하고 있습니다. InvoiceShelf는 동일한 AGPL-3.0 라이선스와 데이터 모델을 사용하므로, 두 서비스 간의 전환은 재작성이 아닌 데이터베이스 마이그레이션 수준에서 가능합니다. Crater를 추천하는 가이드는 프로젝트가 중단되기 전에 작성된 것입니다.

Invoice Ninja를 비용 지불 없이 제 사업에 사용할 수 있습니까?

네. 자체 호스팅하는 Invoice Ninja는 Elastic License 2.0에 따라 반복 청구서, 고객 포털, 결제 게이트웨이를 포함한 모든 기능을 무료로 사용할 수 있습니다. 비용이 발생하는 경우는 두 가지입니다. 고객에게 노출되는 페이지에서 Invoice Ninja 브랜딩을 제거하려면 화이트 라벨 라이선스가 필요하며, 2026년 8월 기준으로 프로젝트 측은 이를 "연간 $40"로 명시하고 있습니다. Peppol 네트워크를 통한 전자 청구서 발송은 별도로 과금됩니다. 라이선스에서 금지하는 것은 이 소프트웨어를 타인을 위한 호스팅 서비스로 운영하는 행위입니다.

청구서 이메일이 왜 스팸 메일함으로 들어갑니까?

거의 대부분 From 주소의 도메인에 대한 메시지 인증이 이루어지지 않았기 때문입니다. VPS에서 직접 발송하지 말고 SMTP 릴레이를 통해 발송하십시오. 그 후 도메인에 대한 SPF 및 DMARC 레코드를 게시하고, 릴레이 서비스에서 제공하는 셀렉터에 맞춰 DKIM 레코드를 추가하십시오. From 주소에는 본인의 주소를 유지하고, Reply-To에 고객의 주소를 넣으십시오. 고객의 주소를 발신자로 설정하면 Gmail은 550 5.7.1 Unauthenticated email from example.com is not accepted due to domain's DMARC policy 오류와 함께 메시지를 거부합니다. 테스트 메시지의 Authentication-Results 헤더에서 dkim=passspf=pass 항목을 확인하여 수정 사항을 검증하십시오.

시간 단위로 청구할 경우 무엇을 선택해야 합니까?

Kimai를 선택하십시오. Kimai는 시간 추적 기능이 우선이므로, 승인된 타임시트 항목을 기반으로 청구서가 생성되며 작업 내역이 항목별로 기록됩니다. 템플릿은 워드 프로세서에서 직접 디자인할 수 있는 DOCX, ODS 또는 XLSX 파일 형식이므로 CSS를 수정하는 것보다 훨씬 간편합니다. 단, Kimai에는 고객 포털이나 결제 게이트웨이가 없으므로 PDF를 이메일로 보내고 계좌 이체로 대금을 받아야 합니다. Invoice Ninja 역시 시간 추적 기능을 지원하고 포털도 제공하므로, 타임시트의 상세함보다 온라인 카드 결제가 더 중요하다면 Invoice Ninja를 선택하십시오.

정확히 무엇을 백업해야 합니까?

데이터베이스, 로고와 생성된 PDF가 저장된 스토리지 볼륨, 환경 파일, 그리고 일반 파일로 보관된 렌더링된 PDF입니다. 환경 파일은 사람들이 가장 자주 놓치는 부분입니다. Invoice Ninja나 InvoiceShelf와 같은 Laravel 애플리케이션은 저장된 자격 증명을 APP_KEY으로 암호화하므로, 새로 생성된 키와 함께 데이터베이스를 복원하면 기존의 결제 게이트웨이 설정을 읽을 수 없게 됩니다. 백업이 정상적으로 작동하는지 확인하는 유일한 방법은 임시 인스턴스에 전체를 복원한 뒤 이전 청구서를 열어보는 것뿐입니다.