2

I'm having hangfire which is hosted inside the docker container. When i try to browse the hangfire dashboard inside the docker container Or locally it is showing me the result. But i forward the port outside and try to access it is showing me blank page for /hangfire dashboard. The application is developed using dot net core.

Dockerfile

   FROM microsoft/dotnet:1.1.1-runtime
USER  root
RUN mkdir -p /LART/WEBAPI
COPY WebApi/Release /LART/WEBAPI/
WORKDIR /LART/WEBAPI
EXPOSE 8082
ADD WebApi/Config/NLog.config /LART/WEBAPI
ENTRYPOINT ["dotnet", "LArt.WebApi.dll"]

Please find the docker-compose file

 lart.api:
   image: lartapi
   restart: always
   container_name: deploy_lartapi
   hostname: lartapi.local
   build:
      context: .
      dockerfile: /WebApi/Dockerfile
   volumes:
    - "logs:/LART/LOGS"
   ports:
    - "8082:8082"  
   networks: 
    lartnetwork:
     aliases: 
      - lartapi
   depends_on:
    - lart.mongo
    - lart.elastic
    - lart.rabbit

hangfire dashboard

  using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using LArt.Shared;
using Hangfire;
using Hangfire.Mongo;

namespace LArt.WebApi
{
    public class StartUp
    {

        public StartUp(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
               .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            //Dataaccess
            services.AddTransient<DataAccess.Interface.IAgentDataService, DataAccess.AgentDataService>();
            services.AddTransient<DataAccess.Interface.ILogDataService, DataAccess.LogDataService>();
            services.AddTransient<DataAccess.Interface.IReportDataService, DataAccess.ReportDataService>();

            //Business
            services.AddSingleton<Business.ServiceInterface.IAgentService, Business.Services.AgentService>();
            services.AddSingleton<Business.ServiceInterface.ILogService, Business.Services.LogService>();
            services.AddSingleton<Business.ServiceInterface.IReportService, Business.Services.ReportService>();
            string[] accessOrgin = new string[] { "http://localhost:8080", "http://lart.web" };
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder
                  //  .WithOrigins(accessOrgin)
                    .AllowAnyOrigin()
                    .WithMethods("GET", "POST")
                    .AllowAnyHeader()
                    .SetPreflightMaxAge(System.TimeSpan.FromDays(7))
                    .AllowCredentials());
            });


            services.AddHangfire(config =>
            {

                var migrationOptions = new MongoStorageOptions
                {
                    MigrationOptions = new MongoMigrationOptions
                    {
                        Strategy = MongoMigrationStrategy.Migrate,
                    }
                };
                config.UseMongoStorage("mongodb://lart.mongo:27017", "LART_HANGFIRE", migrationOptions);
            });


            // Add framework services.
            services.AddMvc();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            // loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            loggerFactory.AddNLog();
            loggerFactory.ConfigureNLog("NLog.config");

            //app.useSTatic
            app.UseCors("CorsPolicy");
            app.UseStaticFiles();
            app.UseHangfireDashboard("/hangfire");
            app.UseMvc();

        }

    }
}

Program.cs

   using Microsoft.AspNetCore.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace LArt.WebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
               .UseKestrel()
               .UseUrls("http://*:8082")
               .UseStartup<StartUp>()
               .Build();
            host.Run();
        }
    }
}

docker inspect of the container

 [
    {
        "Id": "c83b19fdedf2b03c1bb3e874ba5c9b4c488d250d74013b638fe8626053298853",
        "Created": "2017-09-29T18:52:09.745304871Z",
        "Path": "dotnet",
        "Args": [
            "LArt.WebApi.dll"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 992,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2017-09-29T18:52:10.443021987Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:b2d196a29aa3069b614dbd6bab4476243c70f6ccd03c35131e1cf680cd05bcb9",
        "ResolvConfPath": "/var/lib/docker/containers/c83b19fdedf2b03c1bb3e874ba5c9b4c488d250d74013b638fe8626053298853/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/c83b19fdedf2b03c1bb3e874ba5c9b4c488d250d74013b638fe8626053298853/hostname",
        "HostsPath": "/var/lib/docker/containers/c83b19fdedf2b03c1bb3e874ba5c9b4c488d250d74013b638fe8626053298853/hosts",
        "LogPath": "/var/lib/docker/containers/c83b19fdedf2b03c1bb3e874ba5c9b4c488d250d74013b638fe8626053298853/c83b19fdedf2b03c1bb3e874ba5c9b4c488d250d74013b638fe8626053298853-json.log",
        "Name": "/deploy_lartapi",
        "RestartCount": 0,
        "Driver": "aufs",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "lartdeployment_logs:/LART/LOGS:rw"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "lartdeployment_lartnetwork",
            "PortBindings": {
                "8082/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8082"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": [],
            "CapAdd": null,
            "CapDrop": null,
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": -1,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0
        },
        "GraphDriver": {
            "Name": "aufs",
            "Data": null
        },
        "Mounts": [
            {
                "Name": "lartdeployment_logs",
                "Source": "/var/lib/docker/volumes/lartdeployment_logs/_data",
                "Destination": "/LART/LOGS",
                "Driver": "local",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "lartapi",
            "Domainname": "local",
            "User": "root",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "8082/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "DOTNET_VERSION=1.1.1",
                "DOTNET_DOWNLOAD_URL=https://dotnetcli.blob.core.windows.net/dotnet/release/1.1.0/Binaries/1.1.1/dotnet-debian-x64.1.1.1.tar.gz"
            ],
            "Cmd": null,
            "Image": "lartapi",
            "Volumes": {
                "/LART/LOGS": {}
            },
            "WorkingDir": "/LART/WEBAPI",
            "Entrypoint": [
                "dotnet",
                "LArt.WebApi.dll"
            ],
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "e8005c42e4bc420e198d3aac0226222ab6828c55693e41b6903b7f1bbb0ee421",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "lartdeployment",
                "com.docker.compose.service": "lart.api",
                "com.docker.compose.version": "1.16.1"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "16ceb03a1342f49bb1eb3ff366182b7adb284b7499ffa9635f16b7130facafa0",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "8082/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8082"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/16ceb03a1342",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "lartdeployment_lartnetwork": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "lart.api",
                        "lartapi",
                        "c83b19fdedf2"
                    ],
                    "NetworkID": "4c5da8d914811a140758ded49c7191f05203dddf9a6e77d6f7f2de3af7e827dd",
                    "EndpointID": "b22fa70fba70da2a1610b3d6e08cddea14c8abd5cb9ac218912c6b83f5470243",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.5",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:05"
                }
            }
        }
    }
]
Nkosi
  • 235,767
  • 35
  • 427
  • 472
Vipin
  • 938
  • 5
  • 18
  • 36
  • Everything looks good as such. When you get page not found is it something from a .NET page or something else? Also I hope you are testing this directly on a Linux machine? if not please explain your setup also – Tarun Lalwani Sep 29 '17 at 20:13
  • Yes i setup this in linux machine. when i login to my container using the command docker exec -it deploy_lartapi .bin/bash . Then try to execute wget http://localhost:8082/hangfire. I'm able to see the page serve properly. But when i try to access it from outside page cannot be displayed message is coming – Vipin Sep 29 '17 at 20:19
  • Can you show a screenshot of the browser when the error happens? I am not sure, but hopefully that gives me some idea – Tarun Lalwani Sep 29 '17 at 20:22
  • Please find the screenshot of the browser when error happened . It is not page cannot be displayed . It is a blank page. https://drive.google.com/open?id=0B1vN3_5RjceVZEhzMURCWlA1WTQ – Vipin Sep 29 '17 at 20:27
  • What does the Google chrome Network tab show? – Tarun Lalwani Sep 29 '17 at 20:29
  • This is what showing in the google chrome tab. Any clue?? https://drive.google.com/file/d/0B1vN3_5RjceVbjRUN2JnOVhPa1U/view?usp=sharing – Vipin Sep 29 '17 at 20:33
  • See if this helps https://www.illucit.com/blog/2016/04/hangfire-and-asp-net-5/ and https://discuss.hangfire.io/t/hangfire-path-on-staging-machine-throws-a-401-unauthorized/100/6 and https://stackoverflow.com/questions/29441634/why-is-hangfire-requiring-authentication-to-view-dashboard – Tarun Lalwani Sep 29 '17 at 20:41
  • Thank you Tarun Lalwani. This link solve my issue. I was not aware hangfire allow only local request if not authorized. Could you please update this in answer section so that I can make this question as answered – Vipin Sep 29 '17 at 20:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/155636/discussion-between-vipin-and-tarun-lalwani). – Vipin Sep 29 '17 at 23:00

1 Answers1

2

As you can see in your screenshot the issue is that you are getting a 401 access denied. The reason being that you need to set IDashboardAuthorizationFilter.

See below thread on how to do the setup

Why is Hangfire requiring authentication to view dashboard

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265