diff --git a/libpod/container_commit.go b/libpod/container_commit.go
index c1dd42942f..87e5d511c1 100644
--- a/libpod/container_commit.go
+++ b/libpod/container_commit.go
@@ -99,6 +99,11 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
 	for _, p := range c.config.PortMappings {
 		importBuilder.SetPort(fmt.Sprintf("%d/%s", p.ContainerPort, p.Protocol))
 	}
+	for port, protocols := range c.config.ExposedPorts {
+		for _, protocol := range protocols {
+			importBuilder.SetPort(fmt.Sprintf("%d/%s", port, protocol))
+		}
+	}
 	// Labels
 	for k, v := range c.Labels() {
 		importBuilder.SetLabel(k, v)
diff --git a/libpod/container_config.go b/libpod/container_config.go
index e15030c15d..b80b23c25c 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -229,6 +229,12 @@ type ContainerNetworkConfig struct {
 	// namespace
 	// These are not used unless CreateNetNS is true
 	PortMappings []ocicni.PortMapping `json:"portMappings,omitempty"`
+	// ExposedPorts are the ports which are exposed but not forwarded
+	// into the container.
+	// The map key is the port and the string slice contains the protocols,
+	// e.g. tcp and udp
+	// These are only set when exposed ports are given but not published.
+	ExposedPorts map[uint16][]string `json:"exposedPorts,omitempty"`
 	// UseImageResolvConf indicates that resolv.conf should not be
 	// bind-mounted inside the container.
 	// Conflicts with DNSServer, DNSSearch, DNSOption.
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 8c662c4889..97318a2e8a 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -624,7 +624,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
 	// Port bindings.
 	// Only populate if we're using CNI to configure the network.
 	if c.config.CreateNetNS {
-		hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings)
+		hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts)
 	} else {
 		hostConfig.PortBindings = make(map[string][]define.InspectHostPort)
 	}
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 2ed2bb01b5..dbe2274d35 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -1015,7 +1015,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
 	}
 
 	settings := new(define.InspectNetworkSettings)
-	settings.Ports = makeInspectPortBindings(c.config.PortMappings)
+	settings.Ports = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts)
 
 	networks, isDefault, err := c.networks()
 	if err != nil {
diff --git a/libpod/options.go b/libpod/options.go
index 59aec66c69..0bcd1e3a66 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1041,7 +1041,7 @@ func WithDependencyCtrs(ctrs []*Container) CtrCreateOption {
 // namespace with a minimal configuration.
 // An optional array of port mappings can be provided.
 // Conflicts with WithNetNSFrom().
-func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption {
+func WithNetNS(portMappings []ocicni.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption {
 	return func(ctr *Container) error {
 		if ctr.valid {
 			return define.ErrCtrFinalized
@@ -1051,6 +1051,7 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo
 		ctr.config.NetMode = namespaces.NetworkMode(netmode)
 		ctr.config.CreateNetNS = true
 		ctr.config.PortMappings = portMappings
+		ctr.config.ExposedPorts = exposedPorts
 
 		ctr.config.Networks = networks
 
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index 716eb2e5b0..53fb9538f3 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -616,7 +616,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
 			infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...)
 		}
 		infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions
-		infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings)
+		infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings, nil)
 	}
 
 	inspectData := define.InspectPodData{
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index 49213032ed..9236fb1f5f 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -112,7 +112,8 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
 					options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions))
 				}
 			}
-			options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks))
+			// FIXME allow pods to have exposed ports
+			options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, nil, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks))
 		}
 
 		// For each option in InfraContainerConfig - if set, pass into
diff --git a/libpod/util.go b/libpod/util.go
index 3b32fb2640..ed5c4e6c62 100644
--- a/libpod/util.go
+++ b/libpod/util.go
@@ -295,8 +295,8 @@ func writeHijackHeader(r *http.Request, conn io.Writer) {
 }
 
 // Convert OCICNI port bindings into Inspect-formatted port bindings.
-func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define.InspectHostPort {
-	portBindings := make(map[string][]define.InspectHostPort)
+func makeInspectPortBindings(bindings []ocicni.PortMapping, expose map[uint16][]string) map[string][]define.InspectHostPort {
+	portBindings := make(map[string][]define.InspectHostPort, len(bindings))
 	for _, port := range bindings {
 		key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
 		hostPorts := portBindings[key]
@@ -309,6 +309,15 @@ func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define.
 		})
 		portBindings[key] = hostPorts
 	}
+	// add exposed ports without host port information to match docker
+	for port, protocols := range expose {
+		for _, protocol := range protocols {
+			key := fmt.Sprintf("%d/%s", port, protocol)
+			if _, ok := portBindings[key]; !ok {
+				portBindings[key] = nil
+			}
+		}
+	}
 	return portBindings
 }
 
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index 1d7373093a..80790dcc18 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -242,7 +242,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
 		}
 		toReturn = append(toReturn, libpod.WithNetNSFrom(netCtr))
 	case specgen.Slirp:
-		portMappings, err := createPortMappings(ctx, s, imageData)
+		portMappings, expose, err := createPortMappings(ctx, s, imageData)
 		if err != nil {
 			return nil, err
 		}
@@ -250,15 +250,15 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
 		if s.NetNS.Value != "" {
 			val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value)
 		}
-		toReturn = append(toReturn, libpod.WithNetNS(portMappings, postConfigureNetNS, val, nil))
+		toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil))
 	case specgen.Private:
 		fallthrough
 	case specgen.Bridge:
-		portMappings, err := createPortMappings(ctx, s, imageData)
+		portMappings, expose, err := createPortMappings(ctx, s, imageData)
 		if err != nil {
 			return nil, err
 		}
-		toReturn = append(toReturn, libpod.WithNetNS(portMappings, postConfigureNetNS, "bridge", s.CNINetworks))
+		toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", s.CNINetworks))
 	}
 
 	if s.UseImageHosts {
diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go
index bd64080b1c..a300f8014a 100644
--- a/pkg/specgen/generate/ports.go
+++ b/pkg/specgen/generate/ports.go
@@ -254,17 +254,15 @@ func ParsePortMapping(portMappings []types.PortMapping) ([]ocicni.PortMapping, m
 }
 
 // Make final port mappings for the container
-func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]ocicni.PortMapping, error) {
+func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]ocicni.PortMapping, map[uint16][]string, error) {
 	finalMappings, containerPortValidate, hostPortValidate, err := ParsePortMapping(s.PortMappings)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 
-	// If not publishing exposed ports, or if we are publishing and there is
-	// nothing to publish - then just return the port mappings we've made so
-	// far.
-	if !s.PublishExposedPorts || (len(s.Expose) == 0 && imageData == nil) {
-		return finalMappings, nil
+	// No exposed ports so return the port mappings we've made so far.
+	if len(s.Expose) == 0 && imageData == nil {
+		return finalMappings, nil, nil
 	}
 
 	logrus.Debugf("Adding exposed ports")
@@ -273,7 +271,7 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData
 	if imageData != nil {
 		expose, err = GenExposedPorts(imageData.Config.ExposedPorts)
 		if err != nil {
-			return nil, err
+			return nil, nil, err
 		}
 	}
 
@@ -289,11 +287,11 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData
 		// Validate protocol first
 		protocols, err := checkProtocol(proto, false)
 		if err != nil {
-			return nil, errors.Wrapf(err, "error validating protocols for exposed port %d", port)
+			return nil, nil, errors.Wrapf(err, "error validating protocols for exposed port %d", port)
 		}
 
 		if port == 0 {
-			return nil, errors.Errorf("cannot expose 0 as it is not a valid port number")
+			return nil, nil, errors.Errorf("cannot expose 0 as it is not a valid port number")
 		}
 
 		// Check to see if the port is already present in existing
@@ -317,6 +315,11 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData
 		}
 	}
 
+	// If not publishing exposed ports return mappings and exposed ports.
+	if !s.PublishExposedPorts {
+		return finalMappings, toExpose, nil
+	}
+
 	// We now have a final list of ports that we want exposed.
 	// Let's find empty, unallocated host ports for them.
 	for port, protocols := range toExpose {
@@ -332,7 +335,7 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData
 				// unfortunate for the UDP case.
 				candidate, err := utils.GetRandomPort()
 				if err != nil {
-					return nil, err
+					return nil, nil, err
 				}
 
 				// Check if the host port is already bound
@@ -363,12 +366,12 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData
 			}
 			if tries == 0 && hostPort == 0 {
 				// We failed to find an open port.
-				return nil, errors.Errorf("failed to find an open port to expose container port %d on the host", port)
+				return nil, nil, errors.Errorf("failed to find an open port to expose container port %d on the host", port)
 			}
 		}
 	}
 
-	return finalMappings, nil
+	return finalMappings, nil, nil
 }
 
 // Check a string to ensure it is a comma-separated set of valid protocols
diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go
index 0a368b10fd..fbd4068f85 100644
--- a/test/e2e/commit_test.go
+++ b/test/e2e/commit_test.go
@@ -329,4 +329,40 @@ var _ = Describe("Podman commit", func() {
 		session.WaitWithDefaultTimeout()
 		Expect(session.OutputToString()).To(Not(ContainSubstring(secretsString)))
 	})
+
+	It("podman commit adds exposed ports", func() {
+		name := "testcon"
+		s := podmanTest.Podman([]string{"run", "--name", name, "-p", "8080:80", ALPINE, "true"})
+		s.WaitWithDefaultTimeout()
+		Expect(s).Should(Exit(0))
+
+		newImageName := "newimage"
+		c := podmanTest.Podman([]string{"commit", name, newImageName})
+		c.WaitWithDefaultTimeout()
+		Expect(c).Should(Exit(0))
+
+		inspect := podmanTest.Podman([]string{"inspect", newImageName})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect).Should(Exit(0))
+		images := inspect.InspectImageJSON()
+		Expect(images).To(HaveLen(1))
+		Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp"))
+
+		name = "testcon2"
+		s = podmanTest.Podman([]string{"run", "--name", name, "-d", nginx})
+		s.WaitWithDefaultTimeout()
+		Expect(s).Should(Exit(0))
+
+		newImageName = "newimage2"
+		c = podmanTest.Podman([]string{"commit", name, newImageName})
+		c.WaitWithDefaultTimeout()
+		Expect(c).Should(Exit(0))
+
+		inspect = podmanTest.Podman([]string{"inspect", newImageName})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect).Should(Exit(0))
+		images = inspect.InspectImageJSON()
+		Expect(images).To(HaveLen(1))
+		Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp"))
+	})
 })
diff --git a/test/e2e/container_inspect_test.go b/test/e2e/container_inspect_test.go
index 9a95a275ac..7d05b09fbe 100644
--- a/test/e2e/container_inspect_test.go
+++ b/test/e2e/container_inspect_test.go
@@ -3,6 +3,7 @@ package integration
 import (
 	"os"
 
+	"github.com/containers/podman/v3/libpod/define"
 	"github.com/containers/podman/v3/pkg/annotations"
 	. "github.com/containers/podman/v3/test/utils"
 	. "github.com/onsi/ginkgo"
@@ -43,4 +44,28 @@ var _ = Describe("Podman container inspect", func() {
 		Expect(data[0].Config.Annotations[annotations.ContainerManager]).
 			To(Equal(annotations.ContainerManagerLibpod))
 	})
+
+	It("podman inspect shows exposed ports", func() {
+		name := "testcon"
+		session := podmanTest.Podman([]string{"run", "-d", "--stop-timeout", "0", "--expose", "8080/udp", "--name", name, ALPINE, "sleep", "inf"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+		data := podmanTest.InspectContainer(name)
+
+		Expect(data).To(HaveLen(1))
+		Expect(data[0].NetworkSettings.Ports).
+			To(Equal(map[string][]define.InspectHostPort{"8080/udp": nil}))
+	})
+
+	It("podman inspect shows exposed ports on image", func() {
+		name := "testcon"
+		session := podmanTest.Podman([]string{"run", "-d", "--expose", "8080", "--name", name, nginx})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+
+		data := podmanTest.InspectContainer(name)
+		Expect(data).To(HaveLen(1))
+		Expect(data[0].NetworkSettings.Ports).
+			To(Equal(map[string][]define.InspectHostPort{"80/tcp": nil, "8080/tcp": nil}))
+	})
 })