{"id":20640130,"url":"https://github.com/maresb/gitlab-runner-ecr-auth-example","last_synced_at":"2026-04-09T18:53:32.072Z","repository":{"id":107327109,"uuid":"282728850","full_name":"maresb/gitlab-runner-ecr-auth-example","owner":"maresb","description":"An example demonstrating how to authenticate Gitlab Runners to ECR at both the Docker executor and DinD levels","archived":false,"fork":false,"pushed_at":"2020-08-02T11:57:49.000Z","size":74,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-17T08:35:56.355Z","etag":null,"topics":["aws","aws-ecr","aws-iam","docker","docker-compose","docker-executor","ecr","gitlab","gitlab-ci","gitlab-runner"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/maresb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2020-07-26T20:35:07.000Z","updated_at":"2020-08-02T12:11:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"a739d1bd-caeb-46b7-b6ad-b51e38de10c9","html_url":"https://github.com/maresb/gitlab-runner-ecr-auth-example","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/maresb%2Fgitlab-runner-ecr-auth-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maresb%2Fgitlab-runner-ecr-auth-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maresb%2Fgitlab-runner-ecr-auth-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maresb%2Fgitlab-runner-ecr-auth-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maresb","download_url":"https://codeload.github.com/maresb/gitlab-runner-ecr-auth-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242679511,"owners_count":20168163,"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":["aws","aws-ecr","aws-iam","docker","docker-compose","docker-executor","ecr","gitlab","gitlab-ci","gitlab-runner"],"created_at":"2024-11-16T15:28:03.570Z","updated_at":"2025-10-15T21:25:39.978Z","avatar_url":"https://github.com/maresb.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gitlab-runner-ecr-auth-example\n\n* GitHub: \u003chttps://github.com/maresb/gitlab-runner-ecr-auth-example\u003e\n* GitLab: \u003chttps://gitlab.com/bmares/gitlab-runner-ecr-auth-example\u003e\n* GitLab issue on ECR auth: \u003chttps://gitlab.com/gitlab-org/gitlab-runner/-/issues/1583\u003e\n\n## Introduction\n\nHere is a complete Docker-Compose-based example for how to configure\na GitLab runner to work with automatic ECR authentication. This allows\nfor access to private ECR registries for\nboth the Docker executor and Docker-in-Docker (DinD).\n\nThese instructions make the following assumptions.\n\n* You are using Linux. (If not, you deserve better.)\n* Your user has\n[permissions to run `docker` without `sudo`](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user).\n* You are entirely responsible for all aspects of security. This setup is meant\nonly for example purposes where all users are trusted. For more information, see [Security](#security).\n\n## Quick start\n\nIn case you just want to understand how this works, skip to the section [The authentication mechanism](#the-authentication-mechanism).\n\nIf you have an existing GitLab server, you should do the [prerequisites](#prerequisites)\nand then use the [runner-only configuration](#runner-only-configuration).\n\nIf you have no existing GitLab server, you can easily run a GitLab\nserver container. After doing the [prerequisites](#prerequisites)\nyou should skip to the [runner with server configuration](#runner-with-server-configuration).\n\n### Prerequisites\n\nRegardless of whether or not we need to run a server, we must configure the credentials and build the credential helpers.\n\n#### Configure the credentials\n\n* Copy the file `runner-ecr-credentials` to some relatively secure location\non the host (preferably outside of any Git repository where the credentials could\nbe accidentally committed and pushed).\n\n* Edit the `.env` file and set the `RUNNER_CREDENTIALS_FILE` variable to the\ncorresponding path and filename.\n\n#### Build the credential helpers\n\nFor more details, see [the corresponding README](build-amazon-ecr-credential-helpers/README.md).\n\n``` bash\ncd build-amazon-ecr-credential-helpers\n./do-builds\nls docker-credential-ecr-login-*  # Should see two files here.\ncd ..\n```\n\n### Runner-only configuration\n\nIf you also need to set up a GitLab server, then skip to the section\n[Runner with Server configuration](#runner-with-server-configuration).\n\nAt this point you should have completed the [prerequisites](#prerequisites).\n\nFrom the root of the `gitlab-runner-ecr-auth-example/` directory, run\n\n``` bash\ndocker-compose up -d\n./register  # Follow the instructions from server for adding a runner.\n```\n\nLogs can then be monitored with a command such as\n\n``` bash\ndocker-compose logs -f --tail=50\n```\n\n(Before the runner is registered, it is normal to see error messages in\nthe logs about the missing `config.toml` file.)\n\nAfter registration, your configured credentials should work automatically.\n\nIf desired,\n[configure the restart behavior](https://docs.docker.com/compose/compose-file/#restart)\nfor the runner in `docker-compose.yaml`.\n\n### Runner with Server configuration\n\nAt this point you should have completed the [prerequisites](#prerequisites).\n\nWe will set up the local GitLab server with the hostname `gitlab-server`.\nIn order that it is locally accessible from this hostname, we must add the\nline\n\n``` text\n127.0.0.1    gitlab-server\n```\n\nto `/etc/hosts` so that the server can be properly resolved from the host.\n\nThe configuration which includes both the GitLab Runner and GitLab Server\nis given in the `docker-compose-complete.yaml` file. Thus all `docker-compose`\ncommands (including `docker-compose down`) must be adjusted accordingly by\nadding `-f docker-compose-complete.yaml` immediately after `docker-compose`.\n\nTo start the runner and server, run\n\n``` bash\ndocker-compose -f docker-compose-complete.yaml up -d\n```\n\nLogs can be monitored with a command such as\n\n``` bash\ndocker-compose -f docker-compose-complete.yaml logs -f --tail=50\n```\n\n(Before the runner is registered, it is normal to see error messages in\nthe logs about the missing `config.toml` file.)\n\nIt can take several minutes for the GitLab server to start.\nWhen ready, the server will become available on\n\u003chttp://gitlab-server:8800\u003e.\n\nOnce it starts, you can configure a root account, and create a new project.\nTo register a runner, with this project, you should run the\n`register-complete` script. (The only difference with the `register`\nscript is that `register-complete` configures the runner to use the same\nDocker network as the GitLab server.)\n\n``` bash\n./register-complete  # Follow the instructions from server for adding a runner.\n```\n\nIf desired, [configure the restart behavior](https://docs.docker.com/compose/compose-file/#restart)\nfor the runner and server in `docker-compose-complete.yaml`.\n\n### Cleaning up\n\nTo stop the runner, use\n\n``` bash\ndocker-compose down\n```\n\nTo stop both the server and the runner, use\n\n``` bash\ndocker-compose -f docker-compose-complete.yaml down\n```\n\nTo reclaim disk space, most will be taken up by the GitLab Docker images. These can be\nremoved by running\n\n``` bash\ndocker rmi gitlab/gitlab-runner:v13.2.1\ndocker rmi gitlab/gitlab-ce:latest\n```\n\nAdditional files and directories which are created within this repository include:\n\n* the binaries for the credential helper in `build-amazon-ecr-credential-helpers/`,\n* the runner configuration in `gitlab-runner1-config/config.toml`,\n* additional shared runner folders under `gitlab-runner1-mounts/`,\n* in the case of the server, shared folders under `gitlab-server-mounts/`.\n\n## Index of files\n\n``` text\n├ .env                                  [environment variables for docker-compose]\n├ runner-ecr-credentials                [profile template for AWS credentials]\n├ docker-compose.yaml                   [runner-only docker-compose config]\n├ register                              [runner-only runner registration script]\n├ docker-compose-complete.yaml          [runner + server docker-compose config]\n├ register-complete                     [runner + server runner registration script]\n├ config-docker.json                    [DinD config to enable credential helper]\n├ example-.gitlab-ci.yml                [Example .gitlab-ci.yml for testing authentication]\n└ build-amazon-ecr-credential-helpers   [tools to build credential helpers]\n```\n\n## Explanation\n\n### Two distinct authentication requirements\n\nThere are two completely separate (but easily confusable) processes which must be separately configured.\n\n#### Authentication for the runner's Docker executor\n\nSuppose have a job that should be run in a private image, for instance\n\n``` yaml\ntest-runner-pull:\n  image: $PRIVATE_ECR_IMAGE\n  script:\n    - echo \"Hello World!\"\n```\n\nIn this case, the runner's Docker executor must first obtain credentials\nso that `$PRIVATE_ECR_IMAGE` can be pulled.\n\n#### Authentication for running `docker` in a CI script\n\nSuppose we have a script which uses the `docker` command to push or\npull from a private ECR registry, for instance\n\n``` yaml\n# dind service required for test-dind\nservices:\n  - docker:19.03.12-dind\n\ntest-dind:\n  image: docker:19.03.12\n  script:\n    - export\n    - docker pull $PRIVATE_ECR_IMAGE\n```\n\nThe `docker:19.03.12-dind` service provides a Docker host which can then be\naccessed via the `docker` command from the `docker:19.03.12` image. To obtain\ncredentials, one could install and use the AWS CLI. However, this requires\ninstalling Python as a dependency, and it clutters the CI script with a lot\nof boilerplate code. Thus it's more desirable when authentication happens\ntransparently.\n\n### The authentication mechanism\n\nTo handle authentication, we add a bind mount to the credential helper\nunder `/usr/local/bin/docker-credentials-ecr-login`.\nNext we must signal to Docker that it should actually use it.\nFor the GitLab runner's Docker executor, this is done\nby setting the `DOCKER_AUTH_CONFIG` environment variable to\n`{ \"credsStore\": \"ecr-login\" }`. For DinD (using the\n`docker` command in a script), we must put the same content in\n`/root/.docker/config.json` (which we accomplish with a bind mount).\n\nLike the AWS CLI, `docker-credentials-ecr-login` will search for\ncredentials either in the default profile of the\n`~/.aws/credentials` or in the following environment variables.\n\n``` text\nAWS_DEFAULT_REGION\nAWS_ACCESS_KEY_ID\nAWS_SECRET_ACCESS_KEY\n```\n\nWe take the former approach and mount a credentials file to\n`/root/.aws/credentials`.\n\nFor DinD, everything is configured in `config.toml` via the `register`\ncommand, namely:\n\n* privileged containers are allowed (`register`/`config.toml`),\n* `/root/.aws/credentials` is bind-mounted (`register`/`config.toml`),\n* `/usr/local/bin/docker-credential-ecr-login` is bind-mounted (`register`/`config.toml`), and\n* `/root/.docker/config.json` is bind-mounted (`register`/`config.toml`).\n\nFor the GitLab runner,\n\n* privileged containers are not allowed (`docker-compose.yaml`), but `/var/run/docker.sock` is bind-mounted (`docker-compose.yaml`),\n* `/root/.aws/credentials` is bind-mounted (`docker-compose.yaml`),\n* `/usr/local/bin/docker-credential-ecr-login` is bind-mounted (`docker-compose.yaml`),\n* `DOCKER_AUTH_CONFIG` is set as an environment variable (`register`/`config.toml`).\n\n## Security\n\nThis configuration allows privileged containers to be run from the runner host.\nAlso, the AWS credentials are stored unencrypted on the host filesystem, and bound\nto all running containers. Therefore, access to the runner should only be granted\nto people who are both\n\n* trusted to with the AWS credentials and\n* trusted as administrators of the runner host.\n\nI make absolutely no claims as to the security of this configuration, and assume that\nyou know what you are doing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaresb%2Fgitlab-runner-ecr-auth-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaresb%2Fgitlab-runner-ecr-auth-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaresb%2Fgitlab-runner-ecr-auth-example/lists"}