Wails로 데스크톱 앱 만들기 #6 빌드와 배포 — 플랫폼별 패키징

5 분 소요

앱이 완성됐으니 남은 일은 하나입니다. 다른 사람의 컴퓨터에서 실행되는 형태로 만드는 것입니다. 이번 글은 wails build가 만들어 내는 산출물의 구조, 플랫폼별 패키징, 그리고 Wails 배포에서 가장 자주 부딪히는 크로스 컴파일 제약과 그 해법인 CI 매트릭스 빌드를 다룹니다. 시리즈의 마지막 편입니다.

총 8편(본편 6편 + 심화 2편)입니다.

  • #1 Wails란 — Go로 만드는 가벼운 데스크톱 앱
  • #2 프로젝트 구조와 개발 루프 — wails dev와 바인딩
  • #3 Go와 프론트엔드 연결 — 메서드 바인딩과 이벤트
  • #4 시스템 통합 — 다이얼로그·메뉴·창 제어
  • #5 실전 기능 — 설정 저장과 에러 처리
  • #6 빌드와 배포 — 플랫폼별 패키징 ← 이번 글

wails build — 단일 바이너리 #

프로덕션 빌드는 명령 하나입니다.

프로덕션 빌드
wails build
# 산출물: build/bin/ 아래

이 과정에서 프론트엔드가 프로덕션 모드로 빌드되고, 그 결과물이 Go 바이너리 안에 embed 됩니다. HTML, JS, CSS 가 전부 실행 파일 하나에 들어가므로, 배포물 옆에 자산 폴더를 따로 둘 필요가 없습니다. wails dev의 핫 리로드 서버는 개발 전용이고, 빌드된 앱은 내장 자산만으로 동작합니다.

플랫폼별 산출물 #

빌드를 실행한 OS 에 따라 산출물의 형태가 다릅니다.

플랫폼기본 산출물배포 형태
Windows앱이름.exe그대로 전달하거나 NSIS 인스톨러
macOS앱이름.app 번들dmg 로 감싸거나 zip 전달
Linux실행 바이너리그대로 전달, 배포판 패키징은 별도

Windows 는 exe 하나로도 배포가 되지만, 시작 메뉴 등록과 제거 지원까지 갖추려면 인스톨러를 만듭니다. Wails 는 NSIS 인스톨러 생성을 내장 지원합니다.

Windows 인스톨러 생성
wails build -nsis

macOS 산출물은 .app 번들입니다. 여기서 현실적인 관문이 코드 서명과 공증(notarization)입니다. 서명 없는 앱은 Gatekeeper 경고를 띄우고, 공증까지 마쳐야 다운로드한 사용자가 경고 없이 실행할 수 있습니다. Apple Developer Program 계정(연 99달러)과 codesign, notarytool 절차가 필요하다는 사실까지가 이 시리즈의 범위이고, 개인 배포 단계에서는 zip 전달 + 우클릭 열기 안내로 시작하는 경우도 많습니다.

Linux 는 바이너리가 그대로 나오며, WebKitGTK 라이브러리가 시스템에 있어야 실행됩니다. 배포판 패키지(deb, AppImage 등)로 만드는 것은 별도 도구의 영역입니다.

아이콘과 앱 메타데이터 #

프로젝트의 build/ 디렉터리가 패키징 리소스의 위치입니다. build/appicon.png를 교체하면 빌드 시 각 플랫폼 형식(icns, ico)으로 변환되어 들어가고, build/darwin/Info.plistbuild/windows/ 아래 파일로 플랫폼별 메타데이터를 조정합니다. 앱 이름과 산출물 파일명은 프로젝트 루트의 wails.json에서 관리합니다.

wails.json — 주요 항목
{
  "name": "wails-todo",
  "outputfilename": "wails-todo",
  "frontend:install": "npm install",
  "frontend:build": "npm run build"
}

크로스 컴파일 제약과 CI 매트릭스 빌드 #

Go 는 크로스 컴파일이 자유로운 언어지만, Wails 앱은 원칙적으로 대상 OS 에서 빌드해야 합니다. 각 플랫폼의 WebView 와 네이티브 코드에 의존하기 때문입니다. macOS 에서 Windows 용을 빌드하는 우회가 일부 있지만, 공식 권장은 플랫폼별 빌드입니다.

세 OS 를 모두 갖추고 있지 않아도 방법이 있습니다. GitHub Actions 의 매트릭스 빌드가 세 플랫폼 러너에서 각각 빌드해 줍니다.

.github/workflows/build.yml — 매트릭스 빌드 골격
jobs:
  build:
    strategy:
      matrix:
        os: [windows-latest, macos-latest, ubuntu-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with: { go-version: stable }
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
      - run: wails build
      - uses: actions/upload-artifact@v4
        with:
          name: app-${{ matrix.os }}
          path: build/bin/

Linux 러너에서는 WebKitGTK 개발 패키지 설치 스텝이 추가로 필요합니다. 태그를 푸시하면 세 플랫폼 산출물이 릴리스에 첨부되는 구성까지 확장하면, 혼자서도 3 플랫폼 배포가 유지됩니다.

크기와 성능 감각 #

Wails 를 선택한 이유가 숫자로 확인되는 지점입니다. 할 일 앱 수준의 프로젝트라면 산출물은 대략 다음 범위에 들어옵니다.

  • Wails — 바이너리 한 자릿수 MB 대(프론트엔드 자산 포함). 런타임에 OS 의 WebView 를 빌려 쓰므로 브라우저 엔진을 담지 않습니다.
  • Electron — 같은 앱이라도 Chromium 과 Node.js 를 동봉해 백 MB 대에서 시작합니다.

메모리 사용도 같은 구조적 이유로 가볍습니다. 다만 OS WebView 를 쓴다는 것은 렌더링 엔진이 OS 버전에 따라 달라진다는 뜻이기도 하므로, 아주 새로운 CSS 기능은 대상 OS 의 WebView 버전을 확인하고 쓰는 신중함이 필요합니다.

노트
Wails v3 는 이 글 시점에 알파 단계로, 멀티 윈도우, 시스템 트레이 개선, 더 유연한 API 구조를 예고하고 있습니다. 이 시리즈가 다룬 바인딩, 런타임 통합, 빌드의 개념은 v3 에서도 그대로 이어지므로, v2 로 익힌 내용은 이전 비용 없이 유효합니다. 정식 릴리스 시점에 마이그레이션 가이드를 확인하면 됩니다.

시리즈 전체 요약 #

여섯 편의 핵심을 한 줄씩 정리합니다.

  • #1 Wails 는 Go 백엔드와 웹 프론트엔드를 OS WebView 로 묶는, Electron 보다 가벼운 데스크톱 프레임워크입니다.
  • #2 wails dev 가 핫 리로드 개발 루프를 제공하고, 프로젝트는 Go 루트와 frontend 디렉터리로 나뉩니다.
  • #3 Go 메서드는 바인딩으로 프론트엔드 함수가 되고, 역방향 통지는 이벤트로 흐릅니다.
  • #4 다이얼로그, 메뉴, 창 제어, 클립보드 같은 OS 통합은 runtime 패키지가 담당합니다.
  • #5 데이터는 UserConfigDir 에 저장하고, Go 의 error 는 프론트엔드의 거부된 Promise 로 이어집니다.
  • #6 빌드는 단일 바이너리로 나오며, 플랫폼별 빌드 제약은 CI 매트릭스로 해결합니다.

마무리 — 그리고 심화 #

웹 기술로 화면을 만들고 Go 로 시스템을 다루는 조합은, 웹 개발 경험이 있는 사람이 데스크톱 앱에 진입하는 가장 완만한 경로 중 하나입니다. 여기까지 따라왔다면 아이디어를 실행 파일로 만들어 전달하는 한 사이클을 완주한 셈입니다.

본편은 여기서 마치고, 심화 두 편이 이어집니다. 본편이 바닐라로 진행한 앞단을 프레임워크로 바꾸는 #7 프론트엔드 프레임워크 붙이기, 그리고 막혔을 때 원인을 찾는 #8 디버깅입니다. 하나의 앱을 배포와 완성도까지 끌고 가는 실전은 Wails 실전 강좌에서 다룹니다.

X