Descubrí hace unos días y empecé a dar mis primeros pasos con Docker. En el post de hoy voy un paso más y describo cómo he creado mi primer contenedor real, un servidor GIT privado (con «gitolite»). Antes de empezar, Git es un software de control de versiones y Gitolite permite hospedar repositorios Git en tu propio servidor de forma sencilla y segura.
Instalación
Para poner en marcha un contenedor hay que partir de una «imagen» mínima con el Sistema Operativo, así que mi primera intención fue usar Gentoo, pero desistí porque fui incapaz de encontrar o crear yo mismo una imagen de menos de 750-900MB (lo ideal es quedarse por debajo de 100MB-200MB).
Conclusión, como «Host» uso GNU/Linux Gentoo y para los contenedores desde «Debian«.
Preparar el Host
Lo primero es tener instalado docker en el host, aquí tienes un artículo sobre mi instalación.
Disco de datos persistente en el Host
Te recomiendo que el directorio donde vas a dejar los repositorios de tu servidor GIT sea un directorio en el Host, externo al contenedor, de modo que sea persistente.
He elegido el directorio /Apps de mi servidor como la raiz donde voy a dejar tanto los scripts como el directorio persistente para los repositorios:
1 2 3 4 | /Apps/ +--/data <== Datos de mis servicios (incluido repositorios Git) | +--/docker <== scripts y ficheros necesarios para docker |
De esta forma tengo todo lo importante en un solo sitio «persistente», aunque borre el contenedor o imagen de docker los repositorios se mantienen y podré reinstalar (docker/imagen/contenedor) para tener el servicio funcionando literalmente en 5 minutos…
Usuarios en el Host
Creo dos usuarios importantes:
- luis – Mi usuario, un usuario normal para no tener que usar root
- git – Aunque no hace falta creo en el Host el usuario/grupo «git:git» con el mismo UID/GID que tendrá en el contenedor para darle los permisos y propietario al directorio de los repositorios y así tener coherencia dentro y fuera:
Directorio /Apps
Asigno mi usuario como propietario de la raiz
1 2 3 | totobo git # chown luis:luis /Apps |
Usuario y grupo git:git
Para tener coherencia con lo que verán los contenedores:
1 2 3 4 | totobo ~ # groupadd -g 1600 git totobo ~ # useradd -u 1600 -g git -G git -s /sbin/nologin git |
Scripts y Dockerfile
En los enlaces siguientes tienes todo lo necesario:
- Imagen base: GitHub: base-gitolite + Docker Hub Registry: luispa/base-gitolite
- Servicio: GitHub: servicio-gitolite
Solo tienes que bajarte este último:
1 2 3 4 | totobo ~ $ cd /Apps/docker/ totobo docker $ git clone https://github.com/LuisPalacios/docker-gitolite.git |
Nuevo versus Migración
Antes de arrancarlo, tenemos dos opciones:
* Arrancar el servidor «vacío» sin repositorios y empezar desde cero
* Arrancar el servidor usando respositorios de una instalación previa (migración)
Instalación nueva
Dejo el directorio /Apps/data/git/repositories vacío y asigno a git:git como el propietario del mismo.
1 2 3 4 5 6 | totobo ~ # mkdir -p /Apps/data/git totobo ~ # cd /Apps/data/git totobo git # chown -R git:git repositories totobo git # chmod -R 750 repositories |
Arranco la Aplicación (contenedor):
1 2 3 | totobo ~ $ cd /Apps/docker/servicio-gitolite totobo docker-gitolite $ <strong>fig up</strong> |
A continuación clonamos gitolite-admin y empiezo a trabajar, añadir otros puestos de trabajo, sus claves, etc.
1 2 3 4 | ~ $ cd /home/luis/tmp tmp $ git clone ssh://git@totobo.parchis.org:1600/gitolite-admin |
Migración
A la hora de migrar repositiorios desde otro servidor antiguo a mi nuevo Host (a su directorio persistente) el proceso también es muy sencillo: hago un backup del antiguo, lo recupero en el nuevo y al arrancar el contenedor se dará cuenta y respetará la estructura existente.
Backup de repositorio existente
Empezamos haciendo un backup del directorio de repositorios del servidor antiguo.
1 2 3 4 | servidor_antiguo # cd /data/antiguo/dir/git servidor_antiguo # tar cfz /tmp/backup_repos.tgz ./repositories |
Recuperar repositorio en el nuevo Host
1 2 3 4 5 6 7 8 9 10 | EN EL SERVIDOR ANTIGUO servidor_antiguo # scp /tmp/backup_repos.tgz luis@totobo.parchis.org:/tmp EN EL NUEVO Servidor: totobo # cd /Apps/data/git totobo # tar xfz /tmp/backup_repos.tgz totobo # chown -R git:git repositories/ totobo # chmod -R g+rx repositories/ |
Arrancar el contenedor
Creo y arranco el contenedor, detectará que el directorio repositories tiene repos existentes y actuará en consecuencia:
1 2 3 4 | totobo ~ $ cd /Apps/docker/servicio-gitolite totobo docker-gitolite $ fig up |
Comprobar que los repositorios están disponibles
Desde un cliente remoto que teníamos autorizado en el repositorio original
1 2 3 4 5 6 7 8 9 10 11 12 | obelix:~ luis$ ssh -p 1600 git@totobo.parchis.org hello ClaveLuisObelix, this is git@1279cc5fb4ed running gitolite3 v3.6.2-3-ge7752fc on git 1.9.1 R W abaco-swift R W abaco-arte R W gitolite-admin R W espresso : Connection to totobo.parchis.org closed. obelix:~ luis$ |
Acceso y consumo de los repositorios
Ahora que tenemos todo funcionando ya puedo consumir mis repositorios desde el programa «git». Mucho más sencillo y visual, recomiendo SourceTree, una maravilla para MacOSX.
Línea de comandos
1 2 3 4 | $ git clone ssh://git@totobo.parchis.org:1600/espresso : |
Herramienta gráfica SourceTree
Arranque durante el boot del Host
Para arrancar el contenedor durante el boot del equipo (recordar que el Host está basado en Gentoo con openrc) es tan sencillo como crear un script en el directorio /etc/init.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/sbin/runscript # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ depend() { need net need localmount need nfsmount after sshd } start() { ebegin "Arranando servicio: Gitolite" su luis -c "cd /Apps/docker/servicio-gitolite && /usr/local/bin/fig up -d --no-recreate" eend $? } stop() { ebegin "Parando servicio: Gitolite" su luis -c "cd /Apps/docker/servicio-gitolite && /usr/local/bin/fig stop" eend $? } status() { su luis -c "cd /Apps/docker/servicio-gitolite && /usr/local/bin/fig ps" eend $? } |
Por último programo el arranque automático en cada boot
1 2 3 | # rc-update add servicio-gitolite default |
Si usas systemd, te dejo un par de ejemplos de ficheros de servicios:
1 2 3 4 5 6 7 8 9 10 11 12 | [Unit] Description=Servicio GIT After=syslog.target network.target auditd.service docker.service Apps.mount [Service] Type=oneshot ExecStart=/bin/bash /Apps/docker/servicio-gitolite/start-fig.sh ExecStop=/bin/bash /Apps/docker/servicio-gitolite/stop-fig.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target |
1 2 3 4 5 6 7 8 9 10 11 | [Unit] Description=Apps Wants=network.target rpc-statd.service After=network.target rpc-statd.service [Mount] What=panoramix.parchis.org:/Apps Where=/Apps Type=nfs StandardOutput=syslog StandardError=syslog |
No te pierdas el siguiente post sobre cómo configurar múltiples servicios en varios contenedores docker.
Leave a Reply