Add support for docker stack deploy
diff --git a/README.rst b/README.rst
index 40c293f..2718b40 100644
--- a/README.rst
+++ b/README.rst
@@ -95,6 +95,43 @@
Using Docker Compose
~~~~~~~~~~~~~~~~~~~~
+There are two states that provides this functionality:
+
+- docker.client.stack
+- docker.client.compose
+
+Stack is new and works with Docker Swarm Mode. Compose is legacy and works
+only if node isn't member of Swarm.
+Metadata for both states are similar and differs only in implementation.
+
+Stack
+^^^^^
+
+.. code-block:: yaml
+
+ docker:
+ client:
+ stack:
+ django_web:
+ enabled: true
+ update: true
+ environment:
+ SOMEVAR: somevalue
+ service:
+ db:
+ image: postgres
+ web:
+ image: djangoapp
+ volumes:
+ - /srv/volumes/django:/srv/django
+ ports:
+ - 8000:8000
+ depends_on:
+ - db
+
+Compose
+^^^^^^^
+
There are three options how to install docker-compose:
- distribution package (default)
@@ -132,6 +169,9 @@
depends_on:
- db
+Service
+-------
+
To deploy service in Swarm mode, you can use ``docker.client.service``:
.. code-block:: yaml
diff --git a/docker/client/compose.sls b/docker/client/compose.sls
index ccebf4d..3a35649 100644
--- a/docker/client/compose.sls
+++ b/docker/client/compose.sls
@@ -1,5 +1,10 @@
{% from "docker/map.jinja" import client with context %}
+{#-
+ This state is used for old-way docker-compose that doesn't work with Docker
+ Swarm mode. For Docker Swarm, use docker.client.stack
+#}
+
include:
- docker.client
{%- if client.compose.source.engine == 'docker' %}
diff --git a/docker/client.sls b/docker/client/init.sls
similarity index 84%
rename from docker/client.sls
rename to docker/client/init.sls
index b7a87eb..2286f9d 100644
--- a/docker/client.sls
+++ b/docker/client/init.sls
@@ -9,6 +9,9 @@
{%- if client.compose is defined %}
- docker.client.compose
{%- endif %}
+ {%- if client.stack is defined %}
+ - docker.client.stack
+ {%- endif %}
{%- if client.service is defined %}
- docker.client.service
{%- endif %}
diff --git a/docker/client/stack.sls b/docker/client/stack.sls
new file mode 100644
index 0000000..896ed4b
--- /dev/null
+++ b/docker/client/stack.sls
@@ -0,0 +1,89 @@
+{% from "docker/map.jinja" import client with context %}
+
+include:
+ - docker.client
+
+{%- for app, compose in client.stack.iteritems() %}
+ {%- if compose.service is defined %}
+
+docker_{{ app }}_dir:
+ file.directory:
+ - name: {{ client.compose.base }}/{{ app }}
+ - makedirs: true
+
+docker_{{ app }}_compose:
+ file.managed:
+ - name: {{ client.compose.base }}/{{ app }}/docker-compose.yml
+ - source: salt://docker/files/docker-compose.yml
+ - template: jinja
+ - defaults:
+ compose: {{ compose }}
+ service: {{ compose.service }}
+ network: {{ compose.network|default({}) }}
+ - require:
+ - file: docker_{{ app }}_dir
+
+ {%- if compose.environment is defined %}
+
+docker_{{ app }}_env:
+ file.managed:
+ - name: {{ client.compose.base }}/{{ app }}/.env
+ - source: salt://docker/files/docker-env
+ - template: jinja
+ - user: {{ compose.user|default("root") }}
+ - mode: 640
+ - defaults:
+ env: {{ compose.environment }}
+ - require:
+ - file: docker_{{ app }}_dir
+
+ {%- else %}
+
+docker_{{ app }}_env:
+ file.absent:
+ - name: {{ client.compose.base }}/{{ app }}/.env
+
+ {%- endif %}
+
+ {%- if compose.enabled|default(True) %}
+
+docker_stack_{{ app }}:
+ cmd.run:
+ - name: docker stack deploy --compose-file docker-compose.yml {{ app }}
+ - cwd: {{ client.compose.base }}/{{ app }}
+ - user: {{ compose.user|default("root") }}
+ - unless: "docker stack ls | grep '{{ app }}'"
+ - require:
+ - file: docker_{{ app }}_env
+ - file: docker_{{ app }}_compose
+
+docker_stack_{{ app }}_update:
+ cmd.wait:
+ - name: docker stack deploy --compose-file docker-compose.yml {{ app }}
+ - cwd: {{ client.compose.base }}/{{ app }}
+ - user: {{ compose.user|default("root") }}
+ - require:
+ - cmd: docker_stack_{{ app }}
+ - watch:
+ - file: docker_{{ app }}_env
+ - file: docker_{{ app }}_compose
+
+ {%- else %}
+
+docker_remove_{{ app }}:
+ cmd.run:
+ - name: docker stack rm {{ app }}
+ - user: {{ compose.user|default("root") }}
+ - onlyif: "docker stack ls | grep '{{ app }}'"
+
+ {%- endif %}
+
+ {%- else %}
+
+ {#-
+ No stack.service is defined so we can add support for deploying using
+ bundle file, etc.
+ #}
+
+ {%- endif %}
+{%- endfor %}
diff --git a/docker/files/docker-compose.yml b/docker/files/docker-compose.yml
index 81de7ed..6e03b18 100644
--- a/docker/files/docker-compose.yml
+++ b/docker/files/docker-compose.yml
@@ -1,4 +1,4 @@
-version: '2'
+version: '3'
services:
{%- for name, srv in service.iteritems() %}
{%- set env_file_set = False %}
@@ -12,6 +12,16 @@
{%- endif %}
{%- endfor %}
+{%- if network|default({}) %}
+networks:
+{%- for name, net in network.iteritems() %}
+ {{ name }}:
+ {%- for key, value in net.iteritems() %}
+ {{ key }}: {{ value }}
+ {%- endfor %}
+{%- endfor %}
+{%- endif %}
+
{#-
vim: syntax=jinja
-#}
diff --git a/tests/pillar/client_deploy.sls b/tests/pillar/client_deploy.sls
new file mode 100644
index 0000000..860531a
--- /dev/null
+++ b/tests/pillar/client_deploy.sls
@@ -0,0 +1,19 @@
+docker:
+ client:
+ enabled: true
+ stack:
+ django_web:
+ enabled: true
+ environment:
+ SOMEVAR: somevalue
+ service:
+ db:
+ image: postgres
+ web:
+ image: djangoapp
+ volumes:
+ - /srv/volumes/django:/srv/django
+ ports:
+ - 8000:8000
+ depends_on:
+ - db