diff --git a/compose/config/interpolation.py b/compose/config/interpolation.py
index 0f2630383..5a5f349db 100644
--- a/compose/config/interpolation.py
+++ b/compose/config/interpolation.py
@@ -137,6 +137,8 @@ class TemplateWithDefaults(Template):
 
             if named is not None:
                 val = mapping[named]
+                if isinstance(val, six.binary_type):
+                    val = val.decode('utf-8')
                 return '%s' % (val,)
             if mo.group('escaped') is not None:
                 return self.delimiter
diff --git a/compose/config/serialize.py b/compose/config/serialize.py
index 3ab43fc59..7fb9360a2 100644
--- a/compose/config/serialize.py
+++ b/compose/config/serialize.py
@@ -27,6 +27,9 @@ def serialize_string(dumper, data):
     """ Ensure boolean-like strings are quoted in the output and escape $ characters """
     representer = dumper.represent_str if six.PY3 else dumper.represent_unicode
 
+    if isinstance(data, six.binary_type):
+        data = data.decode('utf-8')
+
     data = data.replace('$', '$$')
 
     if data.lower() in ('y', 'n', 'yes', 'no', 'on', 'off', 'true', 'false'):
@@ -90,7 +93,8 @@ def serialize_config(config, image_digests=None):
         denormalize_config(config, image_digests),
         default_flow_style=False,
         indent=2,
-        width=80
+        width=80,
+        allow_unicode=True
     )
 
 
diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py
index 03626ad36..cfbd4cf33 100644
--- a/tests/unit/config/config_test.py
+++ b/tests/unit/config/config_test.py
@@ -4750,3 +4750,20 @@ class SerializeTest(unittest.TestCase):
         assert serialized_service['environment']['CURRENCY'] == '$$'
         assert serialized_service['command'] == 'echo $$FOO'
         assert serialized_service['entrypoint'][0] == '$$SHELL'
+
+    def test_serialize_unicode_values(self):
+        cfg = {
+            'version': '2.3',
+            'services': {
+                'web': {
+                    'image': 'busybox',
+                    'command': 'echo 十六夜 咲夜'
+                }
+            }
+        }
+
+        config_dict = config.load(build_config_details(cfg))
+
+        serialized_config = yaml.load(serialize_config(config_dict))
+        serialized_service = serialized_config['services']['web']
+        assert serialized_service['command'] == 'echo 十六夜 咲夜'
diff --git a/tests/unit/config/interpolation_test.py b/tests/unit/config/interpolation_test.py
index dfeba96d0..62f4ac774 100644
--- a/tests/unit/config/interpolation_test.py
+++ b/tests/unit/config/interpolation_test.py
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
 from __future__ import absolute_import
 from __future__ import unicode_literals
 
@@ -401,3 +403,14 @@ def test_interpolate_mixed_separators(defaults_interpolator):
 def test_unbraced_separators(defaults_interpolator):
     assert defaults_interpolator("ok $FOO:-bar") == "ok first:-bar"
     assert defaults_interpolator("ok $BAZ?error") == "ok ?error"
+
+
+def test_interpolate_unicode_values():
+    variable_mapping = {
+        'FOO': '十六夜 咲夜'.encode('utf-8'),
+        'BAR': '十六夜 咲夜'
+    }
+    interpol = Interpolator(TemplateWithDefaults, variable_mapping).interpolate
+
+    interpol("$FOO") == '十六夜 咲夜'
+    interpol("${BAR}") == '十六夜 咲夜'