1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
---
stage: Package
group: Container Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Build and push container images to the container registry
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
Before you can build and push container images, you must [authenticate](authenticate_with_container_registry.md) with the container registry.
## Use Docker commands
You can use Docker commands to build and push container images to your container registry:
1. [Authenticate](authenticate_with_container_registry.md) with the container registry.
1. Run the Docker command to build or push. For example:
- To build:
```shell
docker build -t registry.example.com/group/project/image .
```
- To push:
```shell
docker push registry.example.com/group/project/image
```
## Configure your `.gitlab-ci.yml` file
You can configure your `.gitlab-ci.yml` file to build and push container images to the container registry.
- If multiple jobs require authentication, put the authentication command in the `before_script`.
- Before building, use `docker build --pull` to fetch changes to base images. It takes slightly
longer, but it ensures your image is up-to-date.
- Before each `docker run`, do an explicit `docker pull` to fetch
the image that was just built. This step is especially important if you are
using multiple runners that cache images locally.
If you use the Git SHA in your image tag, each job is unique and you
should never have a stale image. However, it's still possible to have a
stale image if you rebuild a given commit after a dependency has changed.
- Don't build directly to the `latest` tag because multiple jobs may be
happening simultaneously.
## Use GitLab CI/CD
You can use [GitLab CI/CD](../../../ci/index.md) to build and push container images to the
Container Registry. You can use CI/CD to test, build, and deploy your project from the container
image you created.
### Use a Docker-in-Docker container image from your container registry
You can use your own container images for Docker-in-Docker.
1. Set up [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
1. Update the `image` and `service` to point to your registry.
1. Add a service [alias](../../../ci/services/index.md#available-settings-for-services).
Your `.gitlab-ci.yml` should look similar to this:
```yaml
build:
image: $CI_REGISTRY/group/project/docker:20.10.16
services:
- name: $CI_REGISTRY/group/project/docker:20.10.16-dind
alias: docker
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
```
If you forget to set the service alias, the container image can't find the `dind` service,
and an error like the following is shown:
```plaintext
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host
```
### Use a Docker-in-Docker container image with Dependency Proxy
You can use your own container images with Dependency Proxy.
1. Set up [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
1. Update the `image` and `service` to point to your registry.
1. Add a service [alias](../../../ci/services/index.md#available-settings-for-services).
Your `.gitlab-ci.yml` should look similar to this:
```yaml
build:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:20.10.16
services:
- name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-dind
alias: docker
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
```
If you forget to set the service alias, the container image can't find the `dind` service,
and an error like the following is shown:
```plaintext
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host
```
## Container registry examples with GitLab CI/CD
If you're using Docker-in-Docker on your runners, your `.gitlab-ci.yml` file should look similar to this:
```yaml
build:
image: docker:20.10.16
stage: build
services:
- docker:20.10.16-dind
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
- docker build -t $CI_REGISTRY/group/project/image:latest .
- docker push $CI_REGISTRY/group/project/image:latest
```
You can use [CI/CD variables](../../../ci/variables/index.md) in your `.gitlab-ci.yml` file. For example:
```yaml
build:
image: docker:20.10.16
stage: build
services:
- docker:20.10.16-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
```
In this example, `$CI_REGISTRY_IMAGE` resolves to the address of the registry tied
to this project. `$CI_COMMIT_REF_NAME` resolves to the branch or tag name, which
can contain forward slashes. Image tags can't contain forward slashes. Use
`$CI_COMMIT_REF_SLUG` as the image tag. You can declare the variable, `$IMAGE_TAG`,
combining `$CI_REGISTRY_IMAGE` and `$CI_COMMIT_REF_NAME` to save some typing in the
`script` section.
This example splits the tasks into 4 pipeline stages, including two tests that run in parallel. The `build` is stored in the container
registry and used by subsequent stages, downloading the container image when needed. Changes to `main` also get tagged as
`latest` and deployed using an application-specific deploy script:
```yaml
default:
image: docker:20.10.16
services:
- docker:20.10.16-dind
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
stages:
- build
- test
- release
- deploy
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
build:
stage: build
script:
- docker build --pull -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
test1:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/tests
test2:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/another/test
release-image:
stage: release
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy:
stage: deploy
script:
- ./deploy.sh
rules:
- if: $CI_COMMIT_BRANCH == "main"
environment: production
```
NOTE:
This example explicitly calls `docker pull`. If you prefer to implicitly pull the container image using `image:`,
and use either the [Docker](https://docs.gitlab.com/runner/executors/docker.html) or [Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes/index.html) executor,
make sure that [`pull_policy`](https://docs.gitlab.com/runner/executors/docker.html#how-pull-policies-work) is set to `always`.
|