Answers: <p>You did everything right, it is the correct InSpec test and use with Docker!</p>
  
  <p>You encountered a bug in InSpec that is related to InSpec's netstat output parsing combination with Alpine's netstat output. </p>
  
  <p>See InSpec's output for <code>postgres</code> container instead of <code>postgres:alpine</code>:</p>
  
  <pre><code>$ inspec exec docker_test.rb -t docker://1c8162517c22                                                               1d15h master[a5ff79d3]
  
  Profile: tests from docker_test.rb (tests from docker_test.rb)
  Version: (not specified)
  Target:  docker://1c8162517c229ff8c87ab3e8c909f46b4370d7c63a65c0f973a5c10fdebda800
  
    Port 5432
       ✔  should be listening
  
  Test Summary: 1 successful, 0 failures, 0 skipped
  </code></pre>
  
  <p>In your case, the problem is that Apline's netstat reports a different output then other Linux eg. Ubuntu, CentOS:</p>
  
  <pre><code># netstat -tulpen
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
  tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      999        108791     -                   
  tcp6       0      0 :::5432                 :::*                    LISTEN      999        108792     -  
  </code></pre>
  
  <p>On Alpine, the inode output is missing:</p>
  
  <pre><code>netstat -tulpen
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
  tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
  tcp        0      0 :::5432                 :::*                    LISTEN      -
  </code></pre>
  
  <p>That is why InSpec is not able to parse the netstat output. It is clearly a bug in InSpec. As a mitigation, I recommend to install the <code>iproute2</code> package for alpine containers via <code>apk add iproute2</code>. InSpec prefers <code>ss</code> over <code>netstat</code>. Please report this bug to <a href="https://github.com/chef/inspec/issues/new" rel="nofollow noreferrer">InSpec team</a>.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-28T12:02:07.760Z
Answers: You're right. Using a different OS for the container base and adding iproute2 to the Alpine container both solved the problem. I've [opened a bug](https://github.com/chef/inspec/issues/2890) on the issue.
Answers: CodeGnome
Answers: CC BY-SA 3.0
Answers: 2018-03-28T11:34:53.980Z
Answers: 2018-03-28T11:34:53.980Z
Answers: Christoph Hartmann
Body: <h1>Background</h1>
  
  <p>I'm trying to test a <a href="https://hub.docker.com/_/postgres/" rel="nofollow noreferrer">PostgreSQL container</a> with <a href="https://www.inspec.io/" rel="nofollow noreferrer">InSpec</a> 2.1.10, but I cannot get a simple port check to return true, even though Docker, netstat, and psql all report that the port is properly mapped. While it's possible this is a bug in InSpec, it seems more likely that the problem exists between the keyboard and the chair. What have I missed?</p>
  
  <h1>Repeatable Tests</h1>
  
  <h2>My Spec</h2>
  
  <pre><code># port_test.rb
  describe port(5432) do
    it { should be_listening }
  end
  </code></pre>
  
  <h2>My Testing Commands</h2>
  
  <pre><code>container=$(docker run -d -P --rm postgres:alpine)
  inspec exec port_test.rb -t docker://$container
  </code></pre>
  
  <h2>My Output</h2>
  
  <blockquote>
  <pre><code>Profile: tests from test.rb (tests from test.rb)
  Version: (not specified)
  Target:  docker://8caceaa7e2eefa4a2bf50a58ea1ddf9c927c08d3397e3d9ad5b60d3519971380
  
    Port 5432
       ×  should be listening
       expected `Port 5432.listening?` to return true, got false
  
  Test Summary: 0 successful, 1 failure, 0 skipped
  </code></pre>
  </blockquote>
  
  <h2>But It Should Work!</h2>
  
  <p>Everything but InSpec reports that things are working as expected.</p>
  
  <pre><code>$ docker port $container
  5432/tcp -&gt; 0.0.0.0:32770
  
  # from inside container using netstat
  $ docker exec $container netstat -lntp
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
  tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
  tcp        0      0 :::5432                 :::*                    LISTEN      -
  
  # on macOS Docker host; flags are the macOS equivalent to `-lntp`
  $ netstat -anv | fgrep $(docker port $container | cut -d: -f2)
  tcp6       0      0  ::1.32770              *.*                    LISTEN      131072 131072    709      0
  tcp4       0      0  *.32770                *.*                    LISTEN      131072 131072    709      0
  
  # connecting to database in container from host
  $ psql -V \
         -h localhost \
         -p $(docker port $container | cut -d: -f2)
  psql (PostgreSQL) 10.3
  </code></pre>
  
Tags: <docker><ports><inspec><postgresql><alpine>
Title: Why won't InSpec admit that port 5432 is listening inside a PostgreSQL container?
UserDisplayName: CodeGnome
ThreadText: # Why won't InSpec admit that port 5432 is listening inside a PostgreSQL container?
  
  (Asked by: username_0 on 2018-03-27)
  
  # Background
  
  I'm trying to test a [PostgreSQL container](https://hub.docker.com/_/postgres/) with [InSpec](https://www.inspec.io/) 2.1.10, but I cannot get a simple port check to return true, even though Docker, netstat, and psql all report that the port is properly mapped. While it's possible this is a bug in InSpec, it seems more likely that the problem exists between the keyboard and the chair. What have I missed?
  
  # Repeatable Tests
  
  ## My Spec
  
  ```
  # port_test.rb
  describe port(5432) do
    it { should be_listening }
  end
  
  ```
  
  ## My Testing Commands
  
  ```
  container=$(docker run -d -P --rm postgres:alpine)
  inspec exec port_test.rb -t docker://$container
  
  ```
  
  ## My Output
  
  > ```
  > Profile: tests from test.rb (tests from test.rb)
  > Version: (not specified)
  > Target:  docker://8caceaa7e2eefa4a2bf50a58ea1ddf9c927c08d3397e3d9ad5b60d3519971380
  >
  >   Port 5432
  >      ×  should be listening
  >      expected `Port 5432.listening?` to return true, got false
  >
  > Test Summary: 0 successful, 1 failure, 0 skipped
  >
  > ```
  
  ## But It Should Work!
  
  Everything but InSpec reports that things are working as expected.
  
  ```
  $ docker port $container
  5432/tcp -> 0.0.0.0:32770
  
  # from inside container using netstat
  $ docker exec $container netstat -lntp
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
  tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
  tcp        0      0 :::5432                 :::*                    LISTEN      -
  
  # on macOS Docker host; flags are the macOS equivalent to `-lntp`
  $ netstat -anv | fgrep $(docker port $container | cut -d: -f2)
  tcp6       0      0  ::1.32770              *.*                    LISTEN      131072 131072    709      0
  tcp4       0      0  *.32770                *.*                    LISTEN      131072 131072    709      0
  
  # connecting to database in container from host
  $ psql -V \
         -h localhost \
         -p $(docker port $container | cut -d: -f2)
  psql (PostgreSQL) 10.3
  
  ```
  
  **Tags:** docker, ports, inspec, postgresql, alpine
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2018-03-28. Score: 3 | Accepted answer
  
  You did everything right, it is the correct InSpec test and use with Docker!
  
  You encountered a bug in InSpec that is related to InSpec's netstat output parsing combination with Alpine's netstat output.
  
  See InSpec's output for `postgres` container instead of `postgres:alpine`:
  
  ```
  $ inspec exec docker_test.rb -t docker://1c8162517c22                                                               1d15h master[a5ff79d3]
  
  Profile: tests from docker_test.rb (tests from docker_test.rb)
  Version: (not specified)
  Target:  docker://1c8162517c229ff8c87ab3e8c909f46b4370d7c63a65c0f973a5c10fdebda800
  
    Port 5432
       ✔  should be listening
  
  Test Summary: 1 successful, 0 failures, 0 skipped
  
  ```
  
  In your case, the problem is that Apline's netstat reports a different output then other Linux eg. Ubuntu, CentOS:
  
  ```
  # netstat -tulpen
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
  tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      999        108791     -                   
  tcp6       0      0 :::5432                 :::*                    LISTEN      999        108792     -  
  
  ```
  
  On Alpine, the inode output is missing:
  
  ```
  netstat -tulpen
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
  tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
  tcp        0      0 :::5432                 :::*                    LISTEN      -
  
  ```
  
  That is why InSpec is not able to parse the netstat output. It is clearly a bug in InSpec. As a mitigation, I recommend to install the `iproute2` package for alpine containers via `apk add iproute2`. InSpec prefers `ss` over `netstat`. Please report this bug to [InSpec team](https://github.com/chef/inspec/issues/new).
  
  > **Comments:**
  > **username_0**: You're right. Using a different OS for the container base and adding iproute2 to the Alpine container both solved the problem. I've [opened a bug](https://github.com/chef/inspec/issues/2890) on the issue.  
  
  ---
  
  