nixos에서 rust tauri, blazor wasm GUI 코딩을 위한 설정
안녕하세요.
추석 연휴 기간 중 윈도우10 종료에 대비하여 nixos를 설치해봤습니다 (=윈도우11용 컴터를 살 돈이 없습니다). nixos에서 rust tauri, blazor wasm을 이용해서 개발하기 위한 설정방법을 정리해봤습니다. 제가 모르는 내용이나 잘못된 것을 댓글로 알려 주시면 감사드리겠습니다.
저는 개발자는 아닙니다. 취미 및 실험 & 연구용 GUI프로그램을 rust tauri로 주로 만들고 있습니다. 대부분 간단한 프로그램이기에 프론트앤드를 단순 html 1개 + js파일 1개로 시작했습니다. 하지만 js에 어려움이 있어 c# blazor wasm으로 변경 하였고, 이후로 rust-tauri + c#-blazor-wasm 조합을 애용하고 있습니다.
NixOS, Nix패키지 매니저는 대부분 chatgpt 도움으로 작성했습니다. 윈도우에서 tauri+blazor설정은 문서와 예제보고 가능했지만, nixos는 제 머리로는 아직 힘들었습니다. 특히, nix | nix+홈매니저 | 홈매니저+flake | nix develop+flake | nix-shell 등 달라지는 사용법이나 nix패키지 채널(24.05, 25.05, 언스테이블 등)을 다수 조합하는 경우에 chatgpt의 도움이 많았습니다.
제가 만든 gui들은 대부분 저 혼자만 사용하기 때문에 배포부분에 대해서는 아직 찾아보지 않았습니다. 아마도 앱이미지로 빌드하면 해결될것으로 예상합니다.
요약
- tauri 문서의 Nixos설정
- nix develop으로 User Space + 현재 쉘에서만 코딩용 패키지 환경 구축
- dotnet 설치
- nix develop으로 설치하려 했지만, 동작하지 않음.
nix 패키지 매니저는 dotnet을 읽기전용으로설치, workload설치가 불가 - dotnet-install.sh 사용 (유저스페이스)
- $PATH 추가 (유저스페이스 home.nix 수정)
- nix-ld 사용 (시스템 configuration.nix 수정)
- nix develop으로 설치하려 했지만, 동작하지 않음.
- dotnet workload install wasm-tool
- libicu를 찾지 못해서 설치 불가
- pkg.icu 추가 (유저스페이스 home.nix 수정)
- $LD_LIBRARY_PATH 추가 (유저스페이스 home.nix 수정)
- nvidea 드라이버로 변경 (시스템 configuration.nix 수정)
- WebKitGTK 문제 우회
- WEBKIT_DISABLE_DMABUF_RENDERER=1 (유저스페이스 nix develop)
- 개발할때
- 터미널에서 blazor 프로젝트 폴더로 이동
dotnet watch run- 새 터미널, tauri 폴더(src-tauri)로 이동
cargo tauri dev(tauri.conf.json의 build.devUrl을 blazor watch url로 지정)
- 배포할때
- blazor wasm 먼저 빌드
- (프로잭트를 처음 빌드하는 경우)
dotnet msbuild --restore - visual studio에서 설정한 배포 설정 (pubxml)을 이용해서 배포용 빌드
dotnet msbuild /p:DeployOnBuild=true /p:PublishProfile=MyReleaseProfile /p:Configuration=Release- tauri 빌드
cargo tauri build -b deb- tauri 빌드(release or dev) 결과 실행할경우,
WEBKIT_DISABLE_DMABUF_RENDERER=1필요.
유저스페이스home.nix에서 설정 필요할 수 있음.
설명
tauri 공식문서
tauri공식문서와
해당 문서에 링크걸린 nixos 위키에서 tauri 개발에 필요한 패키지 환경을 설치할 수 있다.
nix-shell 방법
# Run with `nix-shell shell.nix`
let
pkgs = import <nixpkgs> { };
in
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
pkg-config
gobject-introspection
cargo
cargo-tauri # Optional, Only needed if Tauri doesn't work through the traditional way.
nodejs # Optional, this is for if you have a js frontend
];
buildInputs = with pkgs;[
at-spi2-atk
atkmm
cairo
gdk-pixbuf
glib
gtk3
harfbuzz
librsvg
libsoup_3
pango
webkitgtk_4_1
openssl
];
# shellHook = "";
}
해당 위키에서 제공하는 nix코드는, nix-shell을 사용하는것에 맞춰있다.
nix-shell은 현재 쉘에만 개발용 패키지가 설치되는 환경이다.
nix-shell은 채널(24.05, 25.05 등의 패키지 채널)이 외부설정(nix채널로설정)에 영향을 받는다.
flake로 채널을 고정하고, lock파일로 만들기 위해서 nix develop를 사용하기로 한다.
nix develop . 방법
nix develop는 프로젝트별로 flake.nix파일을 생성한 후, 해당 파일이 있는 위치에서 nix develop .로 사용한다.
rust tauri, blazor wasm을 개발하기위한 flake.nix는 다음처럼 작성하였다.
{
inputs = {
nixpkgs = { url = "github:nixos/nixpkgs/nixos-25.05"; };
oldPkgs = { url = "github:nixos/nixpkgs/nixos-25.05"; };
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, oldPkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
# 패키지 채널을 여러개를 사용한다면, 오버레이가 필요하다. (지금은 25.05로 동일하지만)
pkgs = nixpkgs.legacyPackages.${system};
old = oldPkgs.legacyPackages.${system};
overlayDotnet = final: prev: {
dotnetCorePackages = prev.dotnetCorePackages // {
sdk_9_0_1xx-bin = old.dotnetCorePackages.sdk_9_0_1xx-bin;
sdklib = old.dotnet-sdk_9;
};
};
pkgsWithOverlay = import nixpkgs {
inherit system;
overlays = [ overlayDotnet ];
};
in
{
devShell = pkgsWithOverlay.mkShell {
nativeBuildInputs = with pkgsWithOverlay; [
pkg-config
gobject-introspection
# dotnetCorePackages.sdk_9_0_1xx-bin
# dotnetCorePackages.sdklib
];
buildInputs = with pkgsWithOverlay; [
at-spi2-atk
atkmm
cairo
gdk-pixbuf
glib
gtk3
harfbuzz
librsvg
libsoup_3
pango
webkitgtk_4_1
openssl
];
shellHook = ''
export WEBKIT_DISABLE_DMABUF_RENDERER="1";
'';
};
});
}
이 flake에서는 채널을 2개 사용하고, 서로다른 채널에서 nix패키지를 사용하는것을 가정하였다. dotnet을 24.05에서 설치하는것을 시도하였다가, 제거하였다. WebKitGTK 문제때문에 WEBKIT_DISABLE_DMABUF_RENDERER=1이 필요하여 추가하였다.
(추천하는 flake.nix)
일반적으로 채널을 분리할 필요가 없으므로, 1개 채널만 사용한다고 한다면, 아래 코드처럼 작성할 수 있으며, 마찬가지로 nix develop .로 사용한다.
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells = {
default = pkgs.mkShell {
nativeBuildInputs = [
pkgs.pkg-config
pkgs.gobject-introspection
];
buildInputs = [
pkgs.at-spi2-atk
pkgs.atkmm
pkgs.cairo
pkgs.gdk-pixbuf
pkgs.glib
pkgs.gtk3
pkgs.harfbuzz
pkgs.librsvg
pkgs.libsoup_3
pkgs.pango
pkgs.webkitgtk_4_1
pkgs.openssl
];
shellHook = ''
export WEBKIT_DISABLE_DMABUF_RENDERER="1";
'';
};
};
});
}
이처럼 일반적인 방식으로 변경할 수 있다.
(pkgs, pkgs2로 분리하여 채널을 사용하는 경우의 위험성에 대해서는 아직 몰?루 ㅠㅠㅠ)
dotnet설치
dotnet을 nixos에 설치하기 위해서 nix패키지를 사용하는 방식을 먼저 시도하였다.
nix develop의 flake.nix에 dotnet-sdk_9를 추가하였다.
하지만 blazor wasm 프로젝트를 빌드하려고 하니, workload가 필요하고, workload를 설치하려고 하니 불가능 하였다. 이는 nix패키지 매니저가 패키지를 설치할때, 읽기전용으로 추가하기 때문이다.
이를 해결하기 위해서 dotnet에서 제공하는 dotnet-install.sh를 사용하였다. dotnet버전등의 파라미터에 대한 설명은 링크를 참조하여 STS (9.0)을 설치하였다.
dotnet의 설치는 유저스페이스에서 설치하였다. 따라서 개발하고자 하는 프로젝트별 dotnet설치가 아니라 로그인한 유저는 동일한 dotnet을 사용한다.
dotnet을 사용하기 위해서는 path에 등록해야 하고, 이는 유저스페이스 home.nix에 작성하였다.
{
(...)
programs.bash = {
enable = true;
shellAliases = {
#ll = "ls -alh --color=auto";
ls = "eza -1 -l --color=auto --git --git-repos";
ll = "eza -1 -l --color=auto --git --git-repos --all";
};
initExtra = ''
export PATH="$PATH:/home/ks/.local/bin:/home/ks/.dotnet"
'';
};
(...)
}
하지만 nix패키지로 설치하지 않은 바이너리(여기서는 dotnet)을 사용하기 위해서는 nix-ld를 사용하도록 설정해야한다. 그리고 이 설정은 root로 시스템레벨에서 설정해야한다. 유저스페이스에서 설정하는것은 동작하지 않는다.
이를위해, configuration.nix를 수정한다.
{
(...)
programs.nix-ld.enable = true;
(...)
}
dotnet workload 설치
이제 dotnet 명령어를 사용할 수있다. 하지만 blazor wasm을 빌드하기 위해서는 wasm-tool workload 설치가 필요하다.
dotnet workload install wasm-tools을 실행하면, libicu가 필요하다는 에러가 발생한다.
이를 해결하기 위해서 유저스페이스에서 pkgs.icu를 설치하였지만, 여전히 wasm-tool이 설치되지 않았다. libicu는 설치되었지만, dotnet이 찾지 못하는 것이 문제로, LD_LIBRARY_PATH에 추가해서 해결하였다.
이는 dotnet을 path에 추가한것과 마찬가지로 home.nix에 작성하였다.
{
home.packages = [
(유저스페이스 패키지들)
pkgs.icu
]
(...)
programs.bash = {
enable = true;
shellAliases = {
#ll = "ls -alh --color=auto";
ls = "eza -1 -l --color=auto --git --git-repos";
ll = "eza -1 -l --color=auto --git --git-repos --all";
};
initExtra = ''
export PATH="$PATH:/home/ks/.local/bin:/home/ks/.dotnet"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.icu}/lib"
'';
};
(...)
}
이후 dotnet workload install wasm-tool를 실행할 수 있다.
dotnet과 마찬가지로 패키지별 개발환경이 아닌 유저스페이스 환경에서 설치된다.
tauri+blazor 빌드 후 실행
wasm-tool까지 설치하면, dotnet watch가 가능해진다.
cargo tauri dev로 실행시키면, nouveau: kernel rejected pushbuf: No such device 로 시작하는 에러가 발생한다.
이를 해결하기 위해서는 NVIDIA proprietary driver를 사용해야 한다.
그래픽 드라이버를 변경하기 위해서는 root로 configuration.nix를 수정한다.
{
(...)
# nvidia 그래픽 드라이버 사용
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia = {
modesetting.enable = true;
# GTX 1660 super라서, open소스 드라이버가 아닌것 사용
open = false;
nvidiaSettings = true; # 밝기 조절 등 설정가능
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
pkgs.gpu-viewer # 어떤 드라이버가 설치되었는지 확인용
];
(...)
}
nixos-rebuild switch --flake . 이후 재부팅한다.
이렇게 할경우 앞서 발생한 nouveau 에러가 해결된다. 하지만 여전히 tauri dev에서 gui가 작동하지 않는다.
WebKitGTK 문제 우회
nvidia 드라이버를 설정한 이후에는
Failed to create GBM buffer of size 800x600: Invalid argument 에러가 발생한다.
이는 WebKitGTK에서 발생하는 문제로, WEBKIT_DISABLE_DMABUF_RENDERER=1환경변수 설정이 필요하다.
앞서 flake.nix에서 작성한것처럼 개발환경(nix develop) or 유저스페이스(home.nix)에 설정한다.
# nix develop + flake.nix
shellHook = ''
export WEBKIT_DISABLE_DMABUF_RENDERER="1";
'';
# home.nix의 경우
initExtra = ''
export WEBKIT_DISABLE_DMABUF_RENDERER="1";
'';
배포
(해결중) 아마도 앱이미지로 빌드하고, 이를 nix로 배포해야할것 같습니다.
