mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-05-30 23:40:40 +02:00
[Bug]: Unable to start container with non-root user #2880
Open
opened 2026-04-25 00:11:29 +02:00 by adam
·
13 comments
No Branch/Tag Specified
master
book_tags_genres_dedupe
episode_download_fallback
Issue-4540-SortBy-StartedDate-and-FinishedDate
episode_meta_tagging
fix_authorize_race_condition
redirect_transcode_requests
progress_updated_sort
fix_ereader_socket_event
fix_change_empty_root_password
fix_podcast_session_track_index
fix_set_token
session_modal_user
localize_durations
fix_oidc_create_user
jwt_auth_refactor
fix_scanner_deleting_single_file_books
fix_mediaprogress_updatedat_2
experimental_next_client
podcast_episode_duration
episode-timestamps-clickable
book_author_secondary_sort_title
podcast_useragents
pathexists_user_access
fix_pathexists_join
book_author_secondary_sort
clean_duplicate_mediaprogress
sanitize_html_description
trix_prevent_attachments
check_path_api_fix
fix_mediaprogress_updatedat
increase_express_json_limit
fix_dockerfile_nunicode
search_episodes
audiobook_tools_update
episode_secondary_sorts
hls_stream_url_update
new_session_track_endpoint
audiobook_tools_enhancements
watcher_rescans_update
player_track_tooltip
fix_exclude_prefixes_crash
socket_item_events
fix_podcast_episode_scanner_promise
new_stats_controller
count_cache_for_userpermissions
parsing-opf-v3
validate_migration_files
fix-quick-match-all-crash
fix-chapter-end-sleep-timer
stringify_sequelize_query
remove-col-ambiguity
fix_next_prev_edit_description
details_trim_whitespace
fix_content_url_basepath
fix_logger_fatal
progress_bar_visibility
batch-edit-populate-map-details
feed_generator_updates
bookmark-modal-updates
migrate-library-item-in-scanner
migrate-new-library-items
migrate-podcasts-new-library-item-2
migrate-podcasts-new-library-item
fix-remove-episode-from-playlist
playback-session-use-new-library-item
refactor-library-item
fix-heatmap-caption
feed-episodes-upsert
share-media-player-media-session-api
remove-old-playlist
remove_old_collection_object
plugin-implementation-demo
feed_migration
refactor-feeds-from-item
fix_remove_authors_no_books
v2.17.3-fk-constraints-migration
migrations-first-upgrade
sqlite_2
feature/nuxt-target-server
waveform
sqlite
playlists
video
v2.35.1
v2.35.0
v2.34.0
v2.33.2
v2.33.1
v2.33.0
v2.32.1
v2.32.0
v2.31.0
v2.30.0
v2.29.0
v2.28.0
v2.27.0
v2.26.3
v2.26.2
v2.26.1
v2.26.0
v2.25.1
v2.25.0
v2.24.0
v2.23.0
v2.22.0
v2.21.0
v2.20.0
v2.19.5
v2.19.4
v2.19.3
v2.19.2
v2.19.1
v2.19.0
v2.18.1
v2.18.0
v2.17.7
v2.17.6
v2.17.5
v2.17.4
v2.17.3
v2.17.2
v2.17.1
v2.17.0
v2.16.2
v2.16.1
v2.16.0
v2.15.1
v2.15.0
v2.14.0
v2.13.4
v2.13.3
v2.13.2
v2.13.1
v2.13.0
v2.12.3
v2.12.2
v2.12.1
v2.12.0
v2.11.0
v2.10.1
v2.10.0
v2.9.0
v2.8.1
v2.8.0
v2.7.2
v2.7.1
v2.7.0
v2.6.0
v2.5.0
v2.4.4
v2.4.3
v2.4.2
v2.4.1
v2.4.0
v2.3.5
v2.3.4
v2.3.3
v2.3.2
v2.3.1
v2.3.0
v2.2.23
v2.2.22
v2.2.21
v2.2.20
v2.2.19
v2.2.18
v2.2.17
v2.2.16
v2.2.15
v2.2.14
v2.2.13
v2.2.12
v2.2.11
v2.2.10
v2.2.9
v2.2.8
v2.2.7
v2.2.6
v2.2.5
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.5
v2.1.4
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.24
v2.0.23
v2.0.22
v2.0.21
v2.0.20
v2.0.19
v2.0.18
v2.0.17
v2.0.16
v2.0.15
v2.0.14
v2.0.13
v2.0.12
v2.0.11
v2.0.10
v2.0.9
v2.0.8
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v1.7.2
v1.7.1
v1.7.0
v1.6.0
v1.5.5
v1.5.0
v1.4.11
v1.4.9
v1.4.7
v1.4.6
v1.4.4
v1.4.2
v1.4.0
v1.4.1
v1.3.4
v1.3.3
v1.3.1
v1.2.8
v1.2.6
v1.2.5
v1.2.4
v1.2.1
v1.1.15
v1.1.14
v1.1.13
v1.1.12
v1.1.11
v1.1.10
v1.1.9
v1.1.8
v1.0.0
0.9.61-beta.0
0.9.61-beta
Labels
Clear labels
authentication
backlog
bug
chapter editor
config-issue
ebooks
encoding/embedding
enhancement
help wanted
listening sessions & progress
planned
possible plugin
progress sync
pull-request
sorting/filtering/searching
unable to reproduce
upload
users & permissions
waiting
Mirrored from GitHub Pull Request
No Label
bug
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
adam (Adam Melkus)
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/audiobookshelf#2880
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @mill1000 on GitHub (Jul 10, 2025).
What happened?
When attempting to run audiobookshelf via Docker as a non-root user the container is unable to start due to EACCES: permission denied errors.
What did you expect to happen?
The container to start normally as a non-root user.
Steps to reproduce the issue
docker compose upAudiobookshelf version
v2.25.1
How are you running audiobookshelf?
Docker
What OS is your Audiobookshelf server hosted from?
Linux
If the issue is being seen in the UI, what browsers are you seeing the problem on?
None
Logs
Additional Notes
No response
@advplyr commented on GitHub (Jul 10, 2025):
Abs needs write access to the /config and /metadata folder
@mill1000 commented on GitHub (Jul 10, 2025):
Sure of course, but by setting permissions appropriately we can allow non-root users. I made a small PR #4474 to demonstrate.
@advplyr commented on GitHub (Jul 10, 2025):
Ah I see. The key part that I forgot about is that Docker automatically creates folders for volume mounts if they don't already exist. Do you know if there is a way to have Docker use the user passed into the command to create the folders instead of using root?
@mill1000 commented on GitHub (Jul 15, 2025):
At runtime? I think the container is running as the specific user immediately if using the
useroption.I looked at few other implementation. It appears some take UID and GID an environmental vars (instead of user), then tweak permissions & user IDs before dropping permissions when running the final app.
@plz12345 commented on GitHub (Aug 3, 2025):
I'm hitting this too, while trying to migrate an existing working container from Synology to Unraid. Unraid is pretty restrictive on file permissions, so this design is causing issues. The docker file is trying to force the creation of folders that are already there, and I believe it is also ignoring/not leveraging the Docker
userdirective, as well asUIDandGID, all of which are a common standard for running as non-root user.The expectation is to have these two paths volume-mounted, not created within the container, is it not? The app should only need to write inside them, not create them, and at that, only as the passed-in user, not root.
If so, you should just respect the UID/GID pattern (or Docker's
userdirective), and handle the volumes like other conatiners doing identical "config" and "metadata" things.Example, in your dockerfile you would have just the app-internal volume definitions, leaving the user to add their own for
/audiobooks,/podcasts, etc. You'd edit themkdirline to just/configand/metadatafor these mount points entirely.https://docs.docker.com/reference/dockerfile/#volume
and the user would have Volume mount to those that they pass in via CLI or via Docker Compose, like below.
From my container console
Note: I've never built a container before, so I'm just going off the official docs and other example dockerfiles I've seen.
@Vylyne commented on GitHub (Sep 25, 2025):
It seems like the standard solution used by groups like the linuxserver.io and others is to use PID and GID Environment variables, instead of the user directive for this, probably because of the issue you're asking about @advplyr as docker is running as root it will create the missing folders as root but if the container is running as something else like 1000:1000 it wont' have write access can't chown or chmod it can't do anything. Until someone intervenes...
With the PUID and PGID environment variables you should be able to chown the files as root to be owned by the PUID:PGID specified int he those variables when the container starts or in the dockerfile then just have the service start as as that user/group Instead of letting it run as root.
@Vylyne commented on GitHub (Sep 26, 2025):
Okay took a crack at this. And I've created a draft pull request. Feel free to take a look. #4700
@Vylyne commented on GitHub (Sep 30, 2025):
I've actually got another way to think about this user directive now other then the PUID GUID environment variables.
Further investigation into how the USER directive works is that it overrides what user is used to execute the entrypoint. So, basically anything that the needs to read, has to be world readable, and anything it needs to write world writable. So this can actually be fully handled in the dockerfile, I think. I'd need to look at the code again with this in mind rather then my above PR.
What' I'd do is add ARGs for UID and GID, and default them to the IDs currently used. Then make sure to chmod everything that the service touches to make sure "others" would have the permissions to do what ever the service needs. because the UID and GID that is supplied via user is not generally root and won't have privileges to fix permissions and ownership... Hell most likely doesn't even exist in the container. :)
Basically the Issue of the folders being auto created by the docker service is not addressed but you can precreate them and define what user you want them to be owned by then launch the container with the user directive. This also boosts security because nothing is running as root in the container anymore so a break out would still be a less privileged user.
@mill1000 commented on GitHub (Oct 3, 2025):
That was basically my quick solution in #4474, pre-create and chmod the directories so they're world accessible.
@mill1000 commented on GitHub (Jan 2, 2026):
I took another look at this and updated my PR to use the VOLUME instruction that @plz12345 highlighted as well.
Adding VOLUME helps tell the user "hey you should be mounting something here", and causes docker to create anonymous volumes if no mount point is setup.
I also tested @Vylyne PR and it worked too. It has the advantage of also defaulting to non-root. It could probably benefit from adding the VOLUME instruction too.
@advplyr Anything that's preventing either of these solutions from moving forward?
@Zie0 commented on GitHub (Feb 19, 2026):
Any chance this will be addressed soon?
I run all my self-hosted services with podman quadlet and ABS is the only of eleven that requires that it's run as root. This messes up bind mounts for other services to the point that ABS is requiring that I run my other services as root too. I like ABS, but this has been frustrating the way I've had to adjust the deployment of other services and my file system permissions to accommodate it. I saw this was opened when I ran into this months ago and kept using ABS expecting after seeing the MR that appears to resolve it. I figured this wouldn't be a problem for long.
@Vylyne commented on GitHub (Feb 20, 2026):
I'd suggest we open the VOLUME instruction request as a Feature Request so it can have it's own discussion/change tracked appropriately. It probably makes sense for the mandatory volumes (/config /metadata) As stated above.
I've added the VOLUME instruction to my dev and main(ghcr.io/vylyne/audiobookshelf:latest) branches, not my PR for now. If we get any feedback from the people who maintain this project we can see where we go from there but I'll probably incorporate it into my main after a while not sure I'll add it to my non-root PR, at last not without feedback from the maintainers of this project.
@Zie0 commented on GitHub (Feb 24, 2026):
Turns out it was user error on my part that made me need to run my other services as root too. I was using the SELinux
:Zoption for the volumes mounted by audiobookshelf (while it was run as root) instead of the:zoption. I can run my other podman quadlet services rootless now too after updating that option for all shared mounted volumes.