Reputation: 53
I have a simple example webAPI in .NET core, running in a docker container. I'm running Nginx also in a docker container as a reverse proxy for https redirection. The webAPI is accessible on http, but when accessing the https url, the API is not responding.
I have tried many different configurations in the nginx.conf file. I've tried using localhost, 0.0.0.0, and 127.0.0.1. I've tried using several different ports such as 5000, 8000, and 80. I've tried using upstream and also specifying the url on the proxy_pass line directly.
docker-compose.yml:
version: '3.4'
networks:
blogapi-dev:
driver: bridge
services:
blogapi:
image: blogapi:latest
depends_on:
- "postgres_image"
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:80"
expose:
- "8000"
environment:
DB_CONNECTION_STRING: "host=postgres_image;port=5432;database=blogdb;username=bloguser;password=bloguser"
ASPNETCORE_ENVIRONMENT: development
#REMOTE_DEBUGGING: ${REMOTE_DEBUGGING}
networks:
- blogapi-dev
tty: true
stdin_open: true
postgres_image:
image: postgres:latest
ports:
- "5000:80"
restart: always
volumes:
- db_volume:/var/lib/postgresql/data
- ./BlogApi/dbscripts/seed.sql:/docker-entrypoint-initdb.d/seed.sql
environment:
POSTGRES_USER: "bloguser"
POSTGRES_PASSWORD: "bloguser"
POSTGRES_DB: blogdb
networks:
- blogapi-dev
nginx-proxy:
image: nginx:latest
container_name: nginx-proxy
ports:
- 80:80
- 443:443
networks:
- blogapi-dev
depends_on:
- "blogapi"
volumes:
- ./nginx-proxy/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-proxy/error.log:/etc/nginx/error_log.log
- ./nginx-proxy/cache/:/etc/nginx/cache
- /etc/letsencrypt/:/etc/letsencrypt/
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./:/etc/nginx/
networks:
blogapi-dev:
driver: bridge
volumes:
db_volume:
nginx.conf:
events {}
http {
upstream backend {
server 127.0.0.1:8000;
}
server {
server_name local.website.dev;
rewrite ^(.*) https://local.website.dev$1 permanent;
}
server {
listen 443 ssl;
ssl_certificate localhost.crt;
ssl_certificate_key localhost.key;
ssl_ciphers HIGH:!aNULL:!MD5;
server_name local.website.dev;
location / {
proxy_pass http://backend;
}
}
}
Startup.cs:
namespace BlogApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING");
services.AddDbContext<BlogContext>(options =>
options.UseNpgsql(
connectionString));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
When I go to http://127.0.0.1:8000/api/blog, the browser returns the json response from my api. This tells me that the app us up and running on port 8000, although it should not be accessable via http:
[{"id":1,"title":"Title 1","body":"Body 1","timeStamp":"1999-01-08T04:05:06"},{"id":2,"title":"Title 2","body":"Body 2","timeStamp":"2000-01-08T04:05:06"},{"id":3,"title":"Title 3","body":"Body 3","timeStamp":"2001-01-08T04:05:06"},{"id":4,"title":"Title 4","body":"Body 4","timeStamp":"2002-01-08T04:05:06"}]
When I go to 127.0.0.1, the browser properly redirects to https://local.website.dev/ but I get no response from the api, just the chrome local.website.dev refused to connect. ERR_CONNECTION_REFUSED. I get the same response when to go to https://local.website.dev/api/blog.
Also, this is the output from docker-compose up:
Starting blog_postgres_image_1 ... done
Starting blog_blogapi_1 ... done
Starting nginx-proxy ... done
Attaching to blog_postgres_image_1, blog_blogapi_1, nginx-proxy
blogapi_1 | Hosting environment: development
blogapi_1 | Content root path: /app
blogapi_1 | Now listening on: http://[::]:80
blogapi_1 | Application started. Press Ctrl+C to shut down.
postgres_image_1 | 2019-06-27 11:20:49.441 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_image_1 | 2019-06-27 11:20:49.441 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_image_1 | 2019-06-27 11:20:49.577 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_image_1 | 2019-06-27 11:20:49.826 UTC [25] LOG: database system was shut down at 2019-06-27 10:26:12 UTC
postgres_image_1 | 2019-06-27 11:20:49.893 UTC [1] LOG: database system is ready to accept connections
Upvotes: 1
Views: 3146
Reputation: 53
I got it working. There were a couple of issues. First, I was missing some boilerplate at the top of the nginx.conf file. Second, I needed to set the proxy_pass to the name of the docker container housing the service that I wanted to route to, in my case http://blogapi/, instead of localhost.
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
proxy_set_header Host $host;
proxy_pass_request_headers on;
gzip on;
gzip_proxied any;
map $sent_http_content_type $expires {
default off;
~image/ 1M;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
return 301 https://172.24.0.1$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate localhost.crt;
ssl_certificate_key localhost.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://blogapi/;
}
}
}
With the above configuration, I can access the webAPI at: https://172.24.0.1/api/blog/ If http://localhost/api/blog is entered, the browser will redirect to https://172.24.0.1/api/blog/ The IP address is the address of the blogapi-dev bridge network gateway as shown below.
docker inspect 20b
"Networks": {
"blog_blogapi-dev": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"20bd90d1a80a",
"blogapi"
],
"NetworkID": "1edd39000ac3545f9a738a5df33b4ea90e082a2be86752e7aa6cd9744b72d6f0",
"EndpointID": "9201d8a1131a4179c7e0198701db2835e3a15f4cbfdac2a4a4af18804573fea9",
"Gateway": "172.24.0.1",
"IPAddress": "172.24.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:18:00:03",
"DriverOpts": null
}
}
Upvotes: 1