<p>I am creating a POD file with multiple containers. One is a webserver container and another is my PostgreSQL container. Here is my pod file named <code>simple.yaml</code></p>
<pre><code>apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: &quot;2022-01-01T16:28:15Z&quot;
  labels:
    app: eltask
  name: eltask
spec:
  containers:
  - name: el_web
    command:
      - ./entrypoints/entrypoint.sh
    env:
    - name: PATH
      value: /usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: container
      value: podman
    - name: RUBY_MAJOR
      value: &quot;2.7&quot;
    - name: BUNDLE_SILENCE_ROOT_WARNING
      value: &quot;1&quot;
    - name: BUNDLE_APP_CONFIG
      value: /usr/local/bundle
    - name: LANG
      value: C.UTF-8
    - name: RUBY_VERSION
      value: 2.7.2
    - name: RUBY_DOWNLOAD_SHA256
      value: 1b95ab193cc8f5b5e59d2686cb3d5dcf1ddf2a86cb6950e0b4bdaae5040ec0d6
    - name: GEM_HOME
      value: /usr/local/bundle
    image: docker.io/hmtanbir/elearniotask
    ports:
    - containerPort: 3000
      hostPort: 3000
      protocol: TCP
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities:
        drop:
        - CAP_MKNOD
        - CAP_NET_RAW
        - CAP_AUDIT_WRITE
      privileged: false
      readOnlyRootFilesystem: false
      seLinuxOptions: {}
    tty: true
    workingDir: /app
  - name: el_db
    image: docker.io/library/postgres:10-alpine3.13
    env:
      - name: PATH
        value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - name: TERM
        value: xterm
      - name: container
        value: podman
      - name: PG_MAJOR
        value: &quot;10&quot;
      - name: PG_VERSION
        value: &quot;10.17&quot;
      - name: PGDATA
        value: /var/lib/postgresql/data
      - name: LANG
        value: en_US.utf8
      - name: PG_SHA256
        value: 5af28071606c9cd82212c19ba584657a9d240e1c4c2da28fc1f3998a2754b26c
      - name: POSTGRES_PASSWORD
        value: password
    args:
      - postgres
    command:
      - docker-entrypoint.sh
    ports:
      - containerPort: 5432
        hostPort: 9876
        protocol: TCP
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities:
        drop:
          - CAP_MKNOD
          - CAP_NET_RAW
          - CAP_AUDIT_WRITE
        privileged: false
        readOnlyRootFilesystem: false
        seLinuxOptions: {}
    tty: true
    workingDir: /
  dnsConfig: {}
  restartPolicy: Never
status: {}
</code></pre>
<p>I am running a webserver container in <code>3000:3000</code> port and the DB container port is <code>9876:5432</code>.
But when I run cmd using PODMAN <code>podman play kube simple.yaml</code>, DB container is running <code>127.0.0.0:9876</code> but webserver can't connect with the DB server.</p>
<p><a href="https://i.stack.imgur.com/q4U9y.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/q4U9y.png" alt="enter image description here" /></a></p>
<p>My webserver DB config:</p>
<pre><code>ELTASK_DATABASE_HOST=localhost
ELTASK_DATABASE_PORT=9876
ELTASK_DATABASE_USERNAME=postgres
ELTASK_DATABASE_PASSWORD=password
</code></pre>
<p>If I run the webserver without Podman, the server can connect with the DB using <code>9876</code> port.</p>
<p>So, Why the webserver can't connect with the database container while it is running through Podman?</p>

<p>Posting this as a community wiki, feel free to edit and expand.</p>
<hr />
<p>There are two parts of the answer:</p>
<ol>
<li><strong>Which port to use and why</strong></li>
</ol>
<p>For <code>postgresql</code> as a backend service, you can omit the <code>hostPort</code> since <code>podman</code> as a frontend service will access <code>postresql</code> using <code>Cluster-IP</code> and therefore it will be available on port <code>5432</code>. Completely deleting this part is not recommended approach, when you have a lot of pods with containers inside, it's much better to be able to quickly see which container is exposed on which port.</p>
<p>Also in general <code>hostPort</code> shouldn't be used unless it's the only way, consider using <code>NodePort</code>:</p>
<blockquote>
<p>Don't specify a hostPort for a Pod unless it is absolutely necessary.
When you bind a Pod to a hostPort, it limits the number of places the
Pod can be scheduled, because each &lt;hostIP, hostPort, protocol&gt;
combination must be unique.</p>
</blockquote>
<p>See <a href="https://kubernetes.io/docs/concepts/configuration/overview/#services" rel="nofollow noreferrer">best practices</a>.</p>
<ol start="2">
<li><strong>Frontend and backend deployment</strong></li>
</ol>
<p>It's always advisable and a best practice to separate backend and frontend into different <code>deployments</code>, so they can be managed fully separately like upgrades, replicas and etc. As well as <code>services</code> - you don't need to expose backend service outside the cluster.</p>
<p>See <a href="https://kubernetes.io/docs/tasks/access-application-cluster/connecting-frontend-backend/" rel="nofollow noreferrer">an frontend and backend example</a>.</p>
<p>Also @David Maze correctly said that database should use a <code>statefulSet</code> - see <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/" rel="nofollow noreferrer">more details about Statefulset</a>.</p>
