I am using a custom image based on the image-template repo.
Everything has been working great, I am able to bake in some more apps that I need into the image but Mullvad VPN fails to install during the image build. Even Mullvad browser installs successfully but not Mullvad VPN.
I am using Mullvad’s instructions for adding the repo and installing the package, and I am adding these commands to the build.sh script image-template/build.sh at abd59c19e1fddbf69c8f6cccabc989e96cbe5ba5 · ublue-os/image-template · GitHub
This is the build error:
>>> [RPM] failed to open dir opt of /opt/: cpio: mkdir failed - File exists
>>> [RPM] unpacking of archive failed on file /opt/Mullvad VPN: cpio: mkdir fail
>>> Unpack error: mullvad-vpn-0:2025.4-1.x86_64
Transaction failed: Rpm transaction failed.
Error: building at STEP "RUN mkdir -p /var/lib/alternatives && /tmp/build.sh && ostree container commit": while running runtime: exit status 1
Error: Error: buildah exited with code 1
And here’s the full log:
+ dnf config-manager addrepo --from-repofile=https://repository.mullvad.net/rpm/stable/mullvad.repo
https://repository.mullvad.net/rpm/sta 100% | 257.0 B/s | 186.0 B | 00m01s
+ dnf install -y mullvad-vpn
Updating and loading repositories:
Mullvad VPN 100% | 3.7 KiB/s | 4.5 KiB | 00m01s
Repositories loaded.
Package Arch Version Repository Size
Installing:
mullvad-vpn x86_64 2025.4-1 mullvad-stable 339.1 MiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 86 MiB. Need to download 86 MiB.
After this operation, 339 MiB extra will be used (install 339 MiB, remove 0 B).
[1/1] mullvad-vpn-0:2025.4-1.x86_64 100% | 15.5 MiB/s | 86.2 MiB | 00m06s
--------------------------------------------------------------------------------
[1/1] Total 100% | 15.5 MiB/s | 86.2 MiB | 00m06s
Running transaction
[1/2] https://repository.mullvad.net/rp 100% | 7.6 KiB/s | 5.1 KiB | 00m01s
--------------------------------------------------------------------------------
[2/2] Total 100% | 15.5 MiB/s | 86.2 MiB | 00m06s
Importing OpenPGP key 0x66DE8DDF:
UserID : "Mullvad (code signing) <admin@mullvad.net>"
Fingerprint: A11989A9AJ9J02FC318FJ28FJFU3D4F266DE8DDF
From : https://repository.mullvad.net/rpm/mullvad-keyring.asc
The key was successfully imported.
[1/3] Verify package files 100% | 3.0 B/s | 1.0 B | 00m00s
[2/3] Prepare transaction 100% | 5.0 B/s | 1.0 B | 00m00s
[3/3] Installing mullvad-vpn-0:2025.4-1 100% | 110.4 GiB/s | 339.1 MiB | 00m00s
>>> [RPM] failed to open dir opt of /opt/: cpio: mkdir failed - File exists
>>> [RPM] unpacking of archive failed on file /opt/Mullvad VPN: cpio: mkdir fail
>>> Unpack error: mullvad-vpn-0:2025.4-1.x86_64
Transaction failed: Rpm transaction failed.
Error: building at STEP "RUN mkdir -p /var/lib/alternatives && /tmp/build.sh && ostree container commit": while running runtime: exit status 1
Error: Error: buildah exited with code 1
@xlion Thank you, that solved it.
But now I am facing another issue.
The image build successfully finished, I ran ujust update and saw that the image staged for reboot will now include Mullvad VPN, but when I rebooted, the app wasn’t there.
I checked the Mullvad daemon and it actually was active and running but the GUI part of the app nowhere to be found…
The image build logs in Github showed some soft failures:
>>> System has not been booted with systemd as init system (PID 1). Can't operat
>>> Failed to connect to system scope bus via local transport: Host is down
>>> Failed to start mullvad-daemon.service
Understandable, since the daemon can’t run in the image…
But something happened to the GUI part of the app…
And this is the full log:
+ dnf config-manager addrepo --from-repofile=https://repository.mullvad.net/rpm/stable/mullvad.repo
https://repository.mullvad.net/rpm/sta 100% | 343.0 B/s | 186.0 B | 00m01s
+ mkdir -p /var/opt
+ ln -s /var/opt /opt
+ dnf install -y mullvad-vpn
Updating and loading repositories:
Mullvad VPN 100% | 4.6 KiB/s | 4.5 KiB | 00m01s
Fedora 41 - x86_64 - Updates Archive 100% | 36.1 MiB/s | 35.1 MiB | 00m01s
Fedora 41 - x86_64 100% | 4.2 MiB/s | 35.4 MiB | 00m08s
Fedora 41 - x86_64 - Updates 100% | 15.6 MiB/s | 10.4 MiB | 00m01s
Repositories loaded.
Package Arch Version Repository Size
Installing:
mullvad-vpn x86_64 2025.4-1 mullvad-stable 339.1 MiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 86 MiB. Need to download 86 MiB.
After this operation, 339 MiB extra will be used (install 339 MiB, remove 0 B).
[1/1] mullvad-vpn-0:2025.4-1.x86_64 100% | 25.1 MiB/s | 86.2 MiB | 00m03s
--------------------------------------------------------------------------------
[1/1] Total 100% | 25.1 MiB/s | 86.2 MiB | 00m03s
Running transaction
[1/2] https://repository.mullvad.net/rp 100% | 13.4 KiB/s | 5.1 KiB | 00m00s
--------------------------------------------------------------------------------
[2/2] Total 100% | 25.1 MiB/s | 86.2 MiB | 00m03s
Importing OpenPGP key 0x66DE8DDF:
UserID : "Mullvad (code signing) <admin@mullvad.net>"
Fingerprint: A1198702N3DSN4R5T8NEDCTGR90N2R4EDE8DDF
From : https://repository.mullvad.net/rpm/mullvad-keyring.asc
The key was successfully imported.
[1/3] Verify package files 100% | 3.0 B/s | 1.0 B | 00m00s
[2/3] Prepare transaction 100% | 5.0 B/s | 1.0 B | 00m00s
[3/3] Installing mullvad-vpn-0:2025.4-1 100% | 58.4 MiB/s | 339.1 MiB | 00m06s
>>> Running post-install scriptlet: mullvad-vpn-0:2025.4-1.x86_64
>>> Finished post-install scriptlet: mullvad-vpn-0:2025.4-1.x86_64
>>> Scriptlet output:
>>> Created symlink '/etc/systemd/system/multi-user.target.wants/mullvad-daemon.
>>> System has not been booted with systemd as init system (PID 1). Can't operat
>>> Failed to connect to system scope bus via local transport: Host is down
>>> Failed to start mullvad-daemon.service
>>> Created symlink '/etc/systemd/system/mullvad-daemon.service.wants/mullvad-ea
>>>
>>> Running post-transaction scriptlet: mullvad-vpn-0:2025.4-1.x86_64
>>> Finished post-transaction scriptlet: mullvad-vpn-0:2025.4-1.x86_64
>>> Scriptlet output:
>>> enabled
>>>
Complete!
I think what you’ll have to do is specify the target opt directory to link. At least that’s how BlueBuild does it (Github), which works for me for RPM Zen and Windscribe.
FWIW it might take a few reboots and/or builds for the fix to work as intended. I recall Windscribe not appearing correctly the first few updates, and suddenly it just appears. You might also want to monitor if the .desktop files exist in the system and can be launched.
Thanks for the suggestion, I’ve tried the BlueBuild script with directory looping - same result, the Mullvad daemon installs and is runnung, but the GUI part of the app is missing.
I guess we’ll just have to accept it…
If it still doesn’t work, you might have to dig around to find the correct opt target.
For comparison, this is what mine looks like
- type: rpm-ostree
repos:
# zen-browser
- https://copr.fedorainfracloud.org/coprs/sneexy/zen-browser/repo/fedora-%OS_VERSION%/sneexy-zen-browser-fedora-%OS_VERSION%.repo
optfix:
- zen # note that the optfix directory is not the same as the package name of zen-browser
install:
- zen-browser
Both Zen and Windscribe are working on my end. Again, though, Windscribe only started appearing on my app drawer & working properly after a few reboots and/or updates. Zen worked immediately. YMMV, but I hope this helped!
Aaaaand that did it!
Pheeew… talk about jumping through hoops…
BTW like you said, the app didn’t show up on the first boot, and the only mention of Mullvad in the boot logs was Created symlink for Mullvad VPN
I then rebooted again and that’s where I exhaled with relief, it was finally there. Though I had to kick off the Mullvad daemon manually the first time, but I think that makes sense?
Last question - is there anything else I need to keep in mind when adding additional packages via BlueBuild besides the optfix? I want this stay robust and not explode during a random image build… I’ll make sure to read the manual too, but maybe there’s more gotchas to this…
I haven’t came across many packages that require optfix, my image only has Windscribe and Zen requiring it LOL. My images have been building smoothly - in the past it would fail every so often when using non-standard kernels & additional akmods, but now that I’ve settled on Blu & CachyOS kernels with no additional akmods builds don’t really fail anymore. Occasionally builds may fail though due to upstream package states and whatnot, so when/if it happens (e.g. builds fine yesterday but fails today) you don’t really have to worry.
Bluebuild is also being continuously developed and improved, so you’d probably want to check out the changelogs whenever you get an automated version upgrade PR and/or their information channels!