unity-builder icon indicating copy to clipboard operation
unity-builder copied to clipboard

Running action in self-hosted runner

Open WildEgor opened this issue 3 years ago • 25 comments

Bug description

When using game-ci/unity-builder@v2 on self-hosted linux docker machine some error occurs: /bin/bash: /entrypoint.sh: Is a directory Error: The process '/usr/bin/docker' failed with exit code 126

How to reproduce

  1. Use this repo https://github.com/myoung34/docker-github-actions-runner and run https://github.com/myoung34/docker-github-actions-runner/wiki/Usage docker-compose with correct envs for repo (REPO_URL, ACCESS_TOKEN); 1.1. Optionally, if docker running on Windows bind volumes like this volumes:
    • //var/run/docker.sock:/var/run/docker.sock
  2. See successfully started runner status and trigger action;
  3. When step into build see errors.

Expected behavior

Run and build

Additional details

--volume /_work/_actions/game-ci/unity-builder/v2.1.2/dist/platforms/ubuntu/entrypoint.sh:/entrypoint.sh:z unityci/editor:ubuntu-2020.3.28f1-android-1 maybe this line broken?

WildEgor avatar Nov 14 '22 17:11 WildEgor

Did anyone figure this out?

Brulogaz avatar Dec 16 '22 06:12 Brulogaz

i'm getting the same issue when using act to develop locally

the docker docs seem to say that since entrypoint.sh doesn't already exist it will be created as a directory CleanShot 2023-03-14 at 14 49 17@2x

NorthIsUp avatar Mar 14 '23 21:03 NorthIsUp

i'm getting the same issue when using act to develop locally

the docker docs seem to say that since entrypoint.sh doesn't already exist it will be created as a directory CleanShot 2023-03-14 at 14 49 17@2x

seeing this also

gotchipete avatar May 23 '23 16:05 gotchipete

Has anyone found a solution for this?

MoonmonsterBrian avatar Nov 30 '23 14:11 MoonmonsterBrian

So apparently this doesn't work because of the nature of "Docker in Docker" When a DinD container gets ran, its docker socket gets connected to the host, so it's only a docker client in the container that's looping back and hooking into the main docker daemon on your host.

All the files and everything definitely exist in the DinD container, but the DinD container is looking for them on the host, not in the DinD container. This isn't normally a problem for Github because they run as VMs, not as containers. This seems to be a quirk with nektos/act and I'm currently looking into a way to work around this.

lkkuma avatar Dec 05 '23 18:12 lkkuma

A year later (/j, happy 2024), I come with an update. I've gotten to the point of getting a custom image with docker in docker working consistently and independently from the host. The problem I'm facing now is getting /bin/bash: line 1: /entrypoint.sh: Permission denied when actually running my workflow.

I've reached the point where I want to ask for further help here to figure this out.

Dockerfile

FROM ubuntu:23.10
ARG DEBIAN_FRONTEND=noninteractive

# Install core packages
RUN apt-get update -y && apt-get upgrade -y \
    && apt-get install -y --no-install-recommends \
    sudo=\* \
    curl=\* \
    ca-certificates=\* \
    gnupg=\* \
    apt-utils=\* \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# Install Docker GPG keys
RUN install -m 0755 -d /etc/apt/keyrings && \
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
    chmod a+r /etc/apt/keyrings/docker.gpg

# Add the Docker repository to Apt sources
RUN echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install docker + other needed packages
RUN apt-get update -y && apt-get upgrade -y \
    && apt-get install -y --no-install-recommends \
    git=\* \
    git-lfs=\* \
    tar=\* \
    zstd=\* \
    p7zip=\* \
    jq=\* \
    nodejs=\* \
    build-essential=\* \
    libssl-dev=\* \
    libffi-dev=\* \
    python3=\* \
    python3-venv=\* \
    python3-dev=\* \
    python3-pip=\* \
    docker-ce=\* \
    docker-ce-cli=\* \
    containerd.io=\* \
    docker-buildx-plugin=\* \
    docker-compose-plugin=\* \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# Add a sudo'd non-sudo user
RUN useradd -m -G sudo,docker user && echo "user:user" | chpasswd
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# Preemptively create and chown docker socket
RUN touch /var/run/docker.sock && chown user:docker /var/run/docker.sock

# Change to user
USER user

# Start the docker daemon
CMD ["sudo","service","docker","start"]

workflow.yml

name: Game autobuild

on:
  push:
    tags:
      - "v0.0.*"
    paths:
      - ".github/**"
      - "projectPath/**"

env:
  channel: "dev"
  unityVersion: "2021.3.30f1"
  projectPath: "projectPath"
  skipTest: true
  
jobs:
  vars:
    runs-on: self-hosted
    outputs:
      channel:      ${{ env.channel }}
      unityVersion: ${{ env.unityVersion }}
      projectPath:  ${{ env.projectPath }}
      skipTest:     ${{ env.skipTest }}
    steps:
      - name: Set vars
        run: |
          exit 0

  workflow-dev-build:
    needs:
      - vars
    name: ${{ format('Build {0} {1}', matrix.platform, matrix.build) }}
    outputs:
      serverBuild: false
    strategy:
      fail-fast: false
      max-parallel: 4
      matrix:
        platform:
          - "StandaloneLinux64"
          - "Android"
          - "StandaloneWindows"
          - "StandaloneWindows64"
          - "StandaloneOSX"
          - "iOS"
        build:
          - "client"
        include:
          - platform: "StandaloneLinux64"
            build: "server"
    runs-on: self-hosted
    env:
      library:    ${{ format('{0}/Library', needs.vars.outputs.projectPath) }}
      targetName: ${{ format('{0}-{1}', matrix.platform, matrix.build) }}
      target:
    steps:
      - name: Enable docker and cgroupv2 nesting
        run: |
          sudo -s -- <<EOF
          service docker start
          if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
              # move the processes from the root group to the /init group,
              # otherwise writing subtree_control fails with EBUSY.
              # An error during moving non-existent process (i.e., "cat") is ignored.
              mkdir -p /sys/fs/cgroup/init
              xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || :
              # enable controllers
              sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
                  > /sys/fs/cgroup/cgroup.subtree_control
              echo "Enabled cgroupv2 nesting"
          fi
          echo "Finished DinD startup"
          EOF

      - name: Determine if server or client
        run: |
          if [ '${{ matrix.build }}' == 'server' ]
          then
            echo "Target is Server"
            echo "target=Server" >> $GITHUB_ENV
          else
            echo "Target is Player"
            echo "target=Player" >> $GITHUB_ENV
          fi

      - uses: actions/[email protected]
        with:
          fetch-depth: 0
          lfs: true

        # Separate step for hashing to prevent cache step failure
      - name: Hash projectPath for cache
        id: hash
        continue-on-error: true
        run: |
          echo "hash=${{ hashFiles(env.projectPath) }}" >> $GITHUB_OUTPUT
          exit 0

      - uses: actions/[email protected]
        with:
          enableCrossOsArchive: true
          path: ${{ env.library }}
          key:
            Library-${{ env.projectPath }}-${{ matrix.platform }}-${{ steps.hash.outputs.hash }}
          restore-keys: |
            Library-${{ env.projectPath }}-${{ matrix.platform }}-
            Library-${{ env.projectPath }}-
            Library-

      - if: ${{ matrix.platform == 'Android' }}
        name: Android cleanup
        uses: jlumbroso/[email protected]

      - uses: game-ci/[email protected]
        name: Perform build
        id: build
        continue-on-error: true
        env:
          UNITY_LICENSE:  ${{ secrets.UNITY_LICENSE }}
          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
        with:
          versioning:     Tag
          targetPlatform: ${{ matrix.platform }}
          unityVersion:   ${{ needs.vars.outputs.unityVersion }}
          projectPath:    ${{ env.projectPath }}
          buildsPath:     builds
          buildName:      ${{ matrix.platform }}
          runAsHostUser:  true
          customParameters: |
            -standaloneBuildSubtarget ${{ env.target }}

        # Separate step for hashing to prevent check step failure
      - name: Hash build files for check
        id: buildHash
        continue-on-error: true
        run: |
          echo "hash=${{ hashFiles(format('./builds/{0}/**', matrix.platform)) }}" >> $GITHUB_OUTPUT
          exit 0

      - name: Check if build failed
        if: ${{ steps.buildHash.outputs.hash  == '' }}
        id: failCheck
        run: |
          exit 0

      - uses: game-ci/[email protected]
        if: ${{ steps.failCheck.outcome == 'success' }}
        name: Retry build
        id: buildTwo
        continue-on-error: true
        env:
          UNITY_LICENSE:  ${{ secrets.UNITY_LICENSE }}
          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
        with:
          versioning:     Tag
          targetPlatform: ${{ matrix.platform }}
          unityVersion:   ${{ needs.vars.outputs.unityVersion }}
          projectPath:    ${{ env.projectPath }}
          buildsPath:     builds
          buildName:      ${{ matrix.platform }}
          runAsHostUser:  true
          cacheUnityInstallationOnMac: true
          customParameters: |
            -standaloneBuildSubtarget ${{ env.target }}

      - name: Zip build
        if: ${{ steps.build.outcome == 'success' || steps.buildTwo.outcome == 'success' }}
        id: zip
        run: |
          ${{ format('cd ./builds/{0}', matrix.platform) }}
          ${{ format('sudo 7z a -tZip {0}.zip', env.targetName) }}
          ls
          ${{ format('7z l {0}.zip', env.targetName) }}
            
      - uses: actions/upload-artifact@v4
        if: ${{ steps.zip.outcome == 'success' }}
        id: upload
        with:
          name: ${{ format('{0}-{1}', needs.vars.outputs.channel, matrix.build) }}
          path: ${{ format('./builds/{0}/{0}-{1}.zip', matrix.platform, matrix.build) }}
          retention-days: 2
          if-no-files-found: error

      - name: Set serverBuild output
        if: ${{ matrix.build == 'server' && steps.upload.outcome == 'success' }}
        run: |
          echo "serverBuild=true" >> $GITHUB_OUTPUT

nektos/act debug info

act version:            0.2.57
GOOS:                   windows
GOARCH:                 amd64
NumCPU:                 16
Docker host:            DOCKER_HOST environment variable is not set
Sockets found:
        \\.\pipe\docker_engine(broken)
Config files:
        C:\Users\balan\.actrc:
                -P ubuntu-latest=catthehacker/ubuntu:act-latest
                -P ubuntu-22.04=catthehacker/ubuntu:act-22.04
                -P ubuntu-20.04=catthehacker/ubuntu:act-20.04
                -P ubuntu-18.04=catthehacker/ubuntu:act-18.04
        .actrc:
                -P self-hosted=lkkuma/local-runner:latest
                --container-options \" --init -v GameCI-Cache:/var/lib/docker/overlay2/ \"

                --pull=false
                --no-skip-checkout
                --privileged
                --rm
                --container-daemon-socket=-

                --action-cache-path D:\.cache\act
                --artifact-server-path D:\.cache\actartifacts
                --cache-server-path D:\.cache\actcache
Build info:
        Go version:            go1.20.12
        Module path:           github.com/nektos/act
        Main version:          (devel)
        Main path:             github.com/nektos/act
        Main checksum:
        Build settings:
                -buildmode:           exe
                -compiler:            gc
                -ldflags:             -s -w -X main.version=0.2.57 -X main.commit=4fae81efe4cdd9e09e7ef8e874a2d63b1ed98524 -X main.date=2024-01-01T02:17:54Z -X main.builtBy=goreleaser
                CGO_ENABLED:          0
                GOARCH:               amd64
                GOOS:                 windows
                GOAMD64:              v1
                vcs:                  git
                vcs.revision:         4fae81efe4cdd9e09e7ef8e874a2d63b1ed98524
                vcs.time:             2024-01-01T02:17:35Z
                vcs.modified:         false
Docker Engine:
        Engine version:        24.0.6
        Engine runtime:        runc
        Cgroup version:        2
        Cgroup driver:         cgroupfs
        Storage driver:        overlay2
        Registry URI:          https://index.docker.io/v1/
        OS:                    Docker Desktop
        OS type:               linux
        OS version:
        OS arch:               x86_64
        OS kernel:             6.4.16-linuxkit
        OS CPU:                8
        OS memory:             7946 MB
        Security options:
                name=seccomp,profile=unconfined
                name=cgroupns
Any extra help at this point would be fantastic.

lkkuma avatar Jan 05 '24 15:01 lkkuma

I'm wondering if I have to set up docker for rootless EDIT: nevermind

lkkuma avatar Jan 06 '24 00:01 lkkuma

I'm wondering if I have to set up docker for rootless EDIT: nevermind

happy 2024 :D Are you found a solution for this?

WildEgor avatar Jan 06 '24 15:01 WildEgor

I'm wondering if I have to set up docker for rootless EDIT: nevermind

happy 2024 :D Are you found a solution for this?

Sorry, not yet I've burned myself out trying to figure the problem out past this point so I'm taking a small break

lkkuma avatar Jan 06 '24 15:01 lkkuma

I'm using windows and I was using act to attempt local runners so I didn't use up my minutes. I abandoned it comepletely. I installed WSL 2, docker-desktop and Ubuntu (wsl). I created a self hosted runner on github, ran the install commands on the ubuntu terminal and now it works!

Oolix avatar Jan 10 '24 16:01 Oolix

A year later (/j, happy 2024), I come with an update. I've gotten to the point of getting a custom image with docker in docker working consistently and independently from the host. The problem I'm facing now is getting /bin/bash: line 1: /entrypoint.sh: Permission denied when actually running my workflow.

I've reached the point where I want to ask for further help here to figure this out.

@lkkuma, 2 really common reasons you'd get "permission denied" on a shell script are that the script itself is not executable, or that the reference to the script interpreter at the top of the script code does not exist (in other words, maybe your image doesn't have /bin/bash). If you're running it on Ubuntu, that shouldn't be an issue, but if you're on something smaller, like Alpine linux, you'll just want to reference /bin/sh at the top of the script instead. If the permissions are an issue, you'll want to run chmod 755 /entrypoint.sh somewhere in your Dockerfile after it's COPY'd into the image.

oshaughnessy avatar Jan 29 '24 17:01 oshaughnessy

I'm using windows and I was using act to attempt local runners so I didn't use up my minutes. I abandoned it comepletely. I installed WSL 2, docker-desktop and Ubuntu (wsl). I created a self hosted runner on github, ran the install commands on the ubuntu terminal and now it works!

I ended up trying this approach, but I'm having to re-run chmod or chown commands between each run, else set them in the actions file and type them as my runner terminal asks. Annoying. What am I doing wrong?

DakotaIrsik avatar Feb 05 '24 05:02 DakotaIrsik

Same.

Due to the nature of DockerInDocker(dind), it is not necessary to dwell on solving this problem; here is a way to avoid similar problems:

  1. Build an actions-runner/_work directory on the host, e.g. /root/var/unity-ci/actions-runner/_work

  2. When building the game-ci container, in the Dockerfile: WORKDIR /root/var/unity-ci/

  3. To run the game-ci container, use -v /root/var/unity-ci/actions-runner/_work:/root/var/unity-ci/actions-runner/_work

The trick here is to keep the _work path in the container the same as the _work path in the host.

liasece avatar Feb 21 '24 09:02 liasece

Any updates on this?

ReaperMaga avatar Apr 30 '24 16:04 ReaperMaga