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

Containers: overriding HOME environment variable with mismatching /etc/passwd home causes issues #1146

Closed
hoxu opened this issue Jun 11, 2021 · 5 comments
Labels
bug Something isn't working Runner Bug Bug fix scope to the runner

Comments

@hoxu
Copy link

hoxu commented Jun 11, 2021

GitHub Actions runner currently seems to set container HOME environment variable to /github/home. Unfortunately, this is different from what the home directory is set to in the container's /etc/passwd. For example, if the container is run as root, the home directory in /etc/passwd is usually /root.

This mismatch causes some unexpected issues like making caching more difficult. When caching Java M2 dependencies for example, the following does not work:

- uses: actions/cache@v2
   with:
     key: m2
     path: ~/.m2

This is because the Java user.home property is set to whatever is in /etc/passwd.

Would it be possible to have the runner not change HOME by default?

On a related note, it would be really nice if the GitHub runner's parameters to docker containers were documented clearly somewhere.

@hoxu hoxu added the bug Something isn't working label Jun 11, 2021
@justfalter
Copy link

justfalter commented Nov 9, 2021

I've encountered this issue when two different workflows have executed on the same runner, but with containers running as different users. Files end up in the home directory that are owned by different users, resulting in permission denied errors. This can happen when a container is explicitly executed as a different user (ex: --user node:node), but the user can also be specified via Dockerfile's USER command.

The following will run as root, and create a file in the home directory test-file. This file is owned by uid=0, gid=0.

jobs:
  runs-as-root:
    runs-on: [self-hosted, docker]
    container:
      image: node:latest
    steps:
      - run: |
          id
          touch ~/test-file

The following will do the same as above, but run as the node user with uid=1000, gid=1000. This fails with a Permission denied error because the ~/test-file already exists, but is owned by uid=0, gid=0.

jobs:
  runs-as-node:
    runs-on: [self-hosted, docker]
    container:
      image: node:latest
      options: --user node:node
    steps:
      - run: |
          id
          touch ~/test-file

We've come to the conclusion that the safest course of action is to try to run all containers as the root user, but this can be challenging when some software packages behave differently when running as root (ex: npm version 6 won't execute lifecycle scripts when run as root), while others refuse to run at all (ex: postgresql's pg_ctl refuses to run as root).

@lkebin
Copy link

lkebin commented Nov 10, 2021

I've encountered this issue when I use ssh in container

ssh-keyscan github.com >> $HOME/.ssh/known_hosts

or

ssh-keyscan github.com >> ~/.ssh/known_hosts

After run above command in a container job, ssh client command still get error (Host key verification failed.), because ssh using /root/.ssh directory, but the above command writes to /github/home/.ssh 🤦‍♂️

Insteads, I've run that command with /root/.ssh/known_hosts directly.

@bschaatsbergen
Copy link

bschaatsbergen commented Nov 20, 2021

This is actually a pretty annoying issue, e.g. installing binaries into /root (as suggested by the Github Actions docs we should base our image of a Debian distro). Which has $HOME mapped to /root/

Whilst in the container context home turns out to be /github/home.

There's a lot of install scripts that contain ~ in the path for installing binaries.

E.g. https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh

FROM debian:latest

# install build dependencies
RUN	apt-get update && apt-get install -y \ 
  curl 

# install cloudformation-guard
RUN curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh 

# add guard to path
ENV PATH="~/.guard/bin/cfn-guard:${PATH}" <---- this will conflict with the HOME directory if the container now runs in Github its context.

@justfalter
Copy link

It looks like this also affects tool cache directories, as I just had a build fail in actions/setup-node with an EACCES error. First workflow on the runner executed as the root user, and the second (failing) workflow executed the container as a non-root user.

Error in actions/setup-node:

Adding to the cache ...
Error: EACCES: permission denied, mkdir '/__w/_tool/node/12.20.1'

When the container was created, the tool cache directory (among many others) is mounted in as a volume:

/usr/bin/docker create 
--name [snipped] 
--label [snipped] 
--workdir /__w/asset-prep/asset-prep 
--network github_network_b67ddc2a8c634aa39b594c71fafb8f9b 
--user notroot:notroot 
-e "HOME=/github/home"
-e GITHUB_ACTIONS=true
-e CI=true
-v "/var/run/docker.sock":"/var/run/docker.sock"
-v "/home/actions-user/actions-runner/_work":"/__w"
-v "/home/actions-user/actions-runner/externals":"/__e":ro
-v "/home/actions-user/actions-runner/_work/_temp":"/__w/_temp"
-v "/home/actions-user/actions-runner/_work/_actions":"/__w/_actions"
-v "/home/actions-user/actions-runner/_work/_tool":"/__w/_tool"
-v "/home/actions-user/actions-runner/_work/_temp/_github_home":"/github/home"
-v "/home/actions-user/actions-runner/_work/_temp/_github_workflow":"/github/workflow" 

--entrypoint "tail" [snipped]:latest "-f" "/dev/null"

I imagine that this issue could manifest in many different ways.

@ruvceskistefan ruvceskistefan added the Runner Bug Bug fix scope to the runner label Mar 31, 2022
@nikola-jokic
Copy link
Contributor

Hi everyone,

To help you with the workaround, I will provide more context to this issue and close it in favour of #863. We are aware of the permissions problem illustrated by issue #434.

The runner will mount docker volumes as you described above. Files you created inside this docker container will be owned by the corresponding user on your host machine, so if you created a file as a root user inside the mounted volume inside the container, it will be owned by the root outside of it. More generally, if you have a user with UID 1000 (let's call it user user1) inside the container, and you have a user with UID 1000 outside of the container on your machine (let's call that user runner), files created by the user1 inside the container will be owned by the user runner on your host machine. This will cause you issues if you create a user inside the container with UID that does not match any UID on your host machine.

That being said, we are aware of that problem and it is in our backlog. For updates on this issue please refer to the issues I have linked. Since we have this issue linked as well, it won't be hard for us to find it when we start testing the fix.

I am sorry this issue is bothering you and I hope the explanation above helped a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Runner Bug Bug fix scope to the runner
Projects
None yet
Development

No branches or pull requests

6 participants