Skip to main content

Snapcraft 가이드 (리눅스)

이 가이드는 Electron 애플리케이션을 Snapcraft 환경에서 패키징하는 방법을 설명한다. 특히 Ubuntu Software Center를 포함한 다양한 Snapcraft 환경에서의 패키징 과정을 다룬다.

배경과 요구사항

Canonical은 더 넓은 Linux 커뮤니티와 함께 snapcraft 프로젝트를 통해 일반적인 소프트웨어 설치 문제를 해결하고자 한다. 스냅(Snaps)은 필요한 종속성을 포함한 컨테이너화된 소프트웨어 패키지로, 자동 업데이트 기능을 제공하며 모든 주요 Linux 배포판에서 시스템 수정 없이 동작한다.

.snap 파일을 생성하는 방법은 세 가지가 있다:

  1. Electron Forge 또는 electron-builder를 사용한다. 이 두 도구는 기본적으로 snap 지원을 제공하므로 가장 쉬운 방법이다.
  2. electron-installer-snap을 사용한다. 이 도구는 @electron/packager의 출력을 받아 처리한다.
  3. 이미 생성된 .deb 패키지를 활용한다.

특정 경우에는 snapcraft 도구를 설치해야 할 수도 있다. 사용 중인 배포판에 맞는 snapcraft 설치 방법은 여기에서 확인할 수 있다.

electron-installer-snap 사용하기

이 모듈은 electron-winstaller와 유사한 방식으로 동작하며, snap 패키지 빌드에만 초점을 맞춘다. 다음과 같이 설치할 수 있다:

npm install --save-dev electron-installer-snap

1단계: Electron 애플리케이션 패키징

@electron/packager 또는 유사한 도구를 사용해 애플리케이션을 패키징한다. 최종 애플리케이션에서 불필요한 node_modules는 제거해야 한다. 사용하지 않는 모듈은 애플리케이션의 크기를 불필요하게 증가시키기 때문이다.

패키징 결과물은 대략 다음과 같은 구조로 생성된다:

.
└── dist
└── app-linux-x64
├── LICENSE
├── LICENSES.chromium.html
├── content_shell.pak
├── app
├── icudtl.dat
├── libgcrypt.so.11
├── libnode.so
├── locales
├── resources
├── v8_context_snapshot.bin
└── version

2단계: electron-installer-snap 실행하기

snapcraftPATH에 설정된 터미널에서 electron-installer-snap를 실행한다. 필수 인자인 --src에는 첫 번째 단계에서 패키징한 Electron 애플리케이션의 위치를 지정한다.

npx electron-installer-snap --src=out/myappname-linux-x64

기존의 빌드 파이프라인이 있다면, electron-installer-snap를 프로그래밍 방식으로 사용할 수도 있다. 자세한 내용은 Snapcraft API 문서를 참고한다.

const snap = require('electron-installer-snap')

snap(options)
.then(snapPath => console.log(`Created snap at ${snapPath}!`))

@electron/packagersnapcraft 함께 사용하기

1단계: 샘플 Snapcraft 프로젝트 생성

프로젝트 디렉토리를 생성하고 snap/snapcraft.yaml 파일에 다음 내용을 추가한다:

name: electron-packager-hello-world
version: '0.1'
summary: Hello World Electron 앱
description: |
간단한 Hello World Electron 앱 예제
base: core22
confinement: strict
grade: stable

apps:
electron-packager-hello-world:
command: electron-quick-start/electron-quick-start --no-sandbox
extensions: [gnome]
plugs:
- browser-support
- network
- network-bind
environment:
# Chromium Framework/Electron에서 libappindicator가 리소스를 읽을 수 있도록 TMPDIR 경로 수정
TMPDIR: $XDG_RUNTIME_DIR

parts:
electron-quick-start:
plugin: nil
source: https://github.com/electron/electron-quick-start.git
override-build: |
npm install electron @electron/packager
npx electron-packager . --overwrite --platform=linux --output=release-build --prune=true
cp -rv ./electron-quick-start-linux-* $SNAPCRAFT_PART_INSTALL/electron-quick-start
build-snaps:
- node/14/stable
build-packages:
- unzip
stage-packages:
- libnss3
- libnspr4

이 예제를 기존 프로젝트에 적용하려면:

  • source: https://github.com/electron/electron-quick-start.gitsource: .로 변경한다.
  • 모든 electron-quick-start 인스턴스를 프로젝트 이름으로 변경한다.

2단계: 스냅 빌드하기

$ snapcraft

<출력 생략>
Snapped electron-packager-hello-world_0.1_amd64.snap

3단계: snap 설치

sudo snap install electron-packager-hello-world_0.1_amd64.snap --dangerous

Step 4: 스냅 실행

electron-packager-hello-world

기존 Debian 패키지 활용하기

Snapcraft는 기존 .deb 파일을 가져와 .snap 파일로 변환할 수 있다. snap 파일 생성은 snapcraft.yaml 파일을 통해 구성된다. 이 파일은 소스, 의존성, 설명, 그리고 기타 핵심 구성 요소를 정의한다.

1단계: Debian 패키지 만들기

.deb 패키지가 아직 없다면, electron-installer-snap을 사용해 snap 패키지를 만드는 것이 더 쉬운 방법일 수 있다. 하지만 Debian 패키지를 생성하는 여러 방법이 있다. 그중에는 Electron Forge, electron-builder, electron-installer-debian 등이 있다.

Step 2: snapcraft.yaml 파일 생성

사용 가능한 설정 옵션에 대한 자세한 정보는 snapcraft 문법 문서를 참고한다. 예제를 살펴보자:

name: myApp
version: '2.0.0'
summary: 앱에 대한 간단한 설명.
description: |
이 앱은 정말 대단하다! 여러분을 위해 모든 일을 해준다. 어떤 사람들은 이 앱이 젊음을 유지시켜주고, 심지어 행복하게 해준다고 말한다.

grade: stable
confinement: classic

parts:
slack:
plugin: dump
source: my-deb.deb
source-type: deb
after:
- desktop-gtk3
stage-packages:
- libasound2
- libnotify4
- libnspr4
- libnss3
- libpcre3
- libpulse0
- libxss1
- libxtst6
electron-launch:
plugin: dump
source: files/
prepare: |
chmod +x bin/electron-launch

apps:
myApp:
command: bin/electron-launch $SNAP/usr/lib/myApp/myApp
desktop: usr/share/applications/myApp.desktop
# Chromium Framework/Electron에서 libappindicator가 리소스를 읽을 수 있도록 TMPDIR 경로를 수정한다.
environment:
TMPDIR: $XDG_RUNTIME_DIR

여기서 snapcraft.yaml 파일은 시스템에게 electron-launch라는 파일을 실행하도록 지시한다. 이 예제에서는 앱의 바이너리에 정보를 전달한다:

#!/bin/sh

exec "$@" --executed-from="$(pwd)" --pid=$$ > /dev/null 2>&1 &

또는 strict 제한 모드로 snap을 빌드하는 경우, desktop-launch 명령어를 사용할 수 있다:

apps:
myApp:
# Chromium Framework/Electron에서 libappindicator가 리소스를 읽을 수 있도록 TMPDIR 경로를 수정한다.
command: env TMPDIR=$XDG_RUNTIME_DIR PATH=/usr/local/bin:${PATH} ${SNAP}/bin/desktop-launch $SNAP/myApp/desktop
desktop: usr/share/applications/desktop.desktop

선택 사항: 데스크톱 캡처 활성화

Wayland 프로토콜을 사용하는 일부 Linux 환경에서 데스크톱 캡처를 사용하려면 PipeWire 라이브러리가 필요하다. 애플리케이션에 PipeWire를 포함시키려면, 먼저 기본 snap이 core22 이상으로 설정되어 있는지 확인한다. 그런 다음 pipewire라는 part를 생성하고 애플리케이션의 after 섹션에 추가한다:

  pipewire:
plugin: nil
build-packages: [libpipewire-0.3-dev]
stage-packages: [pipewire]
prime:
- usr/lib/*/pipewire-*
- usr/lib/*/spa-*
- usr/lib/*/libpipewire*.so*
- usr/share/pipewire

마지막으로, PipeWire를 위해 애플리케이션의 환경을 설정한다:

    environment:
SPA_PLUGIN_DIR: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/spa-0.2
PIPEWIRE_CONFIG_NAME: $SNAP/usr/share/pipewire/pipewire.conf
PIPEWIRE_MODULE_DIR: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/pipewire-0.3