diff --git a/language-docker.cabal b/language-docker.cabal
--- a/language-docker.cabal
+++ b/language-docker.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: e958774001a0ee7648ae873f3676eeb96096d835bfc0ce02bf292d23c4f1b716
+-- hash: 309a0c933f6e5edbdfbe096391f0b79e6a6f9218347d912f390d58a9c7c7c475
 
 name:           language-docker
-version:        10.3.0
+version:        10.4.0
 synopsis:       Dockerfile parser, pretty-printer and embedded DSL
 description:    All functions for parsing and pretty-printing Dockerfiles are exported through @Language.Docker@. For more fine-grained operations look for specific modules that implement a certain functionality.
                 See the <https://github.com/hadolint/language-docker GitHub project> for the source-code and examples.
diff --git a/src/Language/Docker/Parser/Prelude.hs b/src/Language/Docker/Parser/Prelude.hs
--- a/src/Language/Docker/Parser/Prelude.hs
+++ b/src/Language/Docker/Parser/Prelude.hs
@@ -35,6 +35,7 @@
     char,
     L.charLiteral,
     string,
+    string',
     void,
     when,
     Text,
@@ -173,11 +174,35 @@
 
 heredocContent :: Text -> Parser Text
 heredocContent marker = do
-  foo <- observing $ string $ marker <> "\n"
-  doc <- case foo of
-    Left _ -> manyTill anySingle (string $ "\n" <> marker <> "\n")
+  emptyHeredoc <- observing delimiter
+  doc <- case emptyHeredoc of
+    Left _ -> manyTill anySingle termination
     Right _ -> pure ""
   return $ T.strip $ T.pack doc
+  where
+    termination :: Parser Text
+    termination = try terEOL <|> terEOF
+
+    terEOL :: Parser Text
+    terEOL = string $ "\n" <> marker <> "\n"
+
+    terEOF :: Parser Text
+    terEOF = do
+      t <- string $ "\n" <> marker
+      hidden eof
+      pure t
+
+    delimiter :: Parser Text
+    delimiter = try delEOL <|> delEOF
+
+    delEOL :: Parser Text
+    delEOL = string $ marker <> "\n"
+
+    delEOF :: Parser Text
+    delEOF = do
+      t <- string marker
+      hidden eof
+      pure t
 
 heredoc :: Parser Text
 heredoc = do
diff --git a/src/Language/Docker/Parser/Run.hs b/src/Language/Docker/Parser/Run.hs
--- a/src/Language/Docker/Parser/Run.hs
+++ b/src/Language/Docker/Parser/Run.hs
@@ -202,15 +202,13 @@
         [ mountArgTarget,
           mountArgSource,
           mountArgFromImage,
-          mountArgReadOnly,
-          mountArgReadWrite
+          mountArgReadOnly
         ]
       Cache ->
         [ mountArgTarget,
           mountArgSource,
           mountArgFromImage,
           mountArgReadOnly,
-          mountArgReadWrite,
           mountArgId,
           mountArgSharing,
           mountArgMode,
@@ -234,6 +232,9 @@
 key :: Text -> Parser a -> Parser a
 key name p = string (name <> "=") *> p
 
+tryKeyValue' :: Text -> Text -> Parser Text
+tryKeyValue' k v = try $ string' (k <> "=") *> string' v
+
 cacheSharing :: Parser CacheSharing
 cacheSharing =
   choice [Private <$ string "private", Shared <$ string "shared", Locked <$ string "locked"]
@@ -251,10 +252,42 @@
 mountArgMode = MountArgMode <$> key "mode" stringArg
 
 mountArgReadOnly :: Parser RunMountArg
-mountArgReadOnly = MountArgReadOnly <$> (choice ["ro", "readonly"] $> True)
+mountArgReadOnly =
+  MountArgReadOnly
+    <$> choice
+          [ choiceRoExplicit,
+            choiceRwExplicit,
+            choiceRo,  -- these two must come last and be separate
+            choiceRw
+          ]
+  where
+    choiceRoExplicit =
+      choice
+        [ tryKeyValue' "ro" "true",
+          tryKeyValue' "rw" "false",
+          tryKeyValue' "readonly" "true",
+          tryKeyValue' "readwrite" "false"
+        ] $> True
 
-mountArgReadWrite :: Parser RunMountArg
-mountArgReadWrite = MountArgReadOnly <$> (choice ["rw", "readwrite"] $> False)
+    choiceRwExplicit =
+      choice
+        [ tryKeyValue' "rw" "true",
+          tryKeyValue' "ro" "false",
+          tryKeyValue' "readwrite" "true",
+          tryKeyValue' "readonly" "false"
+        ] $> False
+
+    choiceRo =
+      choice
+        [ string' "ro",
+          string' "readonly"
+        ] $> True
+
+    choiceRw =
+      choice
+        [ string' "rw",
+          string' "readwrite"
+        ] $> False
 
 mountArgRequired :: Parser RunMountArg
 mountArgRequired = MountArgRequired <$> choice
diff --git a/test/Language/Docker/ParseRunSpec.hs b/test/Language/Docker/ParseRunSpec.hs
--- a/test/Language/Docker/ParseRunSpec.hs
+++ b/test/Language/Docker/ParseRunSpec.hs
@@ -330,37 +330,159 @@
             [ Run $ RunArgs (ArgumentsText "echo foo") flags
             ]
 
+  describe "RUN with --mount flag and different ways to write ro/rw" $ do
+    let flagsRo = def { mount = Set.singleton $
+                                BindMount
+                                  ( def
+                                      { bTarget = "/foo",
+                                        bSource = Just "/bar",
+                                        bReadOnly = Just True
+                                      }
+                                  )
+                    }
+        flagsRw = def { mount = Set.singleton $
+                                BindMount
+                                  ( def
+                                      { bTarget = "/foo",
+                                        bSource = Just "/bar",
+                                        bReadOnly = Just False
+                                      }
+                                  )
+                    }
+     in do
+      it "--mount=type=bind,ro" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,ro echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,RO" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,RO echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,readonly" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readonly echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,Readonly" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,Readonly echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,ro=true" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,ro=true echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,RO=TRUE" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,RO=TRUE echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,readonly=true" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readonly=true echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,Readonly=True" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,Readonly=True echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,ro=True" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,ro=True echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,readonly=True" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readonly=True echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,rw=false" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,rw=false echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,readwrite=false" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readwrite=false echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,rw=False" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,rw=False echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+      it "--mount=type=bind,readwrite=False" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readwrite=False echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRo ]
+
+      it "--mount=type=bind,rw" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,rw echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,readwrite" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readwrite echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,rw=true" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,rw=true echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,readwrite=true" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readwrite=true echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,rw=True" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,rw=True echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,readwrite=True" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readwrite=True echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,ro=false" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,ro=false echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,readonly=false" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readonly=false echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,ro=False" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,ro=False echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+      it "--mount=type=bind,readonly=False" $
+        let file = Text.unlines
+              [ "RUN --mount=type=bind,target=/foo,source=/bar,readonly=False echo foo" ]
+         in assertAst file [ Run $ RunArgs (ArgumentsText "echo foo") flagsRw ]
+
   describe "parse RUN in heredocs format" $ do
     it "foo heredoc" $
-      let file = Text.unlines [ "RUN <<EOF", "foo", "EOF"]
+      let file = Text.unlines [ "RUN <<EOF", "foo", "EOF" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
+    it "foo heredoc without newline at end" $
+      let file = "RUN <<EOF\nfoo\nEOF"
+          flags = def { security = Nothing }
+       in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "foo heredoc marker" $
-      let file = Text.unlines [ "RUN <<FOO", "foo", "FOO"]
+      let file = Text.unlines [ "RUN <<FOO", "foo", "FOO" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "foo heredoc quoted marker" $
-      let file = Text.unlines [ "RUN <<\"FOO\"", "foo", "FOO"]
+      let file = Text.unlines [ "RUN <<\"FOO\"", "foo", "FOO" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "foo heredoc single quoted marker" $
-      let file = Text.unlines [ "RUN <<\'FOO\'", "foo", "FOO"]
+      let file = Text.unlines [ "RUN <<\'FOO\'", "foo", "FOO" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "foo heredoc +dash" $
-      let file = Text.unlines [ "RUN <<-FOO", "foo", "FOO"]
+      let file = Text.unlines [ "RUN <<-FOO", "foo", "FOO" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "foo heredoc quoted +dash" $
-      let file = Text.unlines [ "RUN <<-\"FOO\"", "foo", "FOO"]
+      let file = Text.unlines [ "RUN <<-\"FOO\"", "foo", "FOO" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "foo heredoc single quoted +dash" $
-      let file = Text.unlines [ "RUN <<-\'FOO\'", "foo", "FOO"]
+      let file = Text.unlines [ "RUN <<-\'FOO\'", "foo", "FOO" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo") flags ]
     it "multiline foo heredoc" $
-      let file = Text.unlines [ "RUN <<EOF", "foo", "bar", "", "dodo", "EOF"]
+      let file = Text.unlines [ "RUN <<EOF", "foo", "bar", "", "dodo", "EOF" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "foo\nbar\n\ndodo") flags ]
     it "heredoc with shebang/commend" $
@@ -368,9 +490,13 @@
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "#/usr/bin/env python\n\n#print foo\nprint(\"foo\")") flags ]
     it "empty heredoc" $
-      let file = Text.unlines [ "RUN <<EOF", "EOF"]
+      let file = Text.unlines [ "RUN <<EOF", "EOF" ]
           flags = def { security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "") flags ]
+    it "empty heredoc not followed by newline" $
+      let file = "RUN <<EOF\nEOF"
+          flags = def { security = Nothing }
+       in assertAst file [ Run $ RunArgs (ArgumentsText "") flags ]
     it "evil heredoc" $
       let file = Text.unlines [ "RUN <<EOF foo", "bar EOF", "EOF"]
           flags = def { security = Nothing }
@@ -400,5 +526,9 @@
             ]
     it "heredoc correct termination" $
       let file = Text.unlines [ "RUN <<EOF", "echo $EOF", "EOF" ]
+          flags = def {security = Nothing }
+       in assertAst file [ Run $ RunArgs (ArgumentsText "echo $EOF") flags ]
+    it "heredoc correct termination without newline" $
+      let file = "RUN <<EOF\necho $EOF\nEOF"
           flags = def {security = Nothing }
        in assertAst file [ Run $ RunArgs (ArgumentsText "echo $EOF") flags ]
