summaryrefslogtreecommitdiff
path: root/doc/user/packages/container_registry/build_and_push_images.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user/packages/container_registry/build_and_push_images.md')
-rw-r--r--doc/user/packages/container_registry/build_and_push_images.md214
1 files changed, 214 insertions, 0 deletions
diff --git a/doc/user/packages/container_registry/build_and_push_images.md b/doc/user/packages/container_registry/build_and_push_images.md
new file mode 100644
index 00000000000..bbb82300488
--- /dev/null
+++ b/doc/user/packages/container_registry/build_and_push_images.md
@@ -0,0 +1,214 @@
+---
+stage: Package
+group: Container Registry
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Build and push container images to the Container Registry **(FREE)**
+
+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/yaml/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:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ - 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:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ - 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_REGISTRY_IMAGE` 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
+image: docker:20.10.16
+services:
+ - docker:20.10.16-dind
+
+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
+
+before_script:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+
+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
+ only:
+ - main
+
+deploy:
+ stage: deploy
+ script:
+ - ./deploy.sh
+ only:
+ - 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.html) executor,
+make sure that [`pull_policy`](https://docs.gitlab.com/runner/executors/docker.html#how-pull-policies-work) is set to `always`.