diff --git a/compose/config/types.py b/compose/config/types.py
index c410343b8..548f2c1cd 100644
--- a/compose/config/types.py
+++ b/compose/config/types.py
@@ -133,6 +133,48 @@ def normalize_path_for_engine(path):
     return path.replace('\\', '/')
 
 
+class MountSpec(object):
+    options_map = {
+        'volume': {
+            'nocopy': 'no_copy'
+        },
+        'bind': {
+            'propagation': 'propagation'
+        }
+    }
+    _fields = ['type', 'source', 'target', 'read_only', 'consistency']
+
+    def __init__(self, type, source=None, target=None, read_only=None, consistency=None, **kwargs):
+        self.type = type
+        self.source = source
+        self.target = target
+        self.read_only = read_only
+        self.consistency = consistency
+        self.options = None
+        if self.type in kwargs:
+            self.options = kwargs[self.type]
+
+    def as_volume_spec(self):
+        mode = 'ro' if self.read_only else 'rw'
+        return VolumeSpec(external=self.source, internal=self.target, mode=mode)
+
+    def legacy_repr(self):
+        return self.as_volume_spec().repr()
+
+    def repr(self):
+        res = {}
+        for field in self._fields:
+            if getattr(self, field, None):
+                res[field] = getattr(self, field)
+        if self.options:
+            res[self.type] = self.options
+        return res
+
+    @property
+    def is_named_volume(self):
+        return self.type == 'volume' and self.source
+
+
 class VolumeSpec(namedtuple('_VolumeSpec', 'external internal mode')):
 
     @classmethod
diff --git a/compose/service.py b/compose/service.py
index b696fd664..07db3ac5f 100644
--- a/compose/service.py
+++ b/compose/service.py
@@ -14,6 +14,7 @@ from docker.errors import APIError
 from docker.errors import ImageNotFound
 from docker.errors import NotFound
 from docker.types import LogConfig
+from docker.types import Mount
 from docker.utils import version_gte
 from docker.utils import version_lt
 from docker.utils.ports import build_port_bindings
@@ -27,6 +28,7 @@ from .config import DOCKER_CONFIG_KEYS
 from .config import merge_environment
 from .config import merge_labels
 from .config.errors import DependencyError
+from .config.types import MountSpec
 from .config.types import ServicePort
 from .config.types import VolumeSpec
 from .const import DEFAULT_TIMEOUT
@@ -795,9 +797,13 @@ class Service(object):
 
         secret_volumes = self.get_secret_volumes()
         if secret_volumes:
-            override_options['binds'].extend(v.repr() for v in secret_volumes)
-            container_options['volumes'].update(
-                (v.internal, {}) for v in secret_volumes)
+            if version_lt(self.client.api_version, '1.30'):
+                override_options['binds'].extend(v.legacy_repr() for v in secret_volumes)
+                container_options['volumes'].update(
+                    (v.target, {}) for v in secret_volumes
+                )
+            else:
+                override_options['mounts'] = [build_mount(v) for v in secret_volumes]
 
         container_options['image'] = self.image_name
 
@@ -891,6 +897,7 @@ class Service(object):
             device_read_iops=blkio_config.get('device_read_iops'),
             device_write_bps=blkio_config.get('device_write_bps'),
             device_write_iops=blkio_config.get('device_write_iops'),
+            mounts=options.get('mounts'),
         )
 
     def get_secret_volumes(self):
@@ -901,7 +908,7 @@ class Service(object):
             elif not os.path.isabs(target):
                 target = '{}/{}'.format(const.SECRETS_PATH, target)
 
-            return VolumeSpec(secret['file'], target, 'ro')
+            return MountSpec('bind', secret['file'], target, read_only=True)
 
         return [build_spec(secret) for secret in self.secrets]
 
@@ -1346,6 +1353,18 @@ def build_volume_from(volume_from_spec):
         return "{}:{}".format(volume_from_spec.source.id, volume_from_spec.mode)
 
 
+def build_mount(mount_spec):
+    kwargs = {}
+    if mount_spec.options:
+        for option, sdk_name in mount_spec.options_map[mount_spec.type].items():
+            if option in mount_spec.options:
+                kwargs[sdk_name] = mount_spec.options[option]
+
+    return Mount(
+        type=mount_spec.type, target=mount_spec.target, source=mount_spec.source,
+        read_only=mount_spec.read_only, consistency=mount_spec.consistency, **kwargs
+    )
+
 # Labels
 
 
diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py
index 8e8f60203..87c86a731 100644
--- a/tests/unit/service_test.py
+++ b/tests/unit/service_test.py
@@ -1133,8 +1133,8 @@ class ServiceSecretTest(unittest.TestCase):
         )
         volumes = service.get_secret_volumes()
 
-        assert volumes[0].external == secret1['file']
-        assert volumes[0].internal == '{}/{}'.format(SECRETS_PATH, secret1['secret'].target)
+        assert volumes[0].source == secret1['file']
+        assert volumes[0].target == '{}/{}'.format(SECRETS_PATH, secret1['secret'].target)
 
     def test_get_secret_volumes_abspath(self):
         secret1 = {
@@ -1149,8 +1149,8 @@ class ServiceSecretTest(unittest.TestCase):
         )
         volumes = service.get_secret_volumes()
 
-        assert volumes[0].external == secret1['file']
-        assert volumes[0].internal == secret1['secret'].target
+        assert volumes[0].source == secret1['file']
+        assert volumes[0].target == secret1['secret'].target
 
     def test_get_secret_volumes_no_target(self):
         secret1 = {
@@ -1165,5 +1165,5 @@ class ServiceSecretTest(unittest.TestCase):
         )
         volumes = service.get_secret_volumes()
 
-        assert volumes[0].external == secret1['file']
-        assert volumes[0].internal == '{}/{}'.format(SECRETS_PATH, secret1['secret'].source)
+        assert volumes[0].source == secret1['file']
+        assert volumes[0].target == '{}/{}'.format(SECRETS_PATH, secret1['secret'].source)