How to reduce build time for Docker images in GitLab CI





We make containerized CI environments really practical by speeding up the build of Docker images.

, . , . ,





Docker .





Python Flask:





from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'
      
      







Dockerfile

Dockerfile:





FROM python:3.7-alpine as builder

#  ,     python
RUN apk update && apk add --no-cache make gcc && pip install --upgrade pip


#  venv     
ENV VENV="/venv"
ENV PATH="${VENV}/bin:${PATH}"

COPY requirements.txt .
RUN python -m venv ${VENV} \
    && pip install --no-cache-dir -r requirements.txt

FROM python:3.7-alpine

#  venv     
ENV VENV="/venv"
ENV PATH="${VENV}/bin:$PATH"
COPY --from=builder ${VENV} ${VENV}

#   
WORKDIR /app
COPY app .

#  
EXPOSE 5000
ENV FLASK_APP="hello.py"
CMD [ "flask", "run", "--host=0.0.0.0" ]
      
      







:





  • , Python.





  • , , .





? -, , . -, , , .





.

, :





docker build -t hello .
docker run -d --rm -p 5000:5000 hello
curl localhost:5000
Hello, World!
      
      



docker build



:





docker build -t hello .
...
Step 2/15 : RUN apk update && apk add --no-cache make gcc && pip install --upgrade pip
 ---> Using cache
 ---> 24d044c28dce
...
      
      







, , Docker , .





, :





docker tag hello my-registry/hello:1.0
docker push my-registry/hello:1.0

The push refers to repository [my-registry/hello]
8388d558f57d: Pushed 
77a59788172c: Pushed 
673c6888b7ef: Pushed 
fdb8581dab88: Pushed
6360407af3e7: Pushed
68aa0de28940: Pushed
f04cc38c0ac2: Pushed
ace0eda3e3be: Pushed
latest: digest: sha256:d815c1694083ffa8cc379f5a52ea69e435290c9d1ae629969e82d705b7f5ea95 size: 1994
      
      



, . 8 , 8 docker Dockerfile FROM.





, Docker, , . - Docker .





, , CI .





Docker CI  

Docker , . . . , .





CI  





CI , :





  • GitLab.com CI





  • Kubernetes Executor GitLab Runner





, CI . , Kubernetes. CI , Docker : Docker Docker .





, :





  • /var/run/docker.sock



    , Docker, .





  • , Β«Docker in DockerΒ» ( dind) . Dind - Docker, Docker ?





.





GitLab  

GitLab , DinD, service.





docker-build, dind Kubernetes. docker, dind DOCKER_HOST



.





stages:
  - build
  - test
  - deploy

variables:
  #   Docker TLS
  DOCKER_TLS_CERTDIR: ""
  #  localhost    ,   dind  (       )
  #  ,    Docker     dind   Docker 
  DOCKER_HOST: "tcp://localhost:2375"

services:
  - docker:stable-dind

docker-build:
  image: docker:stable
  stage: build
  script:
      - docker build -t hello .
      - docker tag my-registry/hello:${CI_COMMIT_SHORT_SHA}
      - docker push my-registry/hello:${CI_COMMIT_SHORT_SHA}

      
      



. , :





docker build -t hello .

Step 1/15 : FROM python:3.7-alpine as builder
...
Step 2/15 : RUN apk update && apk add --no-cache make gcc && pip install --upgrade pip
---> Running in ca50f59a21f8
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
...
      
      







, . 1 .





, , : ! , . - . , , , .





? , dind - , , . , .





- Dind-?





Docker Docker in Docker

: Pull/Push





: (, ) .





:





  • (pull) (. . ) , docker .





  • , ( --cache-from), . SHA.





  • , , .





stages:
  - build
  - test
  - deploy
    
variables:
   #   Docker TLS
  DOCKER_TLS_CERTDIR: ""
  DOCKER_HOST: "tcp://localhost:2375"

services:
  - docker:stable-dind

docker-build:
  image: docker:stable
  stage: build
  script:
    - docker pull my-registry/hello:latest || true
    - docker build --cache-from my-registry/hello:latest -t hello:latest .

    - docker tag hello:latest my-registry/hello:${CI_COMMIT_SHORT_SHA}
    - docker tag hello:latest my-registry/hello:latest

    - docker push my-registry/hello:${CI_COMMIT_SHORT_SHA}
    - docker push my-registry/hello:latest
      
      



  





, .





. 2 (8 9) , .





, . , , , .





, ( 8 15), , . 10 , , .





, , : 2 15 ! , , :





stages:
  - build
  - test
  - deploy
    
variables:
    #   Docker TLS
  DOCKER_TLS_CERTDIR: ""
  DOCKER_HOST: "tcp://localhost:2375"

services:
  - docker:stable-dind

docker-build:
  image: docker:stable
  stage: build
  script:
    - docker pull my-registry/hello-builder:latest || true
    - docker pull my-registry/hello:latest || true

    - docker build --cache-from my-registry/hello-builder:latest --target builder -t hello-builder:latest .
    - docker build --cache-from my-registry/hello:latest --cache-from my-registry/hello-builder:latest -t hello:latest .

    - docker tag hello-builder:latest my-registry/hello-builder:latest    
    - docker tag hello:latest my-registry/hello:${CI_COMMIT_SHORT_SHA}
    - docker tag hello:latest my-registry/hello:latest

    - docker push my-registry/hello-builder:latest
    - docker push my-registry/hello:${CI_COMMIT_SHORT_SHA}
    - docker push my-registry/hello:latest
      
      



  





, target. , . 15 !





, . , 3 4 ! . , , .





: dind







dind docker. dind , .





Dind , Dind Kubernetes? PersistentVolume , docker .





Kubernetes :





apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    app: docker-dind
  name: dind
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: docker-dind
  name: dind
spec:
  replicas: 1
  selector:
    matchLabels:
      app: docker-dind
  template:
    metadata:
      labels:
        app: docker-dind
    spec:
      containers:
        - image: docker:19.03-dind
          name: docker-dind
          env:
            - name: DOCKER_HOST
              value: tcp://0.0.0.0:2375
            - name: DOCKER_TLS_CERTDIR
              value: ""
          volumeMounts:
            - name: dind-data
              mountPath: /var/lib/docker/
          ports:
            - name: daemon-port
              containerPort: 2375
              protocol: TCP
          securityContext:
            privileged: true #    dind .
      volumes:
        - name: dind-data
          persistentVolumeClaim:
            claimName: dind
            
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: docker-dind
  name: dind
spec:
  ports:
    - port: 2375
      protocol: TCP
      targetPort: 2375
  selector:
    app: docker-dind
      
      



GitLab , , dind :





stages:
  - build
  - test
  - deploy
    
variables:
   #   Docker TLS
  DOCKER_TLS_CERTDIR: ""
   #    dind   dind  Kubernetes   kube dns
  DOCKER_HOST: "tcp://dind:2375"

docker-build:
  image: docker:stable
  stage: build
  script:
    - docker build -t hello .
    - docker tag hello:latest my-registry/hello:{CI_COMMIT_SHORT_SHA}
    - docker push my-registry/hello:{CI_COMMIT_SHORT_SHA}

      
      







, 10 , , . «» , 10 , , .





: Kaniko





Kaniko. Docker Docker, , , .





, BuildKit , , , . .





, . , , . GitLab, , CI .






"CI/CD Docker Kubernetes",   .













All Articles