unity-builder
unity-builder copied to clipboard
Running action in self-hosted runner
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
- 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
- See successfully started runner status and trigger action;
- 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?
Did anyone figure this out?
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

i'm getting the same issue when using
actto develop locallythe docker docs seem to say that since
entrypoint.shdoesn't already exist it will be created as a directory
seeing this also
Has anyone found a solution for this?
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.
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
I'm wondering if I have to set up docker for rootless EDIT: nevermind
I'm wondering if I have to set up docker for rootless EDIT: nevermind
happy 2024 :D Are you found a solution for this?
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
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!
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 deniedwhen 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.
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?
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:
-
Build an actions-runner/_work directory on the host, e.g.
/root/var/unity-ci/actions-runner/_work -
When building the game-ci container, in the Dockerfile:
WORKDIR /root/var/unity-ci/ -
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.
Any updates on this?