Servidor de Git privado con Gogs
El ú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:
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):
- Instalación desde fuentes: https://gogs.io/docs/installation/install_from_source
- Ejecución: https://gogs.io/docs/installation/configuration_and_run
- Instalación avanzada: https://gogs.io/docs/advanced/configuration_for_source_builds
- Instalación desde binarios: https://gogs.io/docs/installation/install_from_binary
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.