Docker 

    The following is an example .gitlab-ci.yml file demonstrating a container build using the common Docker-in-Docker technique. For a variety of reasons, including performance, the DinD storage is placed in memory and is limited by the service container memory (default of 2Gi unless changed via service_memory). If more is needed for, large images, increase it as shown.

    container:
      stage: build
      variables:
        DOCKER_VERSION: 28.0.2
        DOCKER_HOST: tcp://docker:2375
        DOCKER_TLS_CERTDIR: ""
      services:
        - name: docker:${DOCKER_VERSION}-dind
          alias: docker
          command: ["--tls=false"]
          variables:
            KUBERNETES_SERVICE_MEMORY_REQUEST: "8Gi"
      image: docker:${DOCKER_VERSION}
      script: docker buildx build .
    

    Workflow 

    Instead of the common approach of building everything in a Dockerfile it is generally preferred to build the application outside the container build process and copy the result into the container. Builds on the outside will benefit from the Intelligent Cache and thus be more performant and reliable.

    For those already avoiding the build layers ending up in the final image using a multistage build this approach simply moves the first build into the CI job and copies from the build context.

    For example, a multistage build like the following:

    FROM toolchain:1.2.3 as build
    RUN install_dependencies
    RUN compile
    
    FROM scratch
    COPY --from=build /app /app
    

    Becomes:

    container:
      # ...
      image: toolchain:1.2.3
      script:
        - install_dependencies
        - compile
        - docker buildx build .
    
    FROM scratch
    COPY app /app