Deploy Docker Image to Dokku with Ansible

Deploy Docker Image to Dokku with Ansible

Prologue

I recently found out about a "pocket" PaaS similar to Heroku with a rather obvious name - Dokku. I was very attracted by the ability to simply add a certificate to the application and vhost out of the box, so I decided to transfer my docker images to Dokku. True, I was disappointed that Dokku does not have commands like Heroku

dokku container:push
dokku container:release
// ΠžΡ‡Π΅Π½ΡŒ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ Π΅Ρ‰Π΅ Π½Π΅Ρ‚ :(

There is a team tags which allows you to deploy images, but the image itself must already be on the host at this moment. In other words, in order to roll out a newly made local image, it must first be copied to the host.

tags:create <app> <tag>                        # Add tag to latest running app image
tags:deploy <app> <tag>                        # Deploy tagged app image
tags:destroy <app> <tag>                       # Remove app image tag

I am familiar with Ansible and have even built simple backend delivery pipelines with it, so the choice was easy. Of course, one could get tired and write a plug-in for dokku, but no, not now.

Playbook

This playbook archives some local image, copies it to the host, restores it and deploys it to dokku. Posted in Gitlab turnip. There is still plenty of room for improvement.

push-image.dokku.yml

push-image.dokku.yml

---
  - name: "DEPLOY APP '{{ appname }}' TO 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: "Archive '{{ image }}' to upload"
        register: env
        delegate_to: localhost
        shell: 
          cmd: docker image save -o "./{{ tarname }}" {{ image }}

      - name: "Upload image '{{ image }}' to dokku at '{{ inventory_hostname }}'"
        register: upload
        copy:
          src: "./{{ tarname }}"
          dest: "{{ upload_path }}"

      - name: "Log - Upload result"
        debug:
          var: upload.dest

      - name: "Restore uploaded docker image"
        register: restore
        shell:
          cmd: docker image load -i "{{ upload_path }}"

      - name: "Log - Restore image"
        debug:
          var: restore.stdout_lines

      - name: "Retag image to '{{ dokku_image }}'"
        shell: 
          cmd: docker tag "{{ image }}" "{{ dokku_image }}"

      - name: "Create dokku tag for '{{ dokku_image }}'"
        shell: 
          cmd: dokku tags:create "{{ appname }}" "{{ apptag }}"

      - name: "Release '{{ appname }}'"
        register: release
        shell: 
          cmd: dokku tags:deploy "{{ appname }}" "{{ apptag }}"  

      - name: "Log - Release"
        debug:
          var: release.stdout_lines  

it is assumed that ansible on the local machine and dokku on the host are already installed

Use like this

ansible-playbook push-image.dokku.yml -i some_inventory -e "appname=DOKKU_APP_NAME image=DOCKER_IMAGE"

some_inventory

[dokku_hosts]
your.domain.example

Source: habr.com

Buy reliable hosting for sites with DDoS protection, VPS VDS servers πŸ”₯ Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster