├── Dockerfile ├── Dockerfile.golang ├── Dockerfile.java ├── Dockerfile.node ├── Dockerfile.php ├── Dockerfile.python ├── LICENSE ├── README.md ├── README.md.old ├── screenshot1.png └── start.sh /Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM debian:buster 3 | 4 | ARG GH_ACTIONS_RUNNER_VERSION=2.263.0 5 | ARG PACKAGES="gnupg2 apt-transport-https ca-certificates software-properties-common pwgen git make curl wget zip libicu-dev build-essential libssl-dev" 6 | 7 | # install basic stuff 8 | RUN apt-get update \ 9 | && apt-get install -y -q ${PACKAGES} \ 10 | && apt-get clean \ 11 | && rm -rf /var/lib/apt/lists/* 12 | 13 | # install docker 14 | RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \ 15 | && apt-key fingerprint 0EBFCD88 \ 16 | && add-apt-repository \ 17 | "deb [arch=amd64] https://download.docker.com/linux/debian \ 18 | $(lsb_release -cs) \ 19 | stable" \ 20 | && apt-get update \ 21 | && apt-get install -y docker-ce-cli \ 22 | && apt-get clean \ 23 | && rm -rf /var/lib/apt/lists/* \ 24 | && curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \ 25 | && chmod +x /usr/local/bin/docker-compose 26 | 27 | # create "runner" user 28 | RUN useradd -d /runner --uid=1000 runner \ 29 | && echo 'runner:runner' | chpasswd \ 30 | && mkdir /runner \ 31 | && chown -R runner:runner /runner 32 | 33 | USER runner 34 | WORKDIR /runner 35 | 36 | # install github actions runner 37 | RUN curl -o actions-runner-linux-x64.tar.gz -L https://github.com/actions/runner/releases/download/v${GH_ACTIONS_RUNNER_VERSION}/actions-runner-linux-x64-${GH_ACTIONS_RUNNER_VERSION}.tar.gz \ 38 | && tar xzf ./actions-runner-linux-x64.tar.gz \ 39 | && rm -f actions-runner-linux-x64.tar.gz 40 | 41 | COPY start.sh / 42 | 43 | CMD /start.sh 44 | -------------------------------------------------------------------------------- /Dockerfile.golang: -------------------------------------------------------------------------------- 1 | 2 | FROM samber/github-actions-runner:latest 3 | 4 | USER root 5 | 6 | RUN cd /tmp \ 7 | && wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz \ 8 | && tar -xvf go1.13.3.linux-amd64.tar.gz \ 9 | && mv go /usr/local/src \ 10 | && ln -s /usr/local/src/go/bin/go /usr/local/bin/ \ 11 | && apt-get update \ 12 | && apt-get install -y -q build-essential \ 13 | && apt-get clean \ 14 | && rm -rf /var/lib/apt/lists/* 15 | 16 | USER runner 17 | -------------------------------------------------------------------------------- /Dockerfile.java: -------------------------------------------------------------------------------- 1 | 2 | FROM samber/github-actions-runner:latest 3 | 4 | USER root 5 | 6 | RUN echo "deb https://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list \ 7 | && curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | apt-key add \ 8 | && apt-get update \ 9 | && apt-get install -y -q default-jdk maven gradle sbt \ 10 | && apt-get clean \ 11 | && rm -rf /var/lib/apt/lists/* 12 | 13 | USER runner 14 | -------------------------------------------------------------------------------- /Dockerfile.node: -------------------------------------------------------------------------------- 1 | 2 | FROM samber/github-actions-runner:latest 3 | 4 | USER root 5 | 6 | RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \ 7 | && apt-get update \ 8 | && apt-get install -y -q nodejs \ 9 | && apt-get clean \ 10 | && rm -rf /var/lib/apt/lists/* 11 | 12 | RUN npm install -g yarn 13 | 14 | USER runner 15 | -------------------------------------------------------------------------------- /Dockerfile.php: -------------------------------------------------------------------------------- 1 | 2 | FROM samber/github-actions-runner:latest 3 | 4 | ENV PACKAGES="php7.2-fpm php7.2-cli php7.2-common php7.2-curl php7.2-gd php7.2-intl php7.2-pgsql php7.2-json php7.2-redis php7.2-mbstring php7.2-bcmath php-mail-mime" 5 | 6 | USER root 7 | 8 | RUN curl -o /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg \ 9 | && sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ 10 | && apt-get update && apt-get install -y -q $PACKAGES \ 11 | && apt-get clean \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | RUN curl -k -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ \ 15 | && ln -s /usr/local/bin/composer.phar /usr/local/bin/composer 16 | 17 | USER runner 18 | -------------------------------------------------------------------------------- /Dockerfile.python: -------------------------------------------------------------------------------- 1 | 2 | FROM samber/github-actions-runner:latest 3 | 4 | USER root 5 | 6 | RUN apt-get update \ 7 | && apt-get install -y -q libffi-dev python3-dev python3-pip python3-setuptools \ 8 | && apt-get clean \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | USER runner 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Samuel Berthe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | **THIS REPOSITORY IS NOT UP-TO-DATE** 3 | 4 | Please use [myoung34/docker-github-actions-runner](https://github.com/myoung34/docker-github-actions-runner) instead. 5 | 6 | # 👌 Github Actions self-hosted runner provisioning 7 | 8 | [Readme](./README.md.old) 9 | -------------------------------------------------------------------------------- /README.md.old: -------------------------------------------------------------------------------- 1 | 2 | # 👌 Github Actions self-hosted runner provisioning 3 | 4 | > Simple Docker images for starting self-hosted Github Actions runner(s). 5 | 6 | ![Screenshot Github self-hosted runners](./screenshot1.png) 7 | 8 | [Github official documentation for self-hosted runners.](https://help.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners) 9 | 10 | ## 🚀 Quick start 11 | 12 | Add your self-hosted runner from your repository settings: 13 | 14 | - Go to repository > settings > actions 15 | - Click on "Add runner" 16 | - Copy the URL and token 17 | 18 | ```sh 19 | # start a runner on your server 20 | 21 | $ docker run -d \ 22 | -v /var/run/docker.sock:/var/run/docker.sock \ 23 | -v /tmp:/tmp \ 24 | -e GH_REPOSITORY=xxxxxxxxxxxx \ 25 | -e GH_RUNNER_TOKEN=xxxxxxxxxxxxx \ 26 | -e GH_RUNNER_LABELS=label1,label2 \ 27 | samber/github-actions-runner:latest 28 | ``` 29 | 30 | ```yaml 31 | # .github/workflows/main.yml 32 | 33 | on: 34 | - push 35 | 36 | jobs: 37 | example: 38 | runs-on: self-hosted 39 | steps: 40 | - name: Hello world 41 | run: echo "Hello world" 42 | ``` 43 | 44 | ### Runners with language support (NodeJS, Python3...) 45 | 46 | Just select your runner in the Docker image tag. 47 | 48 | Currently available: 49 | 50 | - samber/github-actions-runner:**node** 51 | - samber/github-actions-runner:**golang** 52 | - samber/github-actions-runner:**python** 53 | - samber/github-actions-runner:**java** 54 | - samber/github-actions-runner:**php** 55 | 56 | ```sh 57 | # start a NodeJS runner 58 | 59 | $ docker run -d \ 60 | -v /var/run/docker.sock:/var/run/docker.sock \ 61 | -v /tmp:/tmp \ 62 | -e GH_REPOSITORY=xxxxxxxxxxxx \ 63 | -e GH_RUNNER_TOKEN=xxxxxxxxxxxxx \ 64 | -e GH_RUNNER_LABELS=node \ 65 | samber/github-actions-runner:node 66 | ``` 67 | 68 | ```yaml 69 | # .github/workflows/main.yml 70 | 71 | on: 72 | - push 73 | 74 | jobs: 75 | frontend: 76 | runs-on: self-hosted 77 | steps: 78 | - uses: actions/checkout@v2 79 | - name: Fetch dependencies 80 | run: yarn 81 | - name: Build application 82 | run: npm run build 83 | - name: Execute tests 84 | run: npm run test 85 | ``` 86 | 87 | ### Missing language support ? 88 | 89 | You just need to write a Dockerfile starting with `FROM samber/github-actions-runner:latest`. 90 | 91 | You can contribute to this repository or create your own Docker image. 92 | 93 | ## 💡 Docker compose 94 | 95 | ### Simple runner 96 | 97 | ```yaml 98 | version: '3' 99 | 100 | services: 101 | 102 | runner: 103 | image: samber/github-actions-runner:latest 104 | volumes: 105 | - /var/run/docker.sock:/var/run/docker.sock 106 | - /tmp:/tmp 107 | environment: 108 | - GH_REPOSITORY=xxxxxxxxxxxx 109 | - GH_RUNNER_TOKEN=xxxxxxxxxxxxx 110 | - GH_RUNNER_LABELS=label1,label2 \ 111 | restart: unless-stopped 112 | ``` 113 | 114 | ```sh 115 | $ docker-compose up -d 116 | ``` 117 | 118 | ### Concurrent executors 119 | 120 | ```sh 121 | $ docker-compose scale runner=3 122 | ``` 123 | 124 | ### Runners with language support 125 | 126 | You will need to register multiple runners, with different name+tokens. 127 | 128 | In the following example, we create 2 self-hosted runners: node and golang, with respective tag: "node" and "golang". We will start 2 instances of each. 129 | 130 | ```yaml 131 | version: '3' 132 | 133 | services: 134 | 135 | runner-node: 136 | image: samber/github-actions-runner:node 137 | volumes: 138 | - /var/run/docker.sock:/var/run/docker.sock 139 | - /tmp:/tmp 140 | environment: 141 | - GH_REPOSITORY=yyyyyyyyyyyyy 142 | - GH_RUNNER_TOKEN=xxxxxxxxxxxxx 143 | - GH_RUNNER_LABELS=node \ 144 | restart: unless-stopped 145 | 146 | runner-golang: 147 | image: samber/github-actions-runner:golang 148 | volumes: 149 | - /var/run/docker.sock:/var/run/docker.sock 150 | - /tmp:/tmp 151 | environment: 152 | - GH_REPOSITORY=yyyyyyyyyyyyy 153 | - GH_RUNNER_TOKEN=zzzzzzzzzzzzz 154 | - GH_RUNNER_LABELS=golang \ 155 | restart: unless-stopped 156 | ``` 157 | 158 | ```sh 159 | $ docker-compose up -d 160 | $ docker-compose scale runner-node=2 runner-golang=2 161 | ``` 162 | 163 | ```yaml 164 | # .github/workflows/main.yml 165 | 166 | on: 167 | - push 168 | 169 | jobs: 170 | 171 | frontend: 172 | runs-on: [self-hosted, node] 173 | steps: 174 | - uses: actions/checkout@v2 175 | - name: Fetch dependencies 176 | run: yarn 177 | - name: Build application 178 | run: npm run build 179 | - name: Execute tests 180 | run: npm run test 181 | 182 | api: 183 | runs-on: [self-hosted, golang] 184 | steps: 185 | - uses: actions/checkout@v2 186 | - name: Fetch dependencies 187 | run: go mod download 188 | - name: Build application 189 | run: go build -o hello-world 190 | - name: Execute tests 191 | run: go testt 192 | ``` 193 | 194 | ## 🤯 Advanced 195 | 196 | ### Run as root 197 | 198 | For whatever (bad 😅) reason, if you need to start runners as root, you have to set container user to `root`, and add an empty `RUNNER_ALLOW_RUNASROOT` environment variables. 199 | 200 | ## 🔬 Build 201 | 202 | ```bash 203 | docker build -f Dockerfile -t samber/github-actions-runner:latest -t samber/github-actions-runner:2.272.0 . 204 | docker build -f Dockerfile.node -t samber/github-actions-runner:node -t samber/github-actions-runner:node-2.272.0 . 205 | docker build -f Dockerfile.golang -t samber/github-actions-runner:golang -t samber/github-actions-runner:golang-2.272.0 . 206 | docker build -f Dockerfile.python -t samber/github-actions-runner:python -t samber/github-actions-runner:python-2.272.0 . 207 | docker build -f Dockerfile.java -t samber/github-actions-runner:java -t samber/github-actions-runner:java-2.272.0 . 208 | docker build -f Dockerfile.php -t samber/github-actions-runner:php -t samber/github-actions-runner:php-2.272.0 . 209 | 210 | docker push samber/github-actions-runner:latest 211 | docker push samber/github-actions-runner:2.272.0 212 | 213 | docker push samber/github-actions-runner:node 214 | docker push samber/github-actions-runner:node-2.272.0 215 | 216 | docker push samber/github-actions-runner:golang 217 | docker push samber/github-actions-runner:golang-2.272.0 218 | 219 | docker push samber/github-actions-runner:python 220 | docker push samber/github-actions-runner:python-2.272.0 221 | 222 | docker push samber/github-actions-runner:java 223 | docker push samber/github-actions-runner:java-2.272.0 224 | 225 | docker push samber/github-actions-runner:php 226 | docker push samber/github-actions-runner:php-2.272.0 227 | ``` 228 | 229 | ## ♻️ Host cleanup 230 | 231 | Clean stopped containers on a daily basis: 232 | 233 | ```sh 234 | $ crontab -e 235 | 236 | 0 0 * * * /usr/bin/docker system prune -f 237 | ``` 238 | 239 | ## 🤝 Contributing 240 | 241 | This project is open source and contributions from community (you!) are welcome. 242 | 243 | There are many ways to contribute: writing code, documentation, reporting issues... 244 | 245 | ## Author 246 | 247 | 👤 **Samuel Berthe** 248 | 249 | * Twitter: [@samuelberthe](https://twitter.com/samuelberthe) 250 | * Github: [@samber](https://github.com/samber) 251 | 252 | ## 💫 Show your support 253 | 254 | Give a ⭐️ if this project helped you! 255 | 256 | [![support us](https://c5.patreon.com/external/logo/become_a_patron_button.png)](https://www.patreon.com/samber) 257 | 258 | ## 📝 License 259 | 260 | Copyright © 2020 [Samuel Berthe](https://github.com/samber). 261 | 262 | This project is [MIT](./LICENSE) licensed. 263 | -------------------------------------------------------------------------------- /screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samber/github-actions-runner/54bcd03d688abab4997dbb8c26672a1977e8f8cc/screenshot1.png -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [[ -z ${GH_RUNNER_TOKEN} ]]; 6 | then 7 | echo "Environment variable 'GH_RUNNER_TOKEN' is not set" 8 | exit 1 9 | fi 10 | 11 | if [[ -z ${GH_REPOSITORY} ]]; 12 | then 13 | echo "Environment variable 'GH_REPOSITORY' is not set" 14 | exit 1 15 | fi 16 | 17 | # generate random password 18 | # silent fail because it wont be able override password on restart 19 | newPass=$(pwgen -s1 20) 20 | printf "runner\n${newPass}\n${newPass}\n" | passwd 2> /dev/null || echo 21 | 22 | # print runner version 23 | echo "github runner version: $(./config.sh --version)" 24 | echo "github runner commit: $(./config.sh --commit)" 25 | 26 | workDir=/tmp/_work/$(pwgen -s1 5) 27 | 28 | mkdir -p ${workDir} 29 | echo "Runner working directory: ${workDir}" 30 | 31 | # can fail if already configured 32 | /runner/config.sh --unattended --url ${GH_REPOSITORY} --token ${GH_RUNNER_TOKEN} --labels ${GH_RUNNER_LABELS} --replace --work ${workDir} || echo 33 | 34 | exec /runner/run.sh 35 | --------------------------------------------------------------------------------