diff --git a/README.md b/README.md new file mode 100644 index 0000000..6dfb2ab --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Description + +This is a deployment of [Dokku](https://github.com/dokku/dokku), a docker-powered PaaS that helps you build and manage the lifecycle of applications. + +# Configuration + +In order to configure apps use the `dokku_apps` variable: + +```yaml +dokku_apps: + - name: 'my-awesome-bot' + repo: 'https://github.com/status-im/my-awesome-bot' + env: + APP_ID: 12345 + LOG_LEVEL: debug + WEBHOOK_SECRET: 'my-github-webhook-secret' + PRIVATE_KEY: 'my-secret-private-key' +``` + +# Known Issues + +## Docker Container Renaming + +Because we redirect logs to `rsyslog` and then to files in `/var/log/docker` as well as Logstash, and the way Docker handles container renaming, when Dokku renames containers their logs still flow to the randomly generated name, rather then the propper app name. + +For this reason a hacky workaround has been added to the [`tasks/post_config.yml`](tasks/post_config.yml) file which modifies Dokku script files. + +For more details see: https://github.com/docker/for-linux/issues/582 + +## Docker User Namespaces + +Currently Dokku is unable to properly work with Docker user namespace settings. + +For that reason we are using a hacky workaround in [`tasks/dockremap.yml`](tasks/dockremap.yml) which simply changes the user in Docker `userns-remap` setting to `dokku` rather than `dockremap`. + +This allows us to use to the user namespaces without getting `chmod` errors on container start. + +For more details see: https://github.com/dokku/dokku/issues/3454 diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..adf2486 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,19 @@ +--- +dokku_sub_domain: 'status.im' +dokku_host_domain: 'dokku.status.im' + +dokku_repo_url: 'https://packagecloud.io/dokku/dokku/ubuntu/' +dokku_repo_gpg_url: 'https://packagecloud.io/dokku/dokku/gpgkey' +dokku_repo_gpg_id: '288B3315' + +dokku_repo_apt_entry: 'deb {{ dokku_repo_url }} {{ ansible_distribution_release }} main' + +dokku_cont_ssl_cert: /certs/origin.crt +dokku_cont_ssl_key: /certs/origin.key + +dokku_ssl_backend_port: 8080 + +dokku_debug_plugin_repo: 'https://github.com/josegonzalez/dokku-debug.git' + +# here is where you define apps and how they should be deployed +dokku_apps: [] diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..f11d403 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: reload nginx + service: name=nginx state=reloaded + +- name: Save iptables rules + shell: iptables-save > /etc/iptables/rules.v4 diff --git a/tasks/add_keys.yml b/tasks/add_keys.yml new file mode 100644 index 0000000..67e88c3 --- /dev/null +++ b/tasks/add_keys.yml @@ -0,0 +1,16 @@ +--- +- name: Dokku | Find authorized_keys files for users + find: + paths: /home + file_type: file + recurse: yes + patterns: authorized_keys + excludes: admin + register: user_keys + +# TODO make this more robust, the file can contain more than one kay +# WARNING: Disabled for now since it doesn't work +# ISSUE: https://github.com/dokku/dokku/issues/3417 +#- name: Dokku | Add keys for users to access Dokku +# command: 'dokku ssh-keys:add {{ item.pw_name }} {{ item.path | quote }}' +# with_items: '{{ user_keys.files }}' diff --git a/tasks/create_app.yml b/tasks/create_app.yml new file mode 100644 index 0000000..7d25928 --- /dev/null +++ b/tasks/create_app.yml @@ -0,0 +1,72 @@ +--- +- name: 'Dokku | {{ item.name }} | Check if app exists' + command: 'dokku apps:report {{ item.name }}' + ignore_errors: true + register: app + +- name: 'Dokku | {{ item.name }} | Create app' + command: 'dokku apps:create {{ item.name }}' + when: app.failed + +- name: 'Dokku | {{ item.name }} | Correct app domain' + command: 'dokku domains:clear {{ item.name }}' + +- name: 'Dokku | {{ item.name }} | Set SSL certs' + command: 'dokku certs:add {{ item.name }} {{ dokku_cont_ssl_cert }} {{ dokku_cont_ssl_key }}' + +- name: 'Dokku | {{ item.name }} | Format env variables for container' + set_fact: + env_variables: '{% for key in item.env.keys() %}{{ key }}="{{ item.env[key] }}" {% endfor %}' + +- name: 'Dokku | {{ item.name }} | Set app ENV variables' + command: 'dokku config:set {{ item.name }} {{ env_variables }}' + +- name: 'Dokku | {{ item.name }} | Add SSL backend port' + command: 'dokku proxy:ports-add {{ item.name }} http:{{ dokku_ssl_backend_port }}:5000' + +- name: 'Dokku | {{ item.name }} | Clone app repo' + git: + repo: '{{ item.repo }}' + dest: '/tmp/{{ item.name }}' + update: true + force: true + become_user: admin + +- name: 'Dokku | {{ item.name }} | Check for remote to repo' + command: 'git config remote.dokku.url' + args: + chdir: '/tmp/{{ item.name }}' + register: dokku_remote_check + become_user: admin + ignore_errors: true + +- name: 'Dokku | {{ item.name }} | Add remote to repo' + command: 'git remote add dokku dokku@localhost:{{ item.name }}' + args: + chdir: '/tmp/{{ item.name }}' + when: dokku_remote_check.rc > 0 + become_user: admin + +- name: 'Dokku | {{ item.name }} | Push repo' + command: 'git push dokku' + args: + chdir: '/tmp/{{ item.name }}' + become_user: admin + +- name: 'Dokku | {{ item.name }} | Create Consul service' + include_role: name=infra-role-consul-service + vars: + consul_config_name: 'dokku_{{ item.name }}' + consul_services: + - id: 'dokku:{{ item.name }}' + name: 'dokku' + tags: ['dokku', 'ssl-proxy-backend'] + port: '{{ dokku_ssl_backend_port }}' + address: '{{ ansible_local.wireguard.address }}' + meta: + proxy_fqdn: '{{ item.name }}.{{ dokku_sub_domain }}' + checks: + - id: 'dokku-health:{{ item.name }}' + name: 'Dokku Site Healthcheck' + type: 'http' + http: 'http://localhost:{{ dokku_ssl_backend_port }}/ping' diff --git a/tasks/firewall.yml b/tasks/firewall.yml new file mode 100644 index 0000000..7517d93 --- /dev/null +++ b/tasks/firewall.yml @@ -0,0 +1,9 @@ +--- +- name: Dokku | Enable HTTP & HTTPS + include_role: name=infra-role-open-ports + vars: + open_ports_default_comment: '{{ beacon_node_service_name }}' + open_ports_list: + dokku: + - port: [80,443] + disabled: '{{ not beacon_node_firewall_libp2p_open }}' diff --git a/tasks/install.yml b/tasks/install.yml new file mode 100644 index 0000000..2792465 --- /dev/null +++ b/tasks/install.yml @@ -0,0 +1,30 @@ +--- +- name: Dokku | Add repository signing key + apt_key: + id: '{{ dokku_repo_gpg_id }}' + url: '{{ dokku_repo_gpg_url }}' + state: present + +- name: Dokku | Add APT repository + become: yes + apt_repository: + repo: '{{ dokku_repo_apt_entry }}' + state: present + +- name: Dokku | Install package + apt: + name: dokku + state: present + update_cache: yes + +- name: Dokku | Install plugins + command: 'dokku plugin:install-dependencies --core' + +- name: Dokku | Check for debug plugin + command: 'sudo dokku plugin:list --help | grep debug' + register: dobug_plugin_check + ignore_errors: true + +- name: Dokku | Install debug plugin + command: 'dokku plugin:install {{ dokku_debug_plugin_repo }} debug' + when: dobug_plugin_check.failed diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..d543bd7 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- include_tasks: firewall.yml +- include_tasks: pre_config.yml +- include_tasks: install.yml +- include_tasks: add_keys.yml +- include_tasks: post_config.yml +- include_tasks: create_app.yml + with_items: '{{ dokku_apps }}' diff --git a/tasks/post_config.yml b/tasks/post_config.yml new file mode 100644 index 0000000..9f06369 --- /dev/null +++ b/tasks/post_config.yml @@ -0,0 +1,3 @@ +--- +- name: Dokku | Set Dokku default domain + command: 'dokku domains:set-global {{dokku_sub_domain}}' diff --git a/tasks/pre_config.yml b/tasks/pre_config.yml new file mode 100644 index 0000000..08602d4 --- /dev/null +++ b/tasks/pre_config.yml @@ -0,0 +1,18 @@ +--- +- name: Dokku | Stop installer process + service: + name: dokku-installer + state: stopped + ignore_errors: yes + +- name: Dokku | Configure without Web UI + debconf: + name: dokku + question: '{{ item.q }}' + value: '{{ item.v }}' + vtype: '{{ item.t }}' + with_items: + - { q: 'dokku/web_config', t: 'boolean', v: 'false' } + - { q: 'dokku/vhost_enable', t: 'boolean', v: 'true' } + - { q: 'dokku/hostname', t: 'string', v: '{{ dokku_host_domain }}' } + - { q: 'dokku/key_file', t: 'string', v: '/home/jakub/.ssh/authorized_keys' }