DEV Community

Mario García
Mario García

Posted on

Publish a Docker image to Docker Hub using GitLab

If you need to create a custom Docker image that includes the tools you need for your projects, a way to automate the building process and publish that image on Docker Hub is using GitLab CI.

First you create a new GitLab project and add a Dockerfile with instructions on how to build the image. The following is the Dockerfile for an image that contains development tools for Python and Rust, based on the official Docker image of Rust, that you can find here.

FROM rust:slim-buster
RUN apt-get -y update
RUN apt-get install -y sudo

RUN adduser --disabled-password --gecos '' admin
RUN adduser admin sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN chown -R admin /home/admin

USER admin

RUN sudo apt-get install -y python3 make build-essential libssl-dev zlib1g-dev libbz2-dev \
    libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
    xz-utils tk-dev libffi-dev liblzma-dev python-openssl git && \
    curl https://pyenv.run | bash && \
    curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3

ENV HOME /home/admin
ENV PYENV_ROOT $HOME/.pyenv
ENV POETRY_ROOT $HOME/.poetry
ENV CARGO_ROOT /usr/local/cargo
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
ENV PATH $POETRY_ROOT/bin:$PATH
ENV PATH $CARGO_ROOT/bin:$PATH
Enter fullscreen mode Exit fullscreen mode

Then go to Settings => CI/CD, click on Expand in the Variables section and add the following variables:

  • CI_REGISTRY
  • CI_REGISTRY_IMAGE
  • CI_REGISTRY_PASSWORD
  • CI_REGISTRY_USER

CI_REGISTRY_USER must contain your Docker HUB username.
CI_REGISTRY_PASSWORD must contain your Docker HUB password or your access token (if you have 2FA activated).
CI_REGISTRY must contain docker.io.
CI_REGISTRY_IMAGE must contain index.docker.io/username/image_name.

Now you have to configure GitLab CI, add a .gitlab-ci.yml file. The content of this file is (it can be created using a template from the editor):

# This file is a template, and might need editing before it works on your project.
docker-build-master:
  # Official docker image.
  image: docker:latest
  stage: build
  services:
    - docker:dind
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - docker build --pull -t "$CI_REGISTRY_IMAGE" .
    - docker push "$CI_REGISTRY_IMAGE"
  only:
    - master

docker-build:
  # Official docker image.
  image: docker:latest
  stage: build
  services:
    - docker:dind
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
  except:
    - master
Enter fullscreen mode Exit fullscreen mode

Once you add this file, the pipeline will run.

Pipeline running

And your image will be available from Docker Hub for you to use it on your projects.
Docker Hub

And finally, if you want the building process to be executed daily, weekly or any time as you need, you can schedule the pipeline on your repository.

Go to CI/CD => Schedules, add a New schedule and configure according to your need.
Schedule a new pipeline

Top comments (3)

Collapse
 
mannawar profile image
Mannawar Hussain

If i am using multiple images, then how to add those images as variable ?

Collapse
 
mattdark profile image
Mario García

Hi. Sorry for my late reply. Can you explain your question a little more?

Collapse
 
mannawar profile image
Mannawar Hussain

Thanks Mario. Its done now