[PM-29484] Add support for running rootless and with readonly filesystem - #358
[PM-29484] Add support for running rootless and with readonly filesystem#358kaysond wants to merge 12 commits into
Conversation
|
Aram Akhavan seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
Bump. @tangowithfoxtrot could you please approve the workflow runs? |
|
Maybe @mandreko-bitwarden or @vgrassia can help? |
|
Bumping again. Maybe @pixman20 can approve the workflows? |
|
How about @michalchecinski or @Eeebru ? |
aaccc4b to
d7566f2
Compare
|
|
Great job, no security vulnerabilities found in this Pull Request |
|
@kaysond / @tangowithfoxtrot: what's the current state of this PR? I'm deliberately waiting to run Bitwarden rootless 🤓 |
Looks like it needs to be rebased, which I'm happy to do, but doesn't seem clear that it's going to be merged... If the maintainers commit to merging it I'm happy to update it. Otherwise don't really want to spend more time. |
djsmith85
left a comment
There was a problem hiding this comment.
Hi @kaysond, thank you for your contribution 🎉 ❤️
With the recent announcement of bitwarden-unified being out of beta, it was also decided to change the name to bitwarden-lite. This unfortunately has caused a ton of conflicts with your changes.
As you mentioned previously you'd be up to rebase, if you hear back from Bitwarden. I spoke with someone from @bitwarden/dept-bre and product management, and they think this is a great addition. Once you have updated the PR, this is ready for review by @bitwarden/dept-bre and possibly also @bitwarden/team-platform-dev.
Please let us know if you are still interested in contribution to this PR.
Thanks again for taking the time to contribute and adding a highly requested feature!
Kind regards,
Daniel
Sure, I'll rebase it when I have a chance and let you know. |
|
Rebase completed by blindly re-applying the patches to the new dir and fixing some obvious issues. Still need to test. |
|
Not wanting to hijack this - but would you have plans to implement rootless & read-only to the 'classic' Bitwarden deployment method too? I prefer the 'original' approach as it fits better to the best-practises of how docker/containers were designed. |
No, sorry. That's a much more involved project covering many Dockerfile and entrypoint.sh files (see https://github.com/search?q=repo%3Abitwarden%2Fserver%20Dockerfile&type=code). You could apply the same strategy as is used here, though. |
|
@djsmith85 - this is ready for review. Tested with server v2025.12.0 I'd like to add a github action to run shellcheck on the entrypoint script. It's not clear to me where that should go, though, since it seems you're using azure. |
Co-authored-by: gitclonebrian <235774926+gitclonebrian@users.noreply.github.com>
Co-authored-by: gitclonebrian <235774926+gitclonebrian@users.noreply.github.com>
|
@gitclonebrian - any other feedback? Would be great to get this merged as I just migrated my install to the lite container :) |
Hey @kaysond , sorry for the delay! This PR has actually sparked some more internal discussion here about how we want to proceed with a rootless |
Np. Thanks for the update. Glad it's being discussed! |
|
I just tried experimenting with Bitwarden Lite in Proxmox using the new 9.1 OCI Image support https://forum.proxmox.com/threads/oci-images-in-lxc-release-9-1.176273/ Namely, I imported
I added the necessary environment variables to the configuration (SMTP, admin email, SSL info, sqllite DB provider for an all-in-one experience, installation ID and key, domain) I also created a mountpoint and set it to
I confirmed all these settings worked via a docker compose running in Debian, and this was just porting over to Proxmox OCI However, I am seeing Is this due to the LXC/container/Bitwarden Lite not being set up as root? I confirmed that I'm not super familiar with docker and containers in general, so let me know if I'm barking up the wrong tree and I can go create an issue in https://github.com/bitwarden/server/issues or https://github.com/bitwarden/self-host/issues |
If you're using the latest release of the container, these updates to enable rootless/readonly root vs aren't in yet. You can build this container from this branch and try it, but not sure it'll solve your problem. Try emailing bitwarden support. |
There was a problem hiding this comment.
Overall the current changes look good, thanks @kaysond.
There are two items I think may need updated as well.
- The paths need to be updated in https://github.com/bitwarden/self-host/blob/main/bitwarden-lite/nginx/logrotate.sh to reference the new rootless paths for nginx
- The remaining files with conflicts need to be resolved.
Once these are done, I have availability to test and get this PR moving again.
Main is merged back in. Will address 1 and test again soon... |
|
@mimartin12 - this is tested against 2026.5.0 and ready to go |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Thanks! I have looped in the QA team for some additional testing; this can take some time, but I am eager to get this in. I will follow up when we have results. |
|
@mimartin12 any updates? ETA? |
| - bitwarden:/etc/bitwarden | ||
| - logs:/var/log/bitwarden | ||
|
|
There was a problem hiding this comment.
The named volume here won't work as is. The comment mentions bind mount, but we should stick to named volumes for convenience if we want to make this the default, uncommented config.
@kaysond do you know how we can remain with named volumes? I know that RedHat utilizes group 0, chmod -R g=u for OpenShift images, and could be used here for /etc/bitwarden.
https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/images/creating-images
There was a problem hiding this comment.
That's a good point. Is there a particular reason you want named volumes? Bind mounts are the de facto standard in the self hosted community (partly for this reason). I'd suggest switching the compose example.
There was a problem hiding this comment.
That's a good point. Is there a particular reason you want named volumes? Bind mounts are the de facto standard in the self hosted community (partly for this reason). I'd suggest switching the compose example.
I think that depends, as far as I have seen most people use named volumes. Especially with Podman.
There was a problem hiding this comment.
Do you have any evidence for your claim? Take a look at the docker compose examples for all the LSIO containers - they're all bind mounts. Bind mounts are much easier for permissions and backups, which is why they're used more. Related - Podman is far less popular than docker.
There was a problem hiding this comment.
For the sake of simplicity and ease of use.
My concern is the tradeoff. Rootless gives you better security, but it also means users have to set up the bind mounts themselves. That's a reasonable ask if you're already savvy enough to run a rootless container. As a default, though, it puts that on every user, not just the ones who opted in. That's a higher bar and more friction for people who just want to get running with Lite.
There was a problem hiding this comment.
Do you have any evidence for your claim? Take a look at the docker compose examples for all the LSIO containers - they're all bind mounts. Bind mounts are much easier for permissions and backups, which is why they're used more. Related - Podman is far less popular than docker.
We are discussing this a bit more internally, stand by.
There was a problem hiding this comment.
@mimartin12 - well shoot. I'd written and submitted a response but github was in review mode so it just sat pending.
I completely understand the desire to keep the deployment simple. That being said, the only extra thing that needs to happen is a single chmod (and possibly a mkdir; docker will create the directory if it doesn't already exist, but the user could do it in advances).
Is it more friction than not having to run the commands? Technically, yes. But enough to really matter? I don't think so.
I've rebased to 2026.6.2 and implemented the following suggestions: switch to bind mount and add a more detailed comment including the mkdir/chmod commands. Left a comment with options for named volumes (rootless daemon or podman) and why rootless -container- + bind mount is the default.
As an extra step to reduce on-boarding friction, there's a check to the entrypoint that runs if the container user isn't root and lists any files with incorrect permissions along with a user-friendly message on how to fix things. This is the approach that LSIO takes.
I'd really urge you to ship rootless+bind mounts in the example, as something like bitwarden especially deserves the extra security by default.
mimartin12
left a comment
There was a problem hiding this comment.
Hey @kaysond,
The team and I have discussed it, and we would like these changes to be opt-in, rather than default. A hardened config provided in a commented block in the docker compose would be easy for an experienced hoster to grab and modify where needed.
For changes such as the logs, the path can be gated by a variable. Let me know if you have any questions.








🎟️ Tracking
Fixes #247 and bitwarden/server#2903
📔 Objective
Support running the unified container fully rootless and/or with a readonly root filesystem. See the commit message for a detailed listing of the changes.
Generally, the strategy is to move everything into
/etc/bitwardenin the container, which must be bind-mounted out to the host where the permissions can be managed (specifically, the user specified must have r/w). There are a few files created by the entry point that are needed in other locations. These are addressed with soft links in the image. supervisord and nginx pid/temp/etc files are moved to /tmp, following convention.Note that I left the PUID/PGID environment variables and behavior for the sake of not introducing breaking changes. However, I would strongly urge you to remove them (I can do that in this PR if you'd like). Though it can be convenient to start as root to set everything up then drop privileges for running the actual service, it needlessly increases the attack surface. Having a single directory to chmod/chown on the host is very simple. Given the importance of security for a password manager, I updated the example docker compose file and settings to be the most secure ("true" rootless, read only filesystem, no new privileges).
Also note that not every configuration will work. For example, if you run with PUID/PGID, but want a read only file system, the container fails trying to add the group because it can't write to /run. (Using
user:works fine, though, because group/user creation is skipped). This is a another argument for removing the env vars.Built and tested (briefly) using bitwarden/server@27606e2. I'd encourage further testing before merging.
📸 Screenshots
⏰ Reminders before review
🦮 Reviewer guidelines
:+1:) or similar for great changes:memo:) or ℹ️ (:information_source:) for notes or general info:question:) for questions:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion:art:) for suggestions / improvements:x:) or:warning:) for more significant problems or concerns needing attention:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt:pick:) for minor or nitpick changes