<p>I'm learning Kurbernetes and Docker at the moment, KinD in particular. To start with, I just want to run <code>docker run --rm --name &lt;container's name&gt; -p 8080:80 -d &lt;image name&gt;</code> to create a container from the image.</p>
<p>I know that ports are used in the TCP/IP protocol (or Internet Protocol) to address a specific program (software). Port 80 is a default port to run  web servers.</p>
<p>Now, my question is why 8080 or why 5000? How to determine which port should be an OUTSIDE port in this case? Is it just random or are there any rule/restrictions?</p>

yavnelf
<p>For the <code>docker run -p</code> option (and Compose <code>ports:</code>), for the first port number you can pick any port that isn't already in use on your host system.  As you've noted, port 80 is the standard HTTP port, and what gets used in <code>http://hostname/</code> URLs without an explicit port number.  Various frameworks use port 3000 or 5000 or 8000 or 8080 as their default but none of them is &quot;standard&quot; or &quot;special&quot; in any way.</p>
<p>The second port number <em>must</em> be the port number the server process is listening on.  The server process must be listening on the special 0.0.0.0 &quot;all address&quot; address, if that's a configurable option; if it's listening on 127.0.0.1 (as many developer-oriented servers do by default) it will not be reachable from outside its container.  This number often is included in an <code>EXPOSE</code> line in the Dockerfile, but that directive has no other effect.  (There is no reason to include a <code>docker run --expose</code> option or Compose <code>expose:</code> block and it's always safe to delete it.)</p>
<p>There is no particular requirement that the two ports match.  If you want to use host port 8888 because it's available, and your application is a Node application using the default Express port 3000, it will work to</p>
<pre class="lang-sh prettyprint-override"><code>docker run -p 8888:3000 ...
</code></pre>
<p>If you really don't care you can use <code>docker run -p</code> with only the container port number, but this is unusual.  <a href="https://docs.docker.com/engine/reference/commandline/port/" rel="nofollow noreferrer"><code>docker port</code></a> will tell you what port Docker chose.</p>
<pre class="lang-sh prettyprint-override"><code>docker run -p 3000 --name my-container ...
docker port my-container 3000
</code></pre>
<p>You mention Kubernetes in here as well.  In Kubernetes, all communications between Pods go through a <a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">Service</a>, in effect an in-cluster load balancer.  I'd recommend always making the Service use the &quot;normal&quot; port for whatever protocol you're using, port 80 for unencrypted HTTP.  Each Service has its own in-cluster IP address so there's no risk of conflict between Services or Pods.  If you're using a NodePort-type Service to make it accessible from outside the cluster, you are usually constrained to using ports 30000 through 32767.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata: { name: the-service-name }
spec:
  selector: { ... }
  ports:
    - port: 80           # for HTTP, regardless of how the service is implemented
      targetPort: http   # matching the Pod's `containerPorts:` name
      # nodePort: 30080  # if the Service has type: NodePort, optional
</code></pre>
<p>Now calls from another Pod through this Service can use <code>http://the-service-name/</code> as the URL with the default port.</p>
