mcarmona99 / CineTickets

Aplicación para compra de entradas de cine
GNU General Public License v3.0
0 stars 0 forks source link

No hay documentación sobre subida del contenedor a Docker Hub y actual. auto #47

Closed mcarmona99 closed 2 years ago

mcarmona99 commented 2 years ago

Se debe de subir el contenedor correctamente a Docker Hub y documentar la actualización automática. Esto debe de quedar documentado en el proyecto.

Referente al producto mínimamente viable Interno 3 (https://github.com/mcarmona99/CineTickets/milestone/7). En este hito en el que ampliamos el producto, se desarrolla la infraestructura necesaria para desplegar la aplicación en un contenedor. La documentación de la subida a Docker Hub y actualización automática es primordial ya que este paso es el necesario para que los tests sean lanzados de manera automática al modificar algo en el repositorio.

mcarmona99 commented 2 years ago

Referencias:

Subida del contenedor a Docker Hub

En primer lugar, creamos una cuenta de Docker Hub.

Los repos de Docker Hub te permiten compartir imagenes de contenedores. En nuestro caso, serán usadas para ser construidas automáticamente desde GitHub al encontrar cambios en el repo.

Para crear el repo, es importante tener en cuenta ciertas restricciones, una de ellas quizás la más importante, el nombre del repo debe de ser en minúscula. Ademas, la descripción debe tener hasta 100 caracteres.

Una vez se crea el repositorio, como vemos en la imagen,

image

tenemos que subir la imagen de nuestro Dockerfile.

Seguimos ahora la sección llamada Pushing a Docker container image to Docker Hub.

Construcción de la imagen con tag:

$ docker build . -t mcarmona99/cinetickets:0.1
Sending build context to Docker daemon  885.2kB
Step 1/5 : FROM python:3.8-alpine3.13
 ---> f5b5076daaef
Step 2/5 : RUN apk add gcc libc-dev libffi-dev && pip install poetry pypyr
 ---> Using cache
 ---> 2ce49fbdd703
Step 3/5 : COPY . /app
 ---> Using cache
 ---> d31f33c75301
Step 4/5 : WORKDIR /app
 ---> Using cache
 ---> 423be4c206b7
Step 5/5 : CMD ["pypyr", "tests"]
 ---> Using cache
 ---> 76b8ccaac0e7
Successfully built 76b8ccaac0e7
Successfully tagged mcarmona99/cinetickets:0.1

Subida de la imagen:

$ docker push mcarmona99/cinetickets:0.1
The push refers to repository [docker.io/mcarmona99/cinetickets]
72ba302ede9d: Preparing 
8ceaf09019de: Preparing 
a371e755efd7: Preparing 
72da5b12fa0b: Preparing 
db1287f7a640: Preparing 
71ae3b9da9b3: Waiting 
7fcb75871b21: Waiting 
denied: requested access to the resource is denied

Este error ocurre porque previo a la subida, tenemos que loguearnos en Docker con docker login (ref: https://stackoverflow.com/questions/41984399/denied-requested-access-to-the-resource-is-denied-docker):

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: mcarmona99
Password: 
WARNING! Your password will be stored unencrypted in /home/manuel/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Tras esto, el push se realiza correctamente:

$ docker push mcarmona99/cinetickets:0.1
The push refers to repository [docker.io/mcarmona99/cinetickets]
72ba302ede9d: Pushed 
8ceaf09019de: Pushed 
a371e755efd7: Mounted from library/python 
72da5b12fa0b: Mounted from library/python 
db1287f7a640: Mounted from library/python 
71ae3b9da9b3: Mounted from library/python 
7fcb75871b21: Mounted from library/python 
0.1: digest: sha256:b609a9f6a53b6d37029a99ac2d2c15de1c69f3ad9b1fcd788f2143b7fc59cfe6 size: 1790

La imagen se ha subido correctamente a Docker Hub:

image

mcarmona99 commented 2 years ago

Actualizaciones automáticas

Docker Hub permite configurar construcciones automáticas desde GitHub y BitBucket. Ref: https://docs.docker.com/docker-hub/builds/link-source/

Sin embargo, esto sólo es posible con la versión Pro, que es de pago:

image

Mi cuenta fue creada en Julio de 2020, es decir, antes que esta feature fuese de pago, pero no hicé el link entonces.

Tenemos varias alternativas para hacer frente a este problema y conseguir la actualización automática. En clase hemos hablado de las GitHub actions, que será lo que utilicemos. Ref: https://github.com/features/actions

Seguimos esta guía para aprender a diseñar nuestro workflow. Estos workflow son básicos, necesitamos construir una GitHub Action que actualice el contenedor de Docker en Docker Hub, con lo que necesitamos profundizar en el tema.

En este enlace, se explica cómo construir y subir imágenes de Docker desde una GitHub Action.

Esta acción usa el contexto de Git, con lo que no es necesario usar la Action actions/checkout. Si el repositorio fuese privado, necesitaríamos un Token en la Action.

La Action ejemplo es la siguiente:

name: ci

on:
  push:
    branches:
      - 'master'

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        uses: docker/login-action@v1 
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: user/app:latest

A continuación, realizo algunos cambios para adaptarla a mi caso de uso.

En primer lugar, como mi proyecto está basado en issues y pull requests, no quiero actualizar la imagen al pushear en master, que es lo que tenemos por defecto. En mi caso quiero actualizarla para todas las ramas en su respectivo pull request. Para ello, cambio la etiqueta on por on: [pull_request]. Ref: https://futurestud.io/tutorials/github-actions-run-on-pull-request

Como vemos en los steps, se usa el TOKEN y USERNAME de DockerHub en dos variables, dentro de secrets. Sigo esta guía para configurar esos dos secretos. Concretamente, este link.

image

Con respecto al Token de Docker Hub, se refiere justamente a la contraseña de la cuenta. Con esto, ya tenemos los dos secretos:

image

Este sería el workflow final:

name: Update Docker image

on: [pull_request]

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: mcarmona99/cinetickets:latest