Gogs es un servidor de Git escrito en Go. Proporciona un interfaz web similar a GitHub.

En esta entrada se describe cómo lanzar los contenedores necesarios para tener una instalación funcional de Gogs.

Gogs requiere el uso de una base de datos para almacenar parte de la información. Gogs puede usar una base de datos incrustada como SQLite, aunque lo recomendable es unar algo como MySQL o PostgresSQL.

En nuestro caso usaremos MySQL.

La instalación de Gogs consta de tres bloques:

  1. Creación de la red brigde para conectar MySQL y Gogs
  2. Instalación de MySQL
    1. Creación del volumen para la base de datos
    2. Creación del contenedor con el motor de base de datos MySQL
  3. Instalación de Gogs
    1. Creación del volumen para los repositorios y configuración de Gogs
    2. Creación del contenedor con Gogs

Creación de la red bridge para conectar MySQL y Gogs

Como comentaba en la entrada Consideraciones generales, en internet se pueden encontrar muchos ejemplos en los que se usan el parámetro —link para conectar dos contenedores entre sí. Sin embargo este parámetro está considerado legacy y puede ser eliminado en cualquier versión de Docker, por lo que no es conveniente usarlo.

La alternativa es usar una red puente definida por el usuario (user-defined bridge network). Esta es la forma recomendada en la documentación de MySQL para desplegar MySQL en Linux con Docker: Connect to MySQL from an Application in Another Docker Container.

Creamos la red bridge a la que llamamos backend-gogs:

$ sudo docker network create backend-gogs
3e38ebb671bf595201f0d3cb37e6a6138d0f05025c1f581e3bd8cc84c844c79f
$

Comprobamos que además de las redes creadas por defecto por Docker, ahora tenemos una red bridge adicional:

$ sudo docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f53cd8a2520d        bridge              bridge              local
3cb879caa2f8        host                host                local
3e38ebb671bf        backend-gogs        bridge              local
30f938dfeaa1        none                null                local
$

Instalación de MySQL

Creación del volumen para la base de datos

Para almacenar los datos de la base de datos, creamos un volumen llamado data-mysql-gogs:

$ sudo docker volume create data-mysql-gogs
data-mysql

Creación del contenedor con el motor de base de datos MySQL

Descargamos la imagen de MySQL

$ sudo docker pull mysql:5.7
5.7: Pulling from library/mysql
2a72cbf407d6: Pull complete
38680a9b47a8: Pull complete
4c732aa0eb1b: Pull complete
c5317a34eddd: Pull complete
f92be680366c: Pull complete
e8ecd8bec5ab: Pull complete
2a650284a6a8: Pull complete
5b5108d08c6d: Pull complete
beaff1261757: Pull complete
c1a55c6375b5: Pull complete
8181cde51c65: Pull complete
Digest: sha256:691c55aabb3c4e3b89b953dd2f022f7ea845e5443954767d321d5f5fa394e28c
Status: Downloaded newer image for mysql:5.7
$

Lanzamos el contenedor con MySQL usando el volumen que hemos creado anteriormente:

Siguiendo la recomendación de Docker, usamos --mount en vez de -v o —volume para montar el volumen en el contenedor.

$ sudo docker run -d --name mysql-gogs \
   --mount source=data-mysql-gogs,target=/var/lib/mysql \
   -e MYSQL_ROOT_PASSWORD=ESmCg2g7dnNQeOY \
   -e MYSQL_DATABASE=gogs \
   -e MYSQL_USER=usrgogs -e MYSQL_PASSWORD=Zskkd6jygnK7 \
   mysql:5.7
4426d99884ae84ec4814dbfc8e5cc357fa2616a31b2104ec8b259e9f61c7e98d

No hemos conectado el contenedor a la red backend-gogs para mostrar más adelante cómo hacerlo con el contenedor en marcha.

Podemos comprobar que se ha creado una base de datos llamada gogs en MySQL y que el usuario usrgogs puede conectarse. Para ello, conectamos al contenedor y revisamos las bases de datos existentes:

$ sudo docker exec -it  mysql-gogs mysql -u usrgogs -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| gogs               |
+--------------------+
2 rows in set (0.01 sec)

mysql>

También podemos comprobar que el usuario usrgogs tiene permisos completos sobre la base de datos recién creada:

mysql> show grants for usrgogs;
+---------------------------------------------------+
| Grants for usrgogs@%                              |
+---------------------------------------------------+
| GRANT USAGE ON *.* TO 'usrgogs'@'%'               |
| GRANT ALL PRIVILEGES ON `gogs`.* TO 'usrgogs'@'%' |
+---------------------------------------------------+
2 rows in set (0.01 sec)

Salimos de la consola de MySQL con exit.

Conexión del contenedor mysql-gogs a la red `backend-gogs``

Aunque lo correcto sería conectar el contenedor a la red al crearlo, podemos conectar un contenedor en marcha a una red mediante:

$ sudo docker network connect backend-gogs mysql-gogs
$

Mediante docker inspect podemos revisar la configuración de red del contenedor y comprobar que está conectado a la red bridge y a la red backend-gogs:

...
"Networks": {
                "bridge": {
                    ...
                    "Links": null,
                    "Aliases": null,
                    ...
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    ...
                },
                "backend-gogs": {
                    ...
                    "Links": null,
                    "Aliases": [
                        "5621d1b86dd2"
                    ],
                    ...
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.2",
                    "IPPrefixLen": 16,
                    ...
                }
            }
...

Instalación de Gogs

Creación del volumen para los repositorios y configuración de Gogs

Para almacenar los datos usados por Gogs, creamos un volumen data-gogs:

$ sudo docker volume create data-gogs
data-gogs

Verificamos que se ha creado correctamente:

$ sudo docker volume ls
DRIVER              VOLUME NAME
local               data-gogs
local               data-mysql-gogs
$

Creación del contenedor con Gogs

Descargamos la imagen:

$ sudo docker pull gogs/gogs:0.11.43
0.11.43: Pulling from gogs/gogs
550fe1bea624: Pull complete
d4768cab464c: Pull complete
a09a9b9a1b84: Pull complete
e96e27ca5c6f: Pull complete
610b4353a17a: Pull complete
e1d24556ad31: Pull complete
a8aa7b0b6f56: Pull complete
8dec4c0e4bba: Pull complete
7b83320ea32c: Pull complete
6a575b348264: Pull complete
1c038aa19116: Pull complete
Digest: sha256:1180a8381b40d2c64c09898058dba477483c581096cdce68284b30c91ec1f2a9
Status: Downloaded newer image for gogs/gogs:0.11.43
$

Ahora lanzamos el contenedor para GoGS (conectándolo a la red backend-gogs para que pueda usar MySQL):

Siguendo la recomendación de Docker, usamos --mount en vez de -v o —volume para montar el volumen en el contenedor.

$ sudo docker run -d --name gogs \
   --mount source=data-gogs,target=/data \
   -p 10022:22 -p 10080:3000 \
   --network backend-gogs \
   gogs/gogs:0.11.43
787565af362b2e7f1cd4fe2355720cd64e5a7dffee3d23cddec97fcd69ab6f0b

Hemos conectado el contenedor a la red backend-gogs usando --network backend-gogs como parámetro en el comando docker run.

Validamos que el contenedor sigue corriendo:

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES
787565af362b        gogs/gogs:0.11.43   "/app/gogs/docker/st…"   56 seconds ago      Up 55 seconds       0.0.0.0:10022->22/tcp, 0.0.0.0:10080->3000/tcp   gogs
5621d1b86dd2        mysql:5.7           "docker-entrypoint.s…"   About an hour ago   Up About an hour    3306/tcp                                         mysql
$

Si todo ha funcionado correctamente, podemos acceder a la interfaz web de GoGS a través del puerto 10080 (el puerto 10022 es para las conexiones vía SSH).

Desde la línea de comandos verificamos que al acceder a GoGS (por primera vez) se ejecuta el asistente de configuración:

$ curl localhost:10080
<a href="/install">Found</a>.

Puedes obtener la IP del host con Docker vía ip address show y revisar la IP asignada al interfaz de red (habitualmente, el eth0).

Así que usamos un navegador y apuntamos a http://{$IPHOSTDOCKER}:10080:

Gogs install

Gogs install

Conexión con la base de datos

Como hemos lanzado un contenedor con MySQL, seleccionamos el tipo de base de datos MySQL en Database Type.

En el campo host, debemos indicar el nombre del contenedor donde corre MySQL. El contenedor gogs y el mysql, al estar conectados a la misma red bridge, comparten todos los puertos y pueden encontrarse a través del nombre. En este caso, en host, indicamos mysql-gogs:3306.

Usaremos un usuario sin privilegios globales en el servidor de base de datos; en nuestro caso, hemos definido el usuario usrgogs.

Dejamos gogs como nombre de la base de datos usada por GoGS.

Configuración general de la aplicación

  • Application Name : Gogs
  • Repository Root Path: /data/git/gogs-repositories
  • Run User: git
  • Domain: $(IPHOSTDOCKER)
  • SSH Port: 10022 (recuerda que hemos mapeado el puerto local 22 al 10022 al crear el contenedor)
  • HTTP Port: 3000
  • Application URL: http://$(IPHOSTDOCKER):10080 (recuerda que hemos mapeado el puerto local 3000 al 10080 al crear el contenedor)
  • Log Path: /app/gogs/log

El puerto en el que la aplicación escucha dentro del contenedor (HTTP_PORT) es el 3000, pero el acceso desde fuera del contenedor se realiza a través del puerto 10080.

Configuración adicional: Cuenta de administrador

De la configuración adicional, algunas personalizaciones:

  • Deshabilito la opción de auto-registro (Disable Self-registration)
  • Habilito el modo offline (Enable Offline Mode); esto marca automáticamente la casilla Disable Gravatar Service.

Finalmente, creo una cuenta para el administrador:

  • Username: operador
  • Password: ********** ;)
  • Confirm Password: **********
  • Admin email: operador@local.dev

La configuración de correo implica introducir el servidor de correo y la dirección que se mostrará como remitente del correo:

  • Mailserver: $(IPHOSTDOCKER)
  • Port: 10025
  • gogs-notify@local.dev

Después de comprobar que todos los parámetros son correctos, pulsamos Install Gogs.

Si todo va como debe, se nos presenta el Dashboard del usuario operador:

Gogs Dashboard

Gogs Dashboard

Validación del envío de correo

  1. Accedemos a GoGS
  2. Pulsamos sobre el avatar en la parte superior derecha de la ventana.
  3. En el menú desplegable, seleccionamos Admin Panel.
  4. En el panel lateral de la izquierda, seleccionamos Configuration.
  5. Buscamos la sección Mailer Configuration:
Gogs Mail test

Gogs Mail test

Podemos introducir una dirección de correo para validar que hemos configurado correctamente el servidor de correo.

Configuración del envío de correo en Gogs

La prueba de envío de correo fallará con el mensaje de error:

Gogs Mail Error

Gogs Mail Error

La causa está en que no se está usando un certificado válido (de hecho, no se ha configurado ningún certificado).

Para solucionarlo, debemos editar la configuración de Gogs y reiniciar el contenedor.

En la documentación de Gogs se recomienda crear un fichero custom/conf/app.ini pero después de varios intentos en diferentes ubicaciones, he decidido modificar el fichero original en /data/gogs/conf/app.ini.

Conectamos al contenedor y editamos el fichero (después de hacer una copia de seguridad):

$ sudo docker exec -it gogs /bin/sh
/app/gogs/build # cp /data/gogs/conf/app.ini /data/gogs/conf/app.ini.bkp
/app/gogs/build # vi /data/gogs/conf/app.ini

Editamos la sección [mailer] de la configuración añadiendo el parámetro SKIP_VERIFY = true:

[mailer]
ENABLED = true
HOST    = 192.168.1.209:10025
FROM    = gogs-notify@local.dev
USER    = gogs-notify@local.dev
PASSWD  =
SKIP_VERIFY = true

Guardamos y salimos del contenedor. Para que los efectos surtan efecto, reiniciamos el servidor:

$ sudo docker restart gogs
gogs

Tras el reinicio, al enviar una prueba de correo:

Gogs Mail sent

Gogs Mail sent

Si revisamos la bandeja de entrada de MailDev, comprobamos la recepción del correo de prueba:

Gogs Inbox

Gogs Inbox

Si seleccionamos Mail, Source, podemos ver todos los detalles del correo enviado (como la dirección From, configurada en el fichero app.ini):

Gogs Mail details

Gogs Mail details

En la página Configuration Cheat Sheet tienes todas las variables de configuración definidas en Gogs. Por ejemplo, si quieres que al acceder a Gogs se muestre la página Explore (con el listado de repositorios) en vez de Home (con el logo de Gogs), puedes cambiar el comportamiento usando la variable LANDING_PAGE.