Nginx reverse proxy for Redmine server container

Hi there,

We have a linux PC that we have docker running multiple applications.
The docker is managed by Portainer and we have setup a reverse proxy using Nginx.
We have server applications running already such as git, duplicati (linux back up) and next cloud.
Also those applications are working well with the reverse proxy.

We want to add another server container for Redmine server but I am having a problem with it connected to the Nginx reverse proxy.

In the docker-compose for Redmine, if I define ports, it exposes the port and I can access the Redmine server container by http://localhost:3000. However, when I setup the reverse proxy for this in Nginx, the host name I specify never goes anywhere (ie. “redmine.mycompany.local:3000”).

Can someone please help me in diagnosing this issue?

If I expose the port 3000 and I call netstat -tulp I can see 3000 is listened but when I don’t expose it, it disappears.

I feel like it’s an issue with containers networks but I am new to docker so I don’t know how to go about diagnosing the issue.
Any pointers will be great!

Thanks

Please share how you start your nginx and redmine container. Furthermore, share the nginx config file as well, so we can actually see what you do and how you do it, so we can get an idea what might need to be done differently.

Apologies for not attaching any details.
I’ve copied the docker-compose.yml files for redmine and nginx.
(why can’t I upload files…)

I use the Nginx web interface to configure the proxy for redmine but I’ve attached the conf file it generates.

Let me know what else I should provide to solve this.

Thanks!

nginx.conf file for redmine
Actual name is 9.conf

# ------------------------------------------------------------
# redminelatest.mycompany.local
# ------------------------------------------------------------


server {
  set $forward_scheme http;
  set $server         "redminelatest";
  set $port           3000;

  listen 80;
  listen [::]:80;

  server_name redminelatest.mycompany.local;

  access_log /data/logs/proxy-host-9_access.log proxy;
  error_log /data/logs/proxy-host-9_error.log warn;


  location / {

    # Proxy!
    include conf.d/include/proxy.conf;
  }


  # Custom
  include /data/nginx/custom/server_proxy[.]conf;
}

docker-compose.yml for nginx

version: '3'

services:

  proxy:
    image: 'jc21/nginx-proxy-manager:latest'
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
    container_name: nginx-proxy-manager
    networks:
      - nginx_network
    ports:
      - '80:80'
      - '8385:81'
      - '443:443'
      - '220:220'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      #- ./proxy/conf.d:/etc/nginx/conf.d:rw
      - ./proxy/vhost.d:/etc/nginx/vhost.d:rw
      - ./proxy/html:/usr/share/nginx/html:rw
      - ./proxy/certs:/etc/nginx/certs:ro
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: unless-stopped

networks:
  nginx_network:
    name: nginx_network

docker-compose.yml for Redmine

services:
  db:
    image: mariadb
    container_name: redmine-mariadb
    volumes:
      - redmine_db_data:/var/lib/mysql
      - /etc/localtime:/etc/localtime:ro
    environment:
      - MYSQL_ROOT_PASSWORD=***
      - MYSQL_PASSWORD=***
      - MYSQL_DATABASE=redminelatest
      - MYSQL_USER=redminelatest
    restart: unless-stopped

  redminelatest:
    image: redmine:latest
    container_name: redminelatest
    restart: always
    #ports:
    #  - '3000:3000'
    depends_on:
      - db
      - proxy
    environment:
      - VIRTUAL_HOST=redminelatest.mycompany.local
    volumes:
      - redmine_plugins:/usr/src/redmine/plugins
      - redmine_files:/usr/src/redmine/files
      - redmine_themes:/usr/src/redmine/public/themes

volumes:
  redmine_db_data:
  redmine_plugins:
  redmine_files:
  redmine_themes:

networks:
  default:
    name: nginx_network

It appears this file is mounted as a volume in the proxy service. It listens on port 80 and acts if the proxy is accessed using the url http://redminelatest.mycompany.local.

To get an understanding how you actually proxy the requests to the backend, we need to see the two includes as well.

I assume you do set the variables in the head of the server block and re-use them inside the includes?

Below is the proxy.conf.
I can’t find the other file as there is no custom folder under /data/nginx/.

The other thing we were thinking of was what if a different container was using also port 3000, would Nginx be able to handle that?

I would have thought that should not be a problem since it should handle the network from different containers… Am not sure how to diagnose the docker network (nginx_network).

Any pointers would be great.
Also if you need any other info, let me know!

proxy.conf

# cat proxy.conf
add_header       X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto  $scheme;
proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP          $remote_addr;
proxy_pass       $forward_scheme://$server:$port$request_uri;

I assume the nginx configuration is rendered by nginx-proxy-manager based on configurations done in the ui, so I assume declaring $server and $port does not override required values. Furthermore, I am not sure if $request_uri really is required or even might cause problems.

The incoming request on port 80 uses the reverse proxy rule based on the domain name. The proxy itself uses the service name and container port to forward the request. The proxy and redmine container share a network, so incoming requests should be proxied to redmine. The “plumbing” look correct.

You can copy the nginx logs from the container to your host and inspect them with a editor/viewer of your choice:

docker cp container_name_or_id:/data/logs/proxy-host-9_access.log .
docker cp container_name_or_id:/data/logs/proxy-host-9_error.log .

Why would different proxy rules to different target containers on the same target port create problems?
Nginx doesn’t care and is not affected by this → Of course it can handle it.

As you say I set all the variables ($forward_scheme, $server and $port) from the nginx UI.

It turns out that the both access and error logs are empty for the redminelatest container. The files exist but nothing in it (size is 0 bytes).
Does that indicate that the nginx proxy host for redmine is not working at all?
What else can I try?
I can bash into the nginx container to see what’s going on…

Please help!

It appears like it. I would have expected traces indicating access or at least errors.

Does the domain redminelatest.mycompany.local really resolve to the docker host, where the proxy is running? The server block will only listen if it is access by the domain specified in server_name, it will not react if the docker host’s ip or hostname or even a different domain name that resolves to the host is used.

I don’t use it npm, so I can’t really tell how it needs to be configured. Since the nginx conf looks okay, are you sure there is no “enable rule” button or the requirement to reload the config or restart the nginx service.

Hello

I’m sorry that I haven’t updated this for a while.

Thank you for the pointer meyay!
After realising that it wasn’t working at all, I looked into our DNS for the server and that needed to be setup.
After I added the virtual DNS for the redmine docker, it started working :smiley:

thanks for your help.