
Prólogo
Recientemente supe de un PaaS "de bolsillo" similar a Heroku con un nombre bastante obvio: Dokku. Me atrajo mucho la posibilidad de agregar fácilmente un certificado a la aplicación y un vhost de manera nativa, así que decidí trasladar mis imágenes de Docker a Dokku. Sin embargo, me decepcionó que en Dokku no existieran comandos similares a los de Heroku.
dokku container:push
dokku container:release
// Sería muy conveniente, pero aún no hay :(Existe un comando que permite desplegar imágenes, pero la imagen debe estar ya en el host en ese momento. En otras palabras, para desplegar una imagen local recién creada, primero debe ser copiada al host.
tags:create # Agregar etiqueta a la última imagen de aplicación en funcionamiento
tags:deploy # Desplegar imagen de aplicación etiquetada
tags:destroy # Eliminar etiqueta de imagen de aplicaciónConozco Ansible y hasta he creado pipelines simples para entregar backend con él, así que la elección fue fácil. Claro que podría haberme esforzado y escrito un plugin para dokku, pero no, no ahora.
Playbook
Este playbook archiva cierta imagen local, la copia al host, la restaura y la despliega en dokku. Lo he colocado en un repositorio de Gitlab. Aún hay muchas oportunidades para mejorar.
push-image.dokku.yml
---
- name: "DESPLEGAR APP '{{ appname }}' A DOKKU"
hosts: dokku_hosts
remote_user: root
gather_facts: false
vars:
tarname: "{{ appname }}__{{ image }}.tar"
upload_dir: "\/usr\/local\/src"
upload_path: "{{ upload_dir }}\/{{ tarname }}"
apptag: "{{ upload_tag | default('latest') }}"
dokku_image: "dokku\/{{ appname }}:{{ apptag }}"
tasks:
- name: "Archivar '{{ image }}' para subir"
register: env
delegate_to: localhost
shell:
cmd: docker image save -o ".\/{{ tarname }}" {{ image }}
- name: "Subir imagen '{{ image }}' a dokku en '{{ inventory_hostname }}'"
register: upload
copy:
src: ".\/{{ tarname }}"
dest: "{{ upload_path }}"
- name: "Registro - Resultado de la subida"
debug:
var: upload.dest
- name: "Restaurar imagen de docker subida"
register: restore
shell:
cmd: docker image load -i "{{ upload_path }}"
- name: "Registro - Restaurar imagen"
debug:
var: restore.stdout_lines
- name: "Reetiquetar imagen a '{{ dokku_image }}'"
shell:
cmd: docker tag "{{ image }}" "{{ dokku_image }}"
- name: "Crear etiqueta dokku para '{{ dokku_image }}'"
shell:
cmd: dokku tags:create "{{ appname }}" "{{ apptag }}"
- name: "Liberar '{{ appname }}'"
register: release
shell:
cmd: dokku tags:deploy "{{ appname }}" "{{ apptag }}"
- name: "Registro - Liberar"
debug:
var: release.stdout_lines
Se supone que ansible ya está instalado en la máquina local y dokku en el host.
Usar así
ansible-playbook push-image.dokku.yml -i some_inventory -e "appname=DOKKU_APP_NAME image=DOCKER_IMAGE"some_inventory
[dokku_hosts]
tu.dominio.ejemploFuente: habr.com
