diff --git a/language-docker.cabal b/language-docker.cabal
--- a/language-docker.cabal
+++ b/language-docker.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 2177b40144f01ae0a40effd326ed6357de50c47b559d1a0d307d298994c38b37
+-- hash: dd6c2b3624c04b2f48ffc3844fe2df02d25b1034408fc2221f6b572647e653bc
 
 name:           language-docker
-version:        4.0.1
+version:        5.0.0
 synopsis:       Dockerfile parser, pretty-printer and embedded DSL
 description:    All functions for parsing, printing and writting 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.
@@ -15,8 +15,7 @@
 author:         Lukas Martinelli,
                 Pedro Tacla Yamada,
                 José Lorenzo Rodríguez
-maintainer:     me@lukasmartinelli.ch,
-                lorenzo@seatgeek.com
+maintainer:     lorenzo@seatgeek.com
 copyright:      Lukas Martinelli, Copyright (c) 2016,
                 Pedro Tacla Yamada, Copyright (c) 2016,
                 José Lorenzo Rodríguez, Copyright (c) 2017
diff --git a/src/Language/Docker.hs b/src/Language/Docker.hs
--- a/src/Language/Docker.hs
+++ b/src/Language/Docker.hs
@@ -47,6 +47,8 @@
     , Language.Docker.EDSL.tcpPort
     , Language.Docker.EDSL.udpPort
     , Language.Docker.EDSL.variablePort
+    , Language.Docker.EDSL.portRange
+    , Language.Docker.EDSL.udpPortRange
     , Language.Docker.EDSL.volume
     , Language.Docker.EDSL.entrypoint
     , Language.Docker.EDSL.entrypointArgs
diff --git a/src/Language/Docker/EDSL.hs b/src/Language/Docker/EDSL.hs
--- a/src/Language/Docker/EDSL.hs
+++ b/src/Language/Docker/EDSL.hs
@@ -268,7 +268,10 @@
 variablePort varName = Syntax.PortStr ('$' : varName)
 
 portRange :: Integer -> Integer -> Syntax.Port
-portRange = Syntax.PortRange
+portRange a b = Syntax.PortRange a b Syntax.TCP
+
+udpPortRange :: Integer -> Integer -> Syntax.Port
+udpPortRange a b = Syntax.PortRange a b Syntax.UDP
 
 check :: Syntax.Arguments -> Syntax.Check
 check command =
diff --git a/src/Language/Docker/Parser.hs b/src/Language/Docker/Parser.hs
--- a/src/Language/Docker/Parser.hs
+++ b/src/Language/Docker/Parser.hs
@@ -267,7 +267,7 @@
 port :: Parser Port
 port =
     (try portVariable <?> "a variable") <|> -- There a many valid representations of ports
-    (try portRange <?> "a port range") <|>
+    (try portRange <?> "a port range optionally followed by the protocol (udp/tcp)") <|>
     (try portWithProtocol <?> "a port with its protocol (udp/tcp)") <|>
     (try portInt <?> "a valid port number")
 
@@ -279,8 +279,17 @@
     start <- natural
     void $ char '-'
     finish <- try natural
-    return $ PortRange start finish
+    proto <- try protocol <|> return TCP
+    return $ PortRange start finish proto
 
+protocol :: Parser Protocol
+protocol = do
+    void (char '/')
+    tcp <|> udp
+  where
+    tcp = caseInsensitiveString "tcp" >> return TCP
+    udp = caseInsensitiveString "udp" >> return UDP
+
 portInt :: Parser Port
 portInt = do
     portNumber <- natural
@@ -290,10 +299,7 @@
 portWithProtocol :: Parser Port
 portWithProtocol = do
     portNumber <- natural
-    void (char '/')
-    proto <-
-        (caseInsensitiveString "tcp" >> return TCP) <|> -- Either tcp or udp
-        (caseInsensitiveString "udp" >> return UDP)
+    proto <- protocol
     return $ Port portNumber proto
 
 portVariable :: Parser Port
@@ -336,8 +342,8 @@
 -- Parse arguments of a command in the exec form
 argumentsExec :: Parser Arguments
 argumentsExec = do
-  args <- brackets $ commaSep stringLiteral
-  return $ Arguments args
+    args <- brackets $ commaSep stringLiteral
+    return $ Arguments args
 
 -- Parse arguments of a command in the shell form
 argumentsShell :: Parser Arguments
diff --git a/src/Language/Docker/PrettyPrint.hs b/src/Language/Docker/PrettyPrint.hs
--- a/src/Language/Docker/PrettyPrint.hs
+++ b/src/Language/Docker/PrettyPrint.hs
@@ -77,7 +77,8 @@
 
 prettyPrintPort :: Port -> Doc
 prettyPrintPort (PortStr str) = text str
-prettyPrintPort (PortRange start stop) = integer start <> text "-" <> integer stop
+prettyPrintPort (PortRange start stop TCP) = integer start <> text "-" <> integer stop
+prettyPrintPort (PortRange start stop UDP) = integer start <> text "-" <> integer stop <> char '/' <> text "udp"
 prettyPrintPort (Port num TCP) = integer num <> char '/' <> text "tcp"
 prettyPrintPort (Port num UDP) = integer num <> char '/' <> text "udp"
 
diff --git a/src/Language/Docker/Syntax.hs b/src/Language/Docker/Syntax.hs
--- a/src/Language/Docker/Syntax.hs
+++ b/src/Language/Docker/Syntax.hs
@@ -42,6 +42,7 @@
     | PortStr String
     | PortRange Integer
                 Integer
+                Protocol
     deriving (Show, Eq, Ord)
 
 newtype Ports = Ports
diff --git a/test/Language/Docker/EDSLSpec.hs b/test/Language/Docker/EDSLSpec.hs
--- a/test/Language/Docker/EDSLSpec.hs
+++ b/test/Language/Docker/EDSLSpec.hs
@@ -39,10 +39,12 @@
             let r = prettyPrint $ toDockerfile (do
                         from "scratch"
                         expose $ ports [variablePort "PORT", tcpPort 80, udpPort 51]
-                        expose $ ports [portRange 90 100])
+                        expose $ ports [portRange 90 100]
+                        expose $ ports [udpPortRange 190 200])
             r `shouldBe` unlines [ "FROM scratch"
                                  , "EXPOSE $PORT 80/tcp 51/udp"
                                  , "EXPOSE 90-100"
+                                 , "EXPOSE 190-200/udp"
                                  ]
 
         it "onBuild let's us nest statements" $ do
diff --git a/test/Language/Docker/ParserSpec.hs b/test/Language/Docker/ParserSpec.hs
--- a/test/Language/Docker/ParserSpec.hs
+++ b/test/Language/Docker/ParserSpec.hs
@@ -268,7 +268,10 @@
                 parse expose "" content `shouldBe` Right (Expose (Ports [PortStr "$PORT", Port 8080 TCP, Port 8081 UDP]))
             it "should handle port ranges" $ do
                 let content = "EXPOSE 80 81 8080-8085"
-                parse expose "" content `shouldBe` Right (Expose (Ports [Port 80 TCP, Port 81 TCP, PortRange 8080 8085]))
+                parse expose "" content `shouldBe` Right (Expose (Ports [Port 80 TCP, Port 81 TCP, PortRange 8080 8085 TCP]))
+            it "should handle udp port ranges" $ do
+                let content = "EXPOSE 80 81 8080-8085/udp"
+                parse expose "" content `shouldBe` Right (Expose (Ports [Port 80 TCP, Port 81 TCP, PortRange 8080 8085 UDP]))
 
         describe "syntax" $ do
             it "should handle lowercase instructions (#7 - https://github.com/beijaflor-io/haskell-language-dockerfile/issues/7)" $ do
