{"id":27431832,"url":"https://github.com/existenznl/docker-builder","last_synced_at":"2025-04-14T15:35:09.765Z","repository":{"id":21049955,"uuid":"91261336","full_name":"eXistenZNL/Docker-Builder","owner":"eXistenZNL","description":"A builder image that can be used to build projects on various builders, e.g. GitLab-CI.","archived":false,"fork":false,"pushed_at":"2025-03-05T08:31:19.000Z","size":94,"stargazers_count":6,"open_issues_count":1,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-05T09:33:56.566Z","etag":null,"topics":["ci-cd","composer","docker","docker-in-docker","gitlab-ci","gitlab-runner","hacktoberfest","nodejs","npm","php","yarn"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eXistenZNL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"eXistenZNL"}},"created_at":"2017-05-14T17:52:10.000Z","updated_at":"2025-03-05T08:31:01.000Z","dependencies_parsed_at":"2023-10-30T11:29:52.470Z","dependency_job_id":"0da1be64-5794-4f74-84ea-d9ef15dcea9a","html_url":"https://github.com/eXistenZNL/Docker-Builder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXistenZNL%2FDocker-Builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXistenZNL%2FDocker-Builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXistenZNL%2FDocker-Builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXistenZNL%2FDocker-Builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eXistenZNL","download_url":"https://codeload.github.com/eXistenZNL/Docker-Builder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248906823,"owners_count":21181222,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci-cd","composer","docker","docker-in-docker","gitlab-ci","gitlab-runner","hacktoberfest","nodejs","npm","php","yarn"],"created_at":"2025-04-14T15:33:27.688Z","updated_at":"2025-04-14T15:35:09.759Z","avatar_url":"https://github.com/eXistenZNL.png","language":"Dockerfile","funding_links":["https://github.com/sponsors/eXistenZNL"],"categories":[],"sub_categories":[],"readme":"# Docker Builder\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/eXistenZNL/Docker-Builder/build-containers.yml?branch=master\u0026style=flat-square)](https://github.com/eXistenZNL/Docker-Builder/actions) [![Docker Pulls](https://img.shields.io/docker/pulls/existenz/builder.svg?style=flat-square)](https://hub.docker.com/r/existenz/builder/) [![License](https://img.shields.io/github/license/existenznl/docker-builder.svg?style=flat-square)](https://github.com/eXistenZNL/Docker-Builder/blob/master/LICENSE) [![Sponsors](https://img.shields.io/github/sponsors/eXistenZNL?color=hotpink\u0026style=flat-square)](https://github.com/sponsors/eXistenZNL)\n\n## About\n\nA container that holds all the tools needed to build a run-of-the-mill modern PHP project in a CI like GitLab-CI.\nOptimized for Docker-in-Docker builds that build and push another container to a registry.\nBuilt upon [Alpine Linux](https://alpinelinux.org/), and comes with the latest and greatest of the tools listed below:\n\n### Tools\n\n - [PHP](https://secure.php.net/)\n - [Composer](https://getcomposer.org/)\n - [NodeJS](https://nodejs.org/en/)\n - [NPM](https://www.npmjs.com/)\n - [Yarn](https://yarnpkg.com/lang/en/)\n - [Docker](https://www.docker.com/)\n - [Buildah](https://buildah.io/)\n - [Podman](https://podman.io/)\n\n\n## Why\n\nThat's an easy one: speed. Lots of different approaches are taken when setting up a CI pipeline, but not all setups are\nas fast as they could be. One of the approaches I've seen is where the build is ran inside a pretty clean container, and\nevery tool needed (Composer, NPM, etc.) is pulled in via Docker. And since Docker-in-Docker has no possibility to cache\nlayers, these need to be pulled in over and over again.\n\nAlso, setting all these docker pulls up gets kinda messy with a lot of commands needed to perform a complete build. I\nwanted stuff to be simple, readible, and easy to maintain.\n\n## The goals of this container\n\n- Pull in as few bits from the interwebs as needed, by caching everything that's possible.\n- Minimize the lines of code needed in `.gitlab-ci.yml` and optimize readibility.\n- Optimally share the built cache between the various stages of a build pipeline.\n\n## So how does it work?\n\nActually, quite simple. The scenario this container is built for is a\n[GitLab-CI](https://about.gitlab.com/features/gitlab-ci-cd/) environment that runs in\n[Docker-in-Docker](https://docs.gitlab.com/ce/ci/docker/using_docker_build.html#use-docker-in-docker-executor) mode.\nThis means the following:\n- To build a container without the Docker socket exposed, we must run a Docker instance inside our container using the\n`docker:dind` container as a service.\n- Any container being pulled by the inner docker instance will not be cached since the container will be destroyed\nafterwards.\n- The only container can be cached is the container which is specified in `gitlab-ci.yml` and in which our build is\nrunning, because this container is being pulled by the GitLab runner which controls the outside Docker instance.\n\nThis container brings the following advantages:\n- The image itself is being cached by the GitLab runner, so all tools needed are instantly available.\n- Because all the tools you need are embedded, no external tools need to be pulled in over and over again.\n- The image has a little helper on board that makes is possible to cache stuff outside of the build directory so more\nstuff can be cached and re-used between stages in a pipeline.\n\n## Cache all the things!\n\nIn order to efficiently make use of the cache between stages, a little helper tool called cache-tool is available in the\ncontainer. This tool makes it possible to cache directories outside of the build dir, something that is normally not\nallowed by the GitLab-CI runner.\n\nThis enables us to make use of the native cache of various tools, e.g. Composer or Yarn. Doing\nso allows us to install and remove dependencies at will between stages by using the local cache, without grabbing stuff\nfrom the internet.\n\nTo make this work, the cache must be configured on a global level in your `.gitlab-ci.yml`, so all stages use the same\ncache directories throughout the build. Also add the directory .cache:\n\n```yaml\ncache:\n  untracked: false\n  paths:\n    - .cache/\n    - vendor/\n    - node_modules/\n```\n\nThe added benefit of this is that it makes your `.gitlab-ci.yml` more readible.\n\nWe also need to call the cache-tool before and after running a stage.\nFor example, to cache Composers cache directory, add the following to your `.gitlab-ci.yml`:\n\n```yaml\nsome stage:\n  before_script:\n    - cache-tool extract composer:~/.composer\n  after_script:\n    - cache-tool collect composer:~/.composer\n```\nThe cache-tool allows to cache more than one directory, by simply adding more parameters to the command:\n```bash\n$ cache-tool collect name1:/some/dir name2:~/dir-from-homedir\n```\n\nThe things you list for collection or extraction are up to you, and consist of a key and a directory to cache. The key\nwill be used for the directory name inside the .cache\n\nJust make sure the same directories are listed for extraction and collection.\n\nSome directories that you probably want to cache if you use the tools:\n\n| Tool     | Cache directory              |\n| ---------|------------------------------|\n| Composer | ~/.composer                  |\n| NPM      | ~/.npm                       |\n| Yarn     | /usr/local/share/.cache/yarn |\n\n## An example that shows the improved readability\n\nBecause we don't need to pull in any extra's we don't have to clutter our build script with curl commands, prefetchers,\nor other exotic script. We can instead simply add the commands just as they would normally run, this makes our\nconfiguration really readable and short. A simple example containing two stages is shown here:\n\n```yaml\nstages:\n  - testCode\n  - buildContainer\n\ncache:\n  untracked: false\n  paths:\n    - .cache/\n    - vendor/\n\ntest:\n  image: existenz/builder:latest\n  stage: testCode\n  before_script:\n    - cache-tool extract yarn:/usr/local/share/.cache/yarn composer:~/.composer\n  script:\n    - composer install --ignore-platform-reqs\n    - vendor/bin/phpcs --standard=PSR2 app/\n  after_script:\n    - cache-tool collect yarn:/usr/local/share/.cache/yarn composer:~/.composer\n\nbuild container:\n  image: existenz/builder:latest\n  stage: buildContainer\n  before_script:\n    - cache-tool extract yarn:/usr/local/share/.cache/yarn composer:~/.composer\n  script:\n    - composer install --ignore-platform-reqs --no-dev\n    - yarn install\n    - yarn run production\n    - docker build\n  after_script:\n    - cache-tool collect yarn:/usr/local/share/.cache/yarn composer:~/.composer\n```\n\n## Automated builds\n\nThe containers are automatically rebuilt and tested every week to make sure they are up-to-date.\n\n## Versions\n\n\u003e Tags ending with a `-description` install packages from different repositories to keep up with the latest PHP\n\u003e versions. These are probably short-lived and will be replaced with their default counterpart as soon as these PHP\n\u003e versions make it into the default Alpine repositories. You can use them, just keep in mind you will have to switch\n\u003e over to the default container at one point.\n\u003e\n\u003e Codecasts containers are no longer provided, see [this issue](https://github.com/codecasts/php-alpine/issues/131) for\n\u003e more information.\n\nSee the table below to see what versions are currently available:\n\n| Image tag | Based on          | PHP                                                                                             | NodeJS                                                                                     | Yarn                                          | Composer                                  |\n|-----------|-------------------|-------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|-----------------------------------------------|-------------------------------------------|\n| 8.1       | Alpine Linux 3.18 | [8.1](https://pkgs.alpinelinux.org/packages?name=php81*\u0026branch=3.18\u0026arch=x86_64)                | [18](https://pkgs.alpinelinux.org/packages?name=nodejs\u0026branch=v3.18\u0026repo=main\u0026arch=x86_64) | [Latest stable](https://yarnpkg.com/lang/en/) | [Latest stable](https://getcomposer.org/) |\n| 8.2       | Alpine Linux 3.19 | [8.2](https://pkgs.alpinelinux.org/packages?name=php82*\u0026branch=3.19\u0026arch=x86_64)                | [20](https://pkgs.alpinelinux.org/packages?name=nodejs\u0026branch=v3.19\u0026repo=main\u0026arch=x86_64) | [Latest stable](https://yarnpkg.com/lang/en/) | [Latest stable](https://getcomposer.org/) |\n| 8.3       | Alpine Linux 3.19 | [8.3](https://pkgs.alpinelinux.org/packages?name=php83*\u0026branch=3.19\u0026arch=x86_64)                | [20](https://pkgs.alpinelinux.org/packages?name=nodejs\u0026branch=v3.19\u0026repo=main\u0026arch=x86_64) | [Latest stable](https://yarnpkg.com/lang/en/) | [Latest stable](https://getcomposer.org/) |\n| 8.4       | Alpine Linux 3.21 | [8.4](https://pkgs.alpinelinux.org/packages?name=php84*\u0026branch=3.21\u0026arch=x86_64)                | [22](https://pkgs.alpinelinux.org/packages?name=nodejs\u0026branch=v3.21\u0026repo=main\u0026arch=x86_64) | [Latest stable](https://yarnpkg.com/lang/en/) | [Latest stable](https://getcomposer.org/) |\n\n## Bugs, questions, and improvements\n\nIf you found a bug or have a question, please open an issue on the GitHub Issue tracker.\nImprovements can be sent by a Pull Request against the master branch and are greatly appreciated!\n\n## Contributors\n\nThanks everyone for helping out with this project!\n\n[![Contributor avatars](https://contrib.rocks/image?repo=eXistenZNL/Docker-Builder)](https://github.com/eXistenZNL/Docker-Builder/graphs/contributors)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexistenznl%2Fdocker-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexistenznl%2Fdocker-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexistenznl%2Fdocker-builder/lists"}