Servidor de Git privado con Gogs

Gogs logoEl único problema que tengo con GitHub es que en su versión gratuita todos los repos tienen que ser públicos. Si queremos tener repositorios privados tenemos que pasar por caja, y creo que son unos 7$ al mes, que me parece cojonudo, pero en mi caso necesito minimizar al máximo el coste de mis sistemas, principalmente porque no me da dinero.

Así que estuve investigando que alternativas tenia para instalar un servidor de Git privado. Lo primero que me vino a la cabeza fue GitLab, porque lo he utilizado durante una buena temporada en el trabajo con equipos relativamente grandes y nos ha dado muy buen resultado. En mi actual empresa estamos usando Bitbucket de Atlasian, y prácticamente es lo mismo que teníamos con GitLab, pero al ser de pago no es una opción para mi.

Una vez decidido a instalar GitLab, el problema está cuando te pones a mirar los requisitos:

  • 4GB de RAM es lo recomendado.
  • 2GB de RAM + 2GB de swap, ya te dicen que va a ir como el culo
  • Se necesitan varios GB de espacio en disco solo para la instalación de GitLab

Demasiada caña para mi pobre servidor, y mas si pienso servir desde la misma máquina un par de sitios o algún otro servicio, necesitaba algo mas ligero pero que al menos molase (ya que estamos...).

Así que después de dar algunas vueltas e investigar un poco, acabé encontrando Gogs:

https://gogs.io/

Según ellos mismos, Gogs es:

Gogs is a painless self-hosted Git service.

Que viene a ser un servicio de Git que te alojas tu mismo e indoloro.

Y la verdad es que no ha sido nada doloroso, llevo ya varios meses usándolo y ha sido una gran opción, y es que fue muy sencillo de instalar, viene con un montón de funcionalidades de serie, y tiene una interfaz muy pulida y que es calcada a GitHub.

Entre las funcionalidades interesantes:

  • Open Source
  • Ligero, muy ligero. Esta ocupando menos de 500Mb en disco (con las sus fuentes y las de Go) y aun no lo he visto sobrecargar la máquina.
  • Gravatar (venga va...)
  • Pull request, funcionan igual que Github
  • Webhooks !! (esto ya es lo mas, pero no los he probado aún)
  • Notificaciones por correo
  • Soporta SSH, tanto para servir la aplicación como para los repos
  • Tickets para incidencias, sencillo pero útil.
  • Wiki para cada proyecto
  • Creación de cuentas de usuario: Con registro o manual
  • Permite desactivar el registro de usuarios
  • Permite configurar repositorios privados
  • Webhooks, espera esto ya lo había dicho, ¿no?

 

Instalación

La ayuda oficial para la instalación la podéis encontrar aquí (todo en inglés):

La instalación oficial la están haciendo con Ngnix y postgresql. Yo lo monté tirando de un viejo Apache2 y MySQL que ya tenia corriendo. Voy a hacer una traducción de la instalación que son los pasos que yo he seguido, y luego pongo mis archivos de configuración. Y ojo, que estos pasos son para instalarlo desde el fuente, que es lo que hice yo.

Lo que queremos hacer es:

  • Servir ‘Gogs’ desde un dominio midominio.com, por ejemplo como git.midominio.com
  • Apache2 como servidor web
  • MySQL como servidor de base de datos

Primero creamos un usuario para que corra la aplicación:

$ sudo adduser --disabled-login --gecos 'Gogs' git

Descarga e instalación de Go

Vamos a instalar Go dentro del home del usuario que acabamos de crear para no interferir con ninguna otra versión de la distribución que usemos. Usaremos

/home/git/local/go

Creamos un directorio:

$ sudo su - git
$ cd ~
$ mkdir local

Bajamos la versión disponible:

$ wget https://storage.googleapis.com/golang/go1.7.3.linux-amd64.tar.gz
$ tar -C /home/git/local -xzf go1.7.3.linux-amd64.tar.gz

Añadimos unas cuantas rutas al fichero bashrc de nuestro usuario git:

$ sudo su - git
$ cd ~
$ echo 'export GOROOT=$HOME/local/go' >> $HOME/.bashrc
$ echo 'export GOPATH=$HOME/go' >> $HOME/.bashrc
$ echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> $HOME/.bashrc
$ source $HOME/.bashrc

Instalar Gogs

La forma rápida de instalar Gogs parece ser esta:

$ go get -u github.com/gogits/gogs 
$ cd $GOPATH/src/github.com/gogits/gogs 
$ go build

Y una vez compilado, podemos probarlo con:

$ cd $GOPATH/src/github.com/gogits/gogs
$ ./gogs web

Configuración

La configuración por defecto está en conf/app.ini pero no vamos a editar ese fichero. En lugar de eso Gogs nos permite crear una copia que será donde pondremos nuestras modificaciones. Primero vamos a crear unos directorios:

mkdir -p $GOPATH/src/github.com/gogits/gogs/custom/conf
mkdir -p ~/gogs-repositories
sudo mkdir -p /var/log/gogs
sudo chown git:git /var/log/gogs

Hacemos una copia del fichero de configuración original, en donde haremos nuestros cambios:

cd $GOPATH/src/github.com/gogits/gogs
cp conf/app.ini custom/conf/

En teoría en nuestro fichero de configuración 'custom' solamente deberíamos tener la configuración especifica que necesitemos. Es decir, que podemos borrar todo lo que se quede por defecto. La principal razón de esto es que cuando actualicemos la versión de Gogs, nuestra configuración no se modificará, ya que tienen un .gitignore para este fichero local. Este es el fichero que yo tengo:

; Change it if you run locally
RUN_USER = git
; Either "dev", "prod" or "test", default is "dev"
RUN_MODE = prod

[repository]
ROOT                      = /home/git/gogs-repositories

[server]
PROTOCOL               = http
DOMAIN                 = git.midominio.com
ROOT_URL               = http://git.midominio.com/
HTTP_ADDR              = 0.0.0.0
HTTP_PORT              = 3000

[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
DB_TYPE  = mysql
HOST     = 127.0.0.1:3306
NAME     = gogs
USER     = gogs
PASSWD   = **CONTRASEÑA**

[admin]

[security]
INSTALL_LOCK                      = true
; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!!

#@FDEWREWR&*(
SECRET_KEY                        = *KEY*

; Auto-login remember days
LOGIN_REMEMBER_DAYS               = 7
COOKIE_USERNAME                   = gogs_awesome
COOKIE_REMEMBER_NAME              = gogs_incredible
; Reverse proxy authentication header name of user name
REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER

[service]
ACTIVE_CODE_LIVE_MINUTES               = 180
RESET_PASSWD_CODE_LIVE_MINUTES         = 180
; User need to confirm e-mail for registration
REGISTER_EMAIL_CONFIRM                 = false
; Does not allow register and admin create account only
DISABLE_REGISTRATION                   = true
; User must sign in to view anything.
REQUIRE_SIGNIN_VIEW                    = false
; Mail notification
ENABLE_NOTIFY_MAIL                     = false

[log]
ROOT_PATH  = /home/git/go/src/github.com/gogits/gogs/log
; Either "console", "file", "conn", "smtp" or "database", default is "console"
; Use comma to separate multiple modes, e.g. "console, file"
MODE = file
; Buffer length of channel, keep it as it is if you don't know what it is.
BUFFER_LEN = 10000
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
LEVEL = Info

 

Configurar Apache2 con Gogs

Si quereis usar Nginx en lugar de Apache, la ayuda oficial tiene la info necesaria. En Debian podemos instalar Apache2 si no lo tenemos ya:

sudo apt-get install apache2

La instalación de Gogs que acabamos de hacer corre en el puerto 3000 por defecto. Lo que queremos hacer es utilizar un servidor web como proxy para poder servir Gogs desde el puerto 80, como un subdominio de nuestro dominio, por ejemplo en este caso:

http://git.midominio.com

La mejor forma de hacer esto es crear un fichero de configuración para hacer un VirtualHost y usar mod_proxy para poder servir Gogs en el puerto 80 con Apache.

vi /etc/apache2/sites-available/080-gogs.conf

El contenido del fichero puede ser tan simple como esto:

<VirtualHost *:80>
  ServerName git.midominio.com

  ProxyPreserveHost On
  ProxyPass        / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/

  ErrorLog ${APACHE_LOG_DIR}/gogs-error.log
  CustomLog ${APACHE_LOG_DIR}/gogs-access.log combined

</VirtualHost>

El nombre del dominio que usemos aqui será el mismo que pondremos en la configuración de Gogs. Aún tenemos que activar este VirtualHost:

ln -s /etc/apache2/sites-available/080-gogs.conf /etc/apache2/sites-enabled/

Ahora activaremos el módulo mod_proxy de Apache. Podemos probar con a2enmod:

$ sudo a2enmod proxy

Esto debería crear los dos ficheros necesarios dentro de /etc/apache2/mods-enabled/ : proxy.conf y proxy.load

Reiniciar Apache y a correr. Con suerte no tendreis ningún error.

$ sudo service apache2 restart

 

Configurar MySQL

No voy a entrar en detalles sobre la configuración inicial de MySQL, porque eso daría para un libro entero. En principio bastará con crear una base de datos nueva y asignar todos los permisos a un usuario para Gogs:

CREATE DATABASE gogs CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON gogs.* To 'gogs'@'localhost' IDENTIFIED BY 'password';

Lo suyo sería ahora verificar la conexión a la nueva base de datos para estar seguros de que funciona correctamente, por ejemplo, desde la linea de comandos:

mysql --user=gogs --password=password --host=localhost gogs

 

Ejecutar el instalador

Llegado este punto deberíamos tener todo lo necesario para arrancar el dichoso Gogs. Lo arrancamos manualmente con:

$ cd $GOPATH/src/github.com/gogits/gogs
$ ./gogs web

Si ahora usamos un navegador para acceder a la dirección que hayamos configurado en nuestro Apache, deberiamos acceder a la primera pantalla del instalador, que nos guiará por la configuración básica. En nuestro ejemplo seria:

http://git.midominio.com

 

Añadir Gogs a init.d

Llegados a este punto todo deberia estar funcionando, sin embargo necesitamos arrancar Gogs a mano. Lo que necesitamos es poder levantar y parar Gogs como un servicio mas de nuestra máquina, y además, que este arranque automaticamente al levantar o reiniciar el servidor.

Para esto los chavales de Gogs nos han preparado una plantilla que nos facilitará mucho las cosas (para Debian / Ubuntu). Esta aqui:

$GOPATH/src/github.com/gogits/gogs/scripts/init/debian/gogs

La copiamos al directorio de init.d:

$ sudo cp $GOPATH/src/github.com/gogits/gogs/scripts/init/debian/gogs /etc/init.d/gogs

Y ahora modificamos un par de cosas. Editaremos las dos primeras lineas:

# Required-Start:    $syslog $network
# Required-Stop:     $syslog

De esta manera

# Required-Start:    $syslog $network $local_fs apache2 mysql
# Required-Stop:     $syslog $local_fs

Y nos aseguramos de que la variable WORKINGDIR apunte al directorio correcto:

WORKINGDIR=/home/git/go/src/github.com/gogits/gogs

El script necesita permisos de ejecución, y lo añadimos a la configuración de inicio:

$ sudo chmod ug+x /etc/init.d/gogs
$ sudo update-rc.d gogs defaults 30 70

Ahora podemos probar nuestra configuración y levantar el servicio gogs:

$ sudo service gogs start

Y conectar con un navegador a la URL que hemos configurado

http://git.midominio.com

Listo, espero que disfrutéis tanto como yo montando este pollo. Ahora ya nadie podrá ver los WTF que tenéis en vuestro código.