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

Running LiteFS in Docker #223

Closed
hananbnz opened this issue Dec 13, 2022 · 3 comments
Closed

Running LiteFS in Docker #223

hananbnz opened this issue Dec 13, 2022 · 3 comments
Labels
question Further information is requested

Comments

@hananbnz
Copy link

hananbnz commented Dec 13, 2022

Hi,
I am new to LiteFS and I'm trying to run LiteFS with my Go app on Docker container.
To clarify, I’m not planning on using Fly.io for the near future.
Working on docker container with LiteFS raise some security concerns.
Below I describe my setup and my questions, thanks.

My base image is alpine and this is my Dockerfile:

WORKDIR /af-litefs-poc

COPY go.mod ./
COPY go.sum ./
RUN go mod download

COPY *.go ./

RUN apk add build-base

RUN go build -o main .

# af-litefs-poc listens on 8081 so we'll copy it. Health-checks are configured to listen on 8081 for now as well with
# localhost:8081/readiness
EXPOSE 8081

# Because our main process is LiteFS that runs our Handler go app as a sub process so the command to run our app -
#   CMD ["/af-litefs-poc/main"]
# will be executed within the LiteFS process. Therefore the command will be in the etc/litefs.yml file under `exec`

# Our final Docker image stage starts here - LiteFS is the main process
FROM alpine

# Copy binaries from the previous build stages.
COPY --from=builder /af-litefs-poc /usr/local/bin/af-litefs-poc
COPY --from=litefs /usr/local/bin/litefs /usr/local/bin/litefs

# Copy our LiteFS configuration.
ADD etc/litefs.yml /etc/litefs.yml

# Setup our environment to include FUSE & SQLite.
RUN apk add bash curl fuse sqlite

# Ensure our mount & data directories exists before mounting with LiteFS.
RUN mkdir -p /data /mnt/data

ENTRYPOINT "litefs"

After I build the image if I try to run my container using the following command:
docker run -d -p 8081:8081 litefs_app
I get the following error:

E2022-12-13T13:06:44.997875016Z config file read from /etc/litefs.yml
]2022-12-13T13:06:45.002532068Z primary lease acquired, advertising as http://localhost:20202
p2022-12-13T13:06:45.003717968Z mount helper error: fusermount: fuse device not found, try 'modprobe fuse' first
k2022-12-13T13:06:45.003738443Z cannot init file system: cannot open file system: fusermount: exit status 1
A2022-12-13T13:06:45.003742501Z exiting primary, destroying lease

After some research (including in Fly.io community) I added --cap-add SYS_ADMIN --device /dev/fuse or --privileged to my docker run command, so the full command can be one of the two:
docker run --cap-add SYS_ADMIN --device /dev/fuse -d -p 8081:8081 litefs_app
or
docker run --privileged -d -p 8081:8081 litefs_app
With those commands, the container is up and working.
Is there a way to avoid those flags when working on a docker container with LiteFS?

Specifically using --cap-add SYS_ADMIN and --privileged that of course raise security concerns.
From what I understand using one of the above is inevitable for LiteFS as those kernel capabilities are required to mount filesystems-->the FUSE file system that is used in LiteFS.
So my questions in terms of security and functionality are as follows.

  • What are the capabilities and resources the LiteFS require from the operating system?
  • Can someone describe the privileged given to a container in order to use LiteFS with SQLite and dynamic lease (Consul)?
  • Can those requirements be much more specific requirements in order to limit the securities issues in giving a container extra capabilities on the operation system?

I will really appreciate any helpful input regarding those issues.
Thanks

@benbjohnson
Copy link
Collaborator

@hananbnz From my understanding, --cap-add SYS_ADMIN is required for FUSE in Docker but --privileged is not. I was able to get this Dockerfile running:

FROM alpine
COPY --from=litefs /usr/local/bin/litefs /usr/local/bin/litefs
ADD litefs.yml /etc/litefs.yml
RUN apk add bash curl fuse sqlite
ENTRYPOINT litefs

with this command:

$ docker build -t litefs-docker-test .
$ docker run --device /dev/fuse --cap-add SYS_ADMIN litefs-docker-test

The --device /dev/fuse was needed if I didn't have --privileged set.

This comment on a different issue seems to indicate that you can use seccomp to avoid SYS_ADMIN.

What are the capabilities and resources the LiteFS require from the operating system?

In addition to capabilities required by vanilla SQLite (file read/write), LiteFS needs to be able to access /dev/fuse, mount a file system, listen on a port, and send network requests.

Can someone describe the privileged given to a container in order to use LiteFS with SQLite and dynamic lease (Consul)?

Maybe I'm misunderstanding but that seems similar to the previous question.

Can those requirements be much more specific requirements in order to limit the securities issues in giving a container extra capabilities on the operation system?

Yeah, the biggest limitation seems to be restricting FUSE within Docker. Otherwise, LiteFS doesn't need a lot from the OS.

@benbjohnson benbjohnson changed the title New to LiteFS - I’m trying to run LiteFS with my app on a docker container Running LiteFS in Docker Dec 14, 2022
@benbjohnson benbjohnson added the question Further information is requested label Dec 14, 2022
@hananbnz
Copy link
Author

@benbjohnson Thanks for your answers.

In addition to capabilities required by vanilla SQLite (file read/write), LiteFS needs to be able to access /dev/fuse, mount a file system, listen on a port, and send network requests.

Because I'm trying to minimize the permissions I give a container, I would like to make sure of the following -
From what I understand the mount is for the mount-dir and data-dir on the container itself. Do we have a mount that is done on the host itself?

In other words, LiteFS should only need to access the /dev/fuse device file once, when the file system is being mounted. Once the file system (above directories) is mounted, the FUSE kernel module will handle all subsequent communication with the file system and we don't need any special privileged from the host. is that right?

Thanks

@benbjohnson
Copy link
Collaborator

In other words, LiteFS should only need to access the /dev/fuse device file once, when the file system is being mounted. Once the file system (above directories) is mounted, the FUSE kernel module will handle all subsequent communication with the file system and we don't need any special privileged from the host. is that right?

Yeah, my understanding is that it gets a file descriptor for /dev/fuse on mount and communicates over that. I would assume that removing access to /dev/fuse after that wouldn't affect the already opened descriptor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants