Jellyfin Demo
This whole demo is highly insecure as all the private keys are available publicly. This is only done for convenience as it is just a demo. Do not expose the VM to the internet.
The flake.nix file sets up a Jellyfin server with Self Host Blocks. There are actually 3 demos:
The
basicdemo sets up a lone Jellyfin server accessible through https.The
ldapdemo builds on top of thebasicdemo integrating Jellyfin with a LDAP provider.The
ssodemo builds on top of theldapdemo integrating Jellyfin with an SSO provider, backed by the LDAP provider.
This guide will show how to deploy these demos to a Virtual Machine, like showed here.
Deploy to the VM
The demos are setup to either deploy to a VM through nixos-rebuild or through
Colmena.
Using nixos-rebuild is very fast and requires less steps because it reuses your nix store.
Using colmena is more authentic because you are deploying to a stock VM, like you would with a
real machine but it needs to copy over all required store derivations so it takes a few minutes the
first time.
Deploy with nixos-rebuild
Assuming your current working directory is the one where this Readme file is located, the one-liner command which builds and starts the VM is:
rm nixos.qcow2; \
nixos-rebuild build-vm --flake .#basic \
&& QEMU_NET_OPTS="hostfwd=tcp::2222-:2222,hostfwd=tcp::8080-:80" \
./result/bin/run-nixos-vm
This will deploy the basic demo. If you want to deploy the ldap or sso demo,
use respectively the .#ldap and .#sso flake uris.
You can even test the demos from any directory without cloning this repository by using the GitHub
uri like github:ibizaman/selfhostblocks?path=demo/jellyfin#basic
It is very important to remove leftover nixos.qcow2 files, if any, as done in the snippet above.
Deploy with Colmena
If you deploy with Colmena, you must first build the VM and start it:
rm nixos.qcow2; \
nixos-rebuild build-vm-with-bootloader --fast -I nixos-config=./configuration.nix -I nixpkgs=. ; \
QEMU_NET_OPTS="hostfwd=tcp::2222-:2222,hostfwd=tcp::8080-:80" ./result/bin/run-nixos-vm
It is very important to remove leftover nixos.qcow2 files, if any.
This last call is blocking, so I advice adding a & at the end of the command otherwise you will
need to run the rest of the commands in another terminal.
With the VM started, make the secrets in secrets.yaml decryptable in the VM. This change will
appear in git status but you don’t need to commit this.
SOPS_AGE_KEY_FILE=keys.txt \
nix run --impure nixpkgs#sops -- --config sops.yaml -r -i \
--add-age $(nix shell nixpkgs#ssh-to-age --command sh -c 'ssh-keyscan -p 2222 -t ed25519 -4 localhost 2>/dev/null | ssh-to-age') \
secrets.yaml
The nested command, the one in between the parenthesis $(...), is used to print the VM’s public
age key, which is then added to the secrets.yaml file in order to make the secrets decryptable by
the VM.
If you forget this step, the deploy will seem to go fine but the secrets won’t be populated and neither LLDAP nor Jellyfin will start.
Jellyfin Demos
Before being able to access the VM from your browser, we need to create a SOCKS proxy.
First, you will need to change the permission of the ssh key like so:
chmod 600 sshkey
This is only needed because git mangles with the permissions. You will not even see this change in
git status.
Now, the SOCKS proxy can be started on port 1080 like so:
ssh -F ssh_config -D 1080 example
Point your browser to the SOCKS proxy with URL localhost:1080.
Basic demo
Assuming you deployed the basic demo,
go to https://j.example.com and you will be greeted with the
Jellyfin login screen.
You can login with the declaratively provisioned admin user:
Username:
adminPassword:
jellyfinadmin
::: {.info}
If you’re too fast, you might get some nginx bad gateway errors or even the Jellyfin
web UI showing up telling you you need to pick the server. This is because Jellyfin takes a good
minute to start and until then, you won’t see the login screen. Either wait a bit or in the
terminal where you run the SOCKS proxy, tail the logs with journaltcl -f -u jellyfin and wait
for the message Main: Startup complete.
:::
And that’s the end of the demo.
LDAP demo
After Jellyfin has started (see previous section’s note), go to https://j.example.com and you will be greeted with the Jellyfin login screen.
You can login with the declaratively provisioned LDAP alice user:
Username:
alicePassword:
alicepassword
Or with the declaratively provisioned admin user:
Username:
adminPassword:
jellyfinadmin
The LDAP service is accessible at https://ldap.example.com:8080.
You can login with the alice user (same password as above) or as the LDAP admin user with:
username:
adminpassword: the value of the field
lldap.user_passwordin thesecrets.yamlfile which isfccb94f0f64bddfe299c81410096499a.
SSO demo
After Jellyfin has started (wait up to 2 minutes, see previous section’s note), go to https://j.example.com and you will be greeted with the Jellyfin login screen.
First, login through the normal login form with the declaratively provisioned LDAP alice user:
Username:
alicePassword:
alicepassword
Now, you can logout and login again but this time through the SSO “Sign in with Authelia” button, using the same password.
Note
It is best to login first through the normal form as their are caveats to the LDAP and SSO integrations. See the manual for more information.
You could also still login with the declaratively provisioned admin user using the normal login form:
Username:
adminPassword:
jellyfinadmin
The LDAP service is accessible at https://ldap.example.com:8080.
You can login with the alice user (same password as above) or as the LDAP admin user with:
username:
adminpassword: the value of the field
lldap.user_passwordin thesecrets.yamlfile which isfccb94f0f64bddfe299c81410096499a.
In More Details
Files
flake.nix: nix entry point, defines one target host for colmena to deploy to as well as the selfhostblocks’ config for setting up the jellyfin server paired with the LDAP and SSO server.configuration.nix: defines all configuration required for colmena to deploy to the VM. The file has comments if you’re interested.hardware-configuration.nix: defines VM specific layout. This was generated with nixos-generate-config on the VM.Secrets related files:
keys.txt: your private key for sops-nix, allows you to edit thesecrets.yamlfile. This file should never be published but here I did it for convenience, to be able to deploy to the VM in less steps.secrets.yaml: encrypted file containing required secrets for Jellyfin and the LDAP and SSO servers. This file can be publicly accessible. Edit secrets withSOPS_AGE_KEY_FILE=keys.txt sops secrets.yaml.sops.yaml: describes how to create thesecrets.yamlfile. Can be publicly accessible.
SSH related files:
sshkey(.pub): your private and public ssh keys. Again, the private key should usually not be published as it is here but this makes it possible to deploy to the VM in less steps.ssh_config: the ssh config allowing you to ssh into the VM by just using the hostnameexample. Usually you would store this info in your~/.ssh/configfile but it’s provided here to avoid making you do that.
Virtual Machine
More info about the VM.
We use build-vm-with-bootloader instead of just build-vm as that’s the only way to deploy to the VM.
The VM’s User and password are both nixos, as setup in the configuration.nix file under
user.users.nixos.initialPassword.
You can login with ssh -F ssh_config example. You just need to accept the fingerprint.
The VM’s hard drive is a file name nixos.qcow2 in this directory. It is created when you first create the VM and re-used since. You can just remove it when you’re done.
That being said, the VM uses tmpfs to create the writable nix store so if you stumble in a disk
space issue, you must increase the
virtualisation.vmVariantWithBootLoader.virtualisation.memorySize setting.
Secrets
More info about the secrets can be found in the Usage manual
To open the secrets.yaml file and optionnally edit it, run:
SOPS_AGE_KEY_FILE=keys.txt nix run --impure nixpkgs#sops -- \
--config sops.yaml \
secrets.yaml
You can generate random secrets with:
$ nix run nixpkgs#openssl -- rand -hex 64
If you choose a password too small, some services could refuse to start.
Why do we need the VM’s public key
The sops.yaml file describes what private keys can decrypt and encrypt the
secrets.yaml file containing the application secrets. Usually, you will create and add
secrets to that file and when deploying, it will be decrypted and the secrets will be copied
in the /run/secrets folder on the VM. We thus need one private key for you to edit the
secrets.yaml file and one in the VM for it to decrypt the secrets.
Your private key is already pre-generated in this repo, it’s the sshkey file. But when
creating the VM for Colmena, a new private key and its accompanying public key were automatically
generated under /etc/ssh/ssh_host_ed25519_key in the VM. We just need to get the public key and
add it to the secrets.yaml which we did in the Deploy section.
SSH
The private and public ssh keys were created with:
ssh-keygen -t ed25519 -f sshkey
You don’t need to copy over the ssh public key over to the VM as we set the keyFiles option which copies the public key when the VM gets created.
This allows us also to disable ssh password authentication.
For reference, if instead you didn’t copy the key over on VM creating and enabled ssh authentication, here is what you would need to do to copy over the key:
nix shell nixpkgs#openssh --command ssh-copy-id -i sshkey -F ssh_config example
Deploy
If you get a NAR hash mismatch error like hereunder, you need to run nix flake lock --update-input selfhostblocks.
error: NAR hash mismatch in input ...
Update Demo
If you update the Self Host Blocks configuration in flake.nix file, you can just re-deploy.
If you update the configuration.nix file, you will need to rebuild the VM from scratch.
If you update a module in the Self Host Blocks repository, you will need to update the lock file with:
nix flake lock --override-input selfhostblocks ../.. --update-input selfhostblocks