title: How can I access my docker asp.net core application?
body: <p>I have a ASP.NET Core 2.2./PostgreSQL composed docker solution that seems to be working fine amongst the containers.</p>
  
  <p>I have followed a hybrid of the official <a href="https://docs.docker.com/compose/aspnet-mssql-compose/" rel="nofollow noreferrer">Quickstart: Compose and ASP.NET Core with SQL Server</a> and <a href="https://docs.docker.com/compose/django/" rel="nofollow noreferrer">Quickstart: Compose and Django</a> with a solution for adding node.js into the mix.</p>
  
  <p><del>In the interest of brevity, I've omitted the actual <code>Dockerfile</code> in this post.</del> The <code>Dockerfile</code> should be quite standard:</p>
  
  <pre><code>FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
  COPY . /app
  WORKDIR /app
  
  RUN curl -sL https://deb.nodesource.com/setup_10.x |  bash -
  RUN apt-get install -y nodejs
  
  RUN ["dotnet", "restore"]
  RUN ["dotnet", "build"]
  EXPOSE 80/tcp
  EXPOSE 5001/tcp
  RUN chmod +x ./entrypoint.sh
  CMD /bin/bash ./entrypoint.sh
  </code></pre>
  
  <p>where <code>entrypoint.sh</code> actually fires up the web server and migrates the EF migrations like this:</p>
  
  <pre><code>#!/bin/bash
  
  set -e
  run_cmd="dotnet run"
  
  until dotnet ef database update; do
  &gt;&amp;2 echo "PostgreSQL Server is starting up"
  sleep 1
  done
  
  &gt;&amp;2 echo "PostgreSQL Server is up - executing command"
  exec $run_cmd
  </code></pre>
  
  <p>and finally my <code>docker-compose.yml</code> looks like this:</p>
  
  <pre><code>version: '3.4'
  
  networks:
    aspnetpostgresql:
      driver: bridge
  
  services:
    db:
      image: postgres
      restart: always
      networks: 
        - aspnetpostgresql
    web:
      build: .
      ports:
          - "5001:5001"
          - "5000:5000"
      depends_on:
          - db
      networks: 
        - aspnetpostgresql
  </code></pre>
  
  <p>The ASP.NET Core image is based on <code>mcr.microsoft.com/dotnet/core/sdk:2.2</code>. Suffice it to say, I have two containers, <code>my_web_app_db_1</code> (PostgreSQL) and <code>my_web_app_web_1</code> (ASP.NET Core 2.2. React Web App). I have logged into the <code>my_web_app_web_1</code>-container and established that the web server is running at <a href="https://localhost:5001" rel="nofollow noreferrer">https://localhost:5001</a>:</p>
  
  <pre><code>root@0123456780:/app# wget -p --no-check-certificate https://localhost:5001
  --2019-04-17 19:46:29--  https://localhost:5001/
  Resolving localhost (localhost)... 127.0.0.1, ::1
  Connecting to localhost (localhost)|127.0.0.1|:5001... connected.
  WARNING: The certificate of 'localhost' is not trusted.
  WARNING: The certificate of 'localhost' hasn't got a known issuer.
  HTTP request sent, awaiting response... 200 OK
  Length: 1673 (1.6K) [text/html]
  Saving to: 'localhost:5001/index.html'
  
  localhost:5001/index.html                100%[==================================================================================&gt;]   1.63K  --.-KB/s    in 0s      
  
  # .... yada yada yada
  
  FINISHED --2019-04-17 19:46:30--
  Total wall clock time: 0.4s
  Downloaded: 4 files, 3.2M in 0.1s (23.3 MB/s)
  </code></pre>
  
  <p>In other words, everything seems fine on the web server side. </p>
  
  <pre><code>ABCDE-MacBook-Pro:MyWebApp MY_USER$ docker-compose ps
        Name                    Command               State                           Ports                         
  ------------------------------------------------------------------------------------------------------------------
  my_web_app_db_1    docker-entrypoint.sh postgres    Up      5432/tcp                                              
  my_web_app_web_1   /bin/sh -c /bin/bash ./ent ...   Up      0.0.0.0:5000-&gt;5000/tcp, 0.0.0.0:5001-&gt;5001/tcp, 80/tcp
  </code></pre>
  
  <p><em>Please note:</em> the <code>5001</code> port is also exposed to the host, as can be seen by scrolling right.</p>
  
  <p>However, all attempts at connecting with <code>https://localhost:5001</code> are unsuccessful. E.g. running the same <code>wget</code> operation from the host gives</p>
  
  <pre><code>ABCDE-MacBook-Pro:MyWebApp MY_USER$ wget -p --no-check-certificate https://localhost:5001
  --2019-04-17 23:00:05--  https://localhost:5001/
  Resolving localhost (localhost)... ::1, 127.0.0.1
  Connecting to localhost (localhost)|::1|:5001... connected.
  Unable to establish SSL connection.
  </code></pre>
  
  <p>Doing a <code>curl</code>-operation is equally unsuccessful:</p>
  
  <pre><code>ABCDE-MacBook-Pro:MyWebApp MY_USER$ curl -k https://localhost:5001curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:5001 
  </code></pre>
  
  <p>Finally, I'm aware that the <a href="https://hub.docker.com/r/microsoft/aspnetcore/" rel="nofollow noreferrer"><code>aspnetcore</code>-image</a> is inherently bound to port 80:</p>
  
  <blockquote>
    <p>This image sets the ASPNETCORE_URLS environment variable to <a href="http://+:80" rel="nofollow noreferrer">http://+:80</a> which means that if you have not explicity set a URL in your application, via app.UseUrl in your Program.cs for example, then your application will be listening on port 80 inside the container.</p>
  </blockquote>
  
  <p>However, this does not seem to be the case for me, as I'm able to <code>wget</code> to port <code>5001</code>. Either this does not apply to the SDK image, or the documentation is not up-to-date.</p>
  
  <p>The question is, what do I have to do to access <code>https://localhost:5001</code> from the host?</p>
  
  <p><strong>Update:</strong></p>
  
  <p>My goal with this set up was to get the database to be created and seeded in accordance with the db entity framework migrations. The resulting 
  docker setup was intended to be used by early testers, so large-scale production considerations did not apply.</p>
  
  <p>I'm pretty agnostic when it comes to the exact db initiation mechanisms, but as long as the development is far from finished, my requirement 
  has been that the schema is easily maintainable and the migrations are easily deployed. Thus, it would be handy if I can run the </p>
  
  <p><code>dotnet ef database update</code> </p>
  
  <p>command, as this is the exact same thing I'd do in my development environment. After further investigating my initial attempt at dockerizing my project, I decided to take a step back and run the actual migrations from the ASP.NET Core project itself. This is perhaps not the cleanest of solutions, but it solves my actual case: namely having a docker setup replicating my development environment. For those interested, my <code>Dockerfile</code> now looks like this:</p>
  
  <pre><code>FROM microsoft/dotnet:2.2-sdk AS build-env
  WORKDIR /app
  
  RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
  RUN apt-get install -y nodejs
  
  # Copy csproj and restore as distinct layers
  COPY *.csproj ./
  RUN dotnet restore
  
  # Copy everything else and build
  COPY . ./
  RUN dotnet publish -c Release -o out
  
  # Build runtime image
  FROM microsoft/dotnet:2.2-aspnetcore-runtime AS runtime
  WORKDIR /app
  COPY --from=build-env /app/out . 
  
  EXPOSE 80/tcp
  
  ENTRYPOINT ["dotnet", "MyWebApp.dll"]
  </code></pre>
  
  <p>And the <code>DbContext</code> looks like this:</p>
  
  <pre><code>public class MyDbContext : DbContext
  {
      public MyDbContext(DbContextOptions&lt;MyDbContext&gt; options) : base(options)
      {
          Database.Migrate();
      }
  
      // ...
  
  }
  </code></pre>
  
  <p>The <code>docker-compose.yml</code> is pretty much the same as before (although I've removed the network config). Now I can access <code>http://localhost:8000</code> from the host computer.</p>