Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run the Seafile server with user other than root #86

Closed
fakuivan opened this issue Jul 27, 2018 · 31 comments
Closed

Run the Seafile server with user other than root #86

fakuivan opened this issue Jul 27, 2018 · 31 comments

Comments

@fakuivan
Copy link
Contributor

To facilitate migration from the native environment where seafile ran as a regular user (other than root). The server can then run under UID of the user that owned the server files previously.
I suppose this can also be taken advantage of by more paranoid users that don't like WWW services to be unnecessarily run as root, even on containers.

@languitar
Copy link

This is more or less a duplicate of #22, which isn't resolved at all. With a custom user specified via docker, start up fails with this exception:

Traceback (most recent call last):
  File "/sbin/my_init", line 414, in <module>
    main(args)
  File "/sbin/my_init", line 330, in main
    import_envvars(False, False)
  File "/sbin/my_init", line 90, in import_envvars
    for envfile in listdir("/etc/container_environment"):
  File "/sbin/my_init", line 74, in listdir
    return sorted(os.listdir(path))
PermissionError: [Errno 13] Permission denied: '/etc/container_environment'

@shoeper
Copy link
Collaborator

shoeper commented Aug 10, 2018

This is inherited from phusion/baseimage-docker#264

Looks like my_init being used requires root privileges. It should be configured to start Seafile as seafile, though.

@languitar
Copy link

I tried to implement this for a second, but somehow start up stopped at some point and then I gave up on this.

@fakuivan
Copy link
Contributor Author

fakuivan commented Aug 10, 2018

You don't need to run all processes as an unprivileged user, just the seafile components (the setup script, seahub.sh, seafile.sh, sf-gc.sh, etc.). Things like mariadb and nginx can run as root because they manage those privileges correctly and fork when needed. The seafile components are ment to be run as unprivileged.

@shoeper
Copy link
Collaborator

shoeper commented Aug 10, 2018

Maybe the easiest would be to add a seafile user and run start.py using su seafile -c "/scripts/start.py" https://github.com/haiwen/seafile-docker/blob/master/image/seafile/Dockerfile#L18

GC and so on could then be run using docker exec -useafile -it seafile bash (or directly without first entering the bourne-again shell) or using su seafile within the container.

Just changing this would lead to an issue though: existing setups would have broken permissions (and some paths need new permissions anyway to make this work). Fixing permissions on start could be an option but doing it naively would take quite some time for larger setups with millions of files.

The best would be if user scripts would also deny running them without using the seafile user within the docker container.

@fakuivan
Copy link
Contributor Author

I don't think this should be enforced, but optional. UID and GID variables can be passed to the container intead of hardcoring one, if those are not set then the seafile components should be just run as root

@stale
Copy link

stale bot commented Nov 26, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Nov 26, 2018
@fakuivan
Copy link
Contributor Author

This has not been resolved so don't close it

@stale stale bot removed the wontfix label Nov 26, 2018
@Lordroran
Copy link

Is this possible with Seafile 7? This Issue is the only Thing blocking me from using Seafile on Docker.

@fakuivan
Copy link
Contributor Author

@Lordroran I doubt it, the nginx server still runs on the container

@renfeipeng
Copy link
Contributor

We think that the nginx direction proxy is a component we must rely on, it is necessary to put it in the same container.

@fakuivan
Copy link
Contributor Author

fakuivan commented Aug 27, 2019

@renfeipeng This is not about nginx running as root, the problem is having seafile and seahub running as root. Even starting them using sudo -u seafile "..." could be a viable option.

@fakuivan
Copy link
Contributor Author

@renfeipeng Why is this closed considering the previous comment?

@mishka81
Copy link

Problem is still present with seafile 7 image.

@shoeper shoeper reopened this Jan 1, 2020
@techmunk
Copy link

techmunk commented Jan 11, 2020

I was able to get this to work with the following configuration:

docker-compose.yml

seafile:
    image: docker.seadrive.org/seafileltd/seafile-pro-mc:latest
    entrypoint: /usr/local/bin/entrypoint.sh
    volumes:
      - type: bind
        source: /etc/localtime
        target: /etc/localtime
        read_only: true
      - type: bind
        source: ./entrypoint.sh
        target: /usr/local/bin/entrypoint.sh
        read_only: true
      - type: bind
        source: ./gosu
        target: /usr/local/bin/gosu
        read_only: true
      - type: bind
        source: ./seafile
        target: /shared
        read_only: false

entrypoint.sh

#!/bin/bash

addgroup --gid 988 seafile
useradd -s /bin/bash -u 1000 -m -d /home/seafile -g seafile -k /dev/null seafile

chown seafile:seafile /opt/seafile

sed -i 's!{} start!/usr/local/bin/gosu seafile:seafile {} start!g' /scripts/start.py

/sbin/my_init -- /scripts/start.py

gosu was downloaded from https://github.com/tianon/gosu/releases

Update the uid and gid in the entrypoint.sh script as required. Don't forget to set the mounted "/shared/seafile" folder to be owned by the same uid:gid.

@lowne
Copy link

lowne commented Jan 22, 2020

To improve upon @techmunk's excellent solution, it's possible to bake it into the image; among other things, this allows the container to be restarted without exploding:

Dockerfile:

FROM {{ hub_image }}
RUN apt-get update && apt-get -y -qq install gosu && rm -rf /var/lib/apt/lists/*
COPY imagesetup.sh /
RUN /imagesetup.sh && rm /imagesetup.sh

imagesetup.sh:

#!/bin/bash

# https://github.com/haiwen/seafile-docker/issues/86#issuecomment-573274807

GROUPNAME=$(getent group "{{ PGID }}" | cut -d ':' -f 1)

if [ -z $GROUPNAME ]
then
	addgroup --gid {{ PGID }} seafile
	GROUPNAME=seafile
fi

useradd -s /bin/bash -u {{ PUID }} -m -d /home/seafile -g $GROUPNAME -k /dev/null seafile
sed -i 's!{} start!/usr/sbin/gosu seafile:'$GROUPNAME' {} start!g' /scripts/start.py
chown seafile:$GROUPNAME /opt/seafile

# memcached host is hardcoded, gotta override
# sed -i 's!memcached:11211!{{ mc_svc_name }}:11211!g' /scripts/bootstrap.py

The last line is only relevant if you want/need to rename the memcached host in your setup.

@svengreb
Copy link

svengreb commented Aug 7, 2020

My experience

I've also tried to run the Seafile server and SeaHub as non-privileged user using a custom Dockerfile similar to the one @lowne posted (using RUN statements instead of a separate script). It started without errors, at least after the 2nd container start because one needs to change the Linux filesystem ownership of the directories that have been created by the bootstrap script to the custom user (seafile in my case with UID/GID 5000:5000).
Unfortunately the first problems occurred right after browsing to the login page was loaded without any CSS, JS and images. It was caused by a 403 Forbidden HTTP status code to the /media/* path that is defined in the nginx.conf to point to /opt/seafile/seafile-server-latest/seafile. I tired multiple other ways to solve this, e.g. by allowing various security-related headers, adding additional Traefik routers and middleswares for the /media/* path, and some more. Even changing the ownership of the whole /opt/seafile and /shared paths to my custom user failed. Strangely enough the only workaround that worked was to remove the whole location /media block from nginx.conf, but that's definitely not what you want.

Long story short: I ended up running the Seafile server as root for now until there's maybe official support for custom Docker users. Even if I had made it work without the strange workaround described above there are still other processes next to Seafile itself that are running in the container as root like e.g. multiple ones from nginx. These are way harder to “fix“ since it is not possible to start a process as non-root user that binds to a port <1024 due to (absolute legitimate) Linux security policies. So finding a working way for Seafile to run as non-privileged user is still not enough to run the container without root at all.

Optimal solution

Even though the seafileltd/seafile-mc Docker image is a great improvement through the decoupling of the database and cache into their own containers, in my opinion the only way would be to split the stack even more by getting rid of running multiple processes in a single Docker container like e.g. nginx. Instead of relying on a proxy to route requests to the services, the internal structure needs to be refactored so every component can run in it's own container and requests are routed by components that have been designed for it (e.g. Docker Compose/Swarm ports, external routers like Traefik or Kubernetes Ingresses).

Better way to handle “hardcoded“ memcached network name/alias

This is a bit unrelated to the main topic of this issues, but I thought it might help others that stumble across here.
@lowne posted a simple way to solve the problem of the “hardcoded“ network/alias name for the memached component that is defined in the seahub_settings-py file:

# sed -i 's!memcached:11211!{{ mc_svc_name }}:11211!g' /scripts/bootstrap.py

This “fix“ works when using a custom Dockerfile but might be a blocker again for other who don't want or can do it and need another way.

I've tried to “fix“ this by simply following the official Seafile documentations about how to add memcached, but for some reason the CACHES object in seahub_settings.py is not respected, not even after deleting the __pycache__ directory (Python is a terrible language 😣).
In the end I've solved it for my Docker Compose setup by using a network alias for my service that is named seafile-cache instead of memcached. Here's a stripped down example of how to use it:

version: "3.7"
services:
  seafile:
    image: seafileltd/seafile-mc:7.1.4
    networks:
      - seafile-net
    # ...

  seafile-db:
    image: mariadb:10.5.4
    networks:
      - seafile-net
    # ...

  seafile-cache:
    image: memcached:1.6.6
    networks:
      seafile-net:
        aliases:
          # Make this service available through the "memcached" alias.
          # This is required since the name is hardcoded in the SeaHub source code and configurations in
          # the "seahub_settings.py" are not respected.
          # See:
          #   - https://github.com/haiwen/seafile-docker/blob/55930f2/scripts/bootstrap.py#L154
          #   - https://github.com/haiwen/seafile-docker/issues/86#issuecomment-670362046
          #   - https://docs.docker.com/compose/compose-file/#aliases
          - memcached
    # ...

This way my memcached container is reachable for all other containers in the seafile-net netwotk through the seafile-cache and memcached name which make a change in the scripts/bootstrap.py file unnecessary. Using a network alias doesn't require to change actual source code and makes the setup compatible for changes in future versions.

@bryanc12
Copy link

bryanc12 commented Mar 9, 2022

Is this problem solved?

@fakuivan
Copy link
Contributor Author

fakuivan commented Mar 9, 2022

@bryanc12 not solved as of right now

@bryanc12
Copy link

bryanc12 commented Mar 9, 2022

@bryanc12 not solved as of right now

Is this improvement on the worklist anytime soon?

@freaky-m0
Copy link

I'm at the point where I need to migrate my Rocky Linux installation because centOS support ist dropped now. I wanted to use docker, but this is holding me back. I don't know why "productive" containers with root still exist? I can find articles even from 2017 that say, that containers with root are not a good idea ;). Is there anything on the roadmap to fix this? Thanks in advance.

@LucaDanelutti
Copy link

Are there any new on this?

@paukr
Copy link

paukr commented Jan 6, 2023

Trying to build my own docker image using SQLite, I found that there is a non-documented environment variable NON_ROOT, which you can set in the docker-compose.yml. This will create a non-root user seafile and start the seafile server and seahub server using that user (the rest, e.g. nginx will still run a s root).
From my point of view this needs some rework, for example nginx should not be part of this image at all (I would prefer Traefik as I use it for other services already). Hard coding the ports 80/443 into the image and config is also not ideal.

@ggogel
Copy link

ggogel commented Feb 12, 2023

I'm at the point where I need to migrate my Rocky Linux installation because centOS support ist dropped now. I wanted to use docker, but this is holding me back. I don't know why "productive" containers with root still exist? I can find articles even from 2017 that say, that containers with root are not a good idea ;). Is there anything on the roadmap to fix this? Thanks in advance.

Excuse me but I think that you and some other users in this thread are misunderstanding a couple of things here.

The root user inside the container does not equal the host root user. The container runtime controls root access to the host system with so called capabilities. If those are not set, the users inside the container have no root access on the host.

What you probably read about is running the container runtime itself as non-root user, also called rootless. Docker has introduced this as experimental feature and there are runtimes, like CRI-O, which run rootless by default.

@JokerQyou
Copy link

@ggogel I think some of us are just tired of getting files owned by root (the host root) on the host side. It's very hard to backup or migrate those files.

@ggogel
Copy link

ggogel commented Feb 13, 2023

@JokerQyou As I already explained in my repository, the only proper solution for this is running a rootless container runtime, which solves the problem at the root. Pun not intended. Otherwise you'll just end up trying to find workarounds for each and every deployment.

@freeplant
Copy link
Member

Since version 10, Seafile docker can be run with non root user: https://manual.seafile.com/docker/deploy_seafile_with_docker/#run-seafile-as-non-root-user-inside-docker

Feedbacks are welcome.

@kanpov
Copy link

kanpov commented Jun 4, 2024

Since version 10, Seafile docker can be run with non root user: https://manual.seafile.com/docker/deploy_seafile_with_docker/#run-seafile-as-non-root-user-inside-docker

Feedbacks are welcome.

Why is there a limitation that the rootless user must be called seafile? Is it possible for the devs to make an environment variable for specifying another username?

@freeplant
Copy link
Member

We think making the user changable adding unnecessary complexity to the Seafile docker. We don't have a plan to support it.

@Neurrone
Copy link

Neurrone commented Jun 5, 2024

I've tried using the solution described in the Seafile documentation. However, it isn't practical for any realistic number of files, since it does a chown recursively for everything, every time the container starts.

@kanpov
Copy link

kanpov commented Jun 5, 2024

We think making the user changable adding unnecessary complexity to the Seafile docker. We don't have a plan to support it.

I've switched to using seafile-containerized since as it seems more polished (bundling nginx inside another image seems questionable) and I've had no issues running it under podman rootlessly. Would be nice to see the official images get more improvements though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests