0

I have an api running in docker with:

nginx
nodejs api
postgresql
pgadmin4
certbot

When I try to add an endpoint for pgadmin so I can work with the database, I get a 502 bad gateway regardless how I'm setting up the ports for proxy_pass or in docker-compose for the actual container for pgadmin.

docker-compose.yml

version: "3"

services:
  webserver:
    image: nginx:mainline-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - web-root:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - dhparam:/etc/ssl/certs
    depends_on:
      - api-graphql
      - api-postgres-pgadmin
    networks:
      - app-network

  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - web-root:/var/www/html
    depends_on:
      - webserver
    command: certonly --force-renewal --webroot --expand --webroot-path=/var/www/html --email contact@name.dev --agree-tos --no-eff-email -d api.name.dev

  api-graphql:
    container_name: api-graphql
    restart: always
    build: .
    depends_on:
      - api-postgres
    networks:
      - app-network

  api-postgres-pgadmin:
    container_name: api-postgres-pgadmin
    image: dpage/pgadmin4:latest
    networks:
      - app-network
    ports:
      - "8080:8080"
    environment:
      - PGADMIN_DEFAULT_EMAIL=name@gmail.com
      - PGADMIN_DEFAULT_PASSWORD=pass
    depends_on:
      - api-postgres

  api-postgres:
    container_name: api-postgres
    image: postgres:10
    volumes:
      - ./data:/data/db
    networks:
      - app-network
    environment:
      - POSTGRES_PASSWORD=pass

networks:
  app-network:
    driver: bridge

volumes:
  certbot-etc:
  certbot-var:
  web-root:
    driver: local
    driver_opts:
      type: none
      device: /home/name/api/data
      o: bind
  dhparam:
    driver: local
    driver_opts:
      type: none
      device: /home/name/api/dhparam
      o: bind

nginx.conf

server {
        listen 80;
        listen [::]:80;
        server_name api.name.dev;

        location ~ /.well-known/acme-challenge {
          allow all;
          root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name api.name.dev;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/api.name.dev/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.name.dev/privkey.pem;

        ssl_buffer_size 8k;

        ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_prefer_server_ciphers on;

        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

        ssl_ecdh_curve secp384r1;
        ssl_session_tickets off;

        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8;

        location / {
                try_files $uri @api-graphql;
        }

        location @api-graphql {
                proxy_pass http://api-graphql:8080;
                add_header X-Frame-Options "SAMEORIGIN" always;
                add_header X-XSS-Protection "1; mode=block" always;
                add_header X-Content-Type-Options "nosniff" always;
                add_header Referrer-Policy "no-referrer-when-downgrade" always;
                add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
                # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
                # enable strict transport security only if you understand the implications
        } 

        location /pg {
                try_files $uri @api-postgres-pgadmin;
        }

        location @api-postgres-pgadmin {
                proxy_pass http://api-postgres-pgadmin:8080;
                add_header X-Frame-Options "SAMEORIGIN" always;
                add_header X-XSS-Protection "1; mode=block" always;
                add_header X-Content-Type-Options "nosniff" always;
                add_header Referrer-Policy "no-referrer-when-downgrade" always;
                add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
                # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
                # enable strict transport security only if you understand the implications
        }

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
}

Is this just not going to work with having a http://something.com/stuff work with pgadmin? Do we have to us a parent sub domain like stuff.something.com ?

SudoGaron
  • 339
  • 6
  • 22

1 Answers1

1

Bad gateway means nginx cannot reach the backend service you've identified. That could be DNS issues (which don't appear to be an issue here), containers on different networks (again, not an issue), or communicating to a port the container isn't listening on.

Checking the pgadmin image docs, this image appears to listen on port 80, not port 8080. So you'll need to adjust nginx to connect to that port instead:

    location @api-postgres-pgadmin {
            # adjust the next line, removing port 8080, port 80 is the default for http
            proxy_pass http://api-postgres-pgadmin;
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-XSS-Protection "1; mode=block" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header Referrer-Policy "no-referrer-when-downgrade" always;
            add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
            # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
            # enable strict transport security only if you understand the implications
    }
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • That did change things some: it's now a 404. I think I see the issue at this point since my root domain is being rewritten and served over https so api.blah.dev rewrites to https://api.blah.dev. When passing to http://api-postgres-pgadmin it's sending back a 404 "I think". I was hoping it would just allow traffic through since the main webserver is already running across https. Edit: No I'm wrong, as the main / is passing to http: and it works. Which now would point to the pgadmin container having an issue. – SudoGaron May 07 '19 at 00:38
  • 1
    Solution was to add ```SCRIPT_NAME=pg``` to the env variables list in docker-compose. – SudoGaron May 07 '19 at 01:02
  • 1
    Was just about to comment that the "pg" in the path is probably throwing off pgadmin. – BMitch May 07 '19 at 01:03