Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx - Heroku Docker - Is it possible to run Nginx as a reverse proxy on Heroku

I'm trying to figure out how build a reverse proxy on an Heroku app with Nginx. The problem is that Heroku seems to accept only one container per application. But my application system would use at least three container:

  • one for Nginx
  • one for my app frontend
  • one for my business logic server

So is it possible to make that with Heroku? I mean, deploy in a way or another a multi-container application on the same domain? It would be purely awesome. If someone has any hint, would be great. Thanks.

like image 618
HoCo_ Avatar asked Oct 12 '18 14:10

HoCo_


People also ask

Can Nginx be used as reverse proxy?

Nginx is an open source web server that can also serve as a reverse proxy. Apart from being used to host websites, it's also one of the most widely used reverse proxy and load balancing solutions.

Can I use nginx on Heroku?

Installing Nginx on HerokuYou can run multiple processes and applications in your Dyno by using the Heroku Multi Buildpack in combination with the Heroku Runit Buildpack. This allows you to specify any amount of buildpacks to run on one Dyno.

Is Nginx a forward or reverse proxy?

Reverse proxy is one of the most widely deployed use case for NGINX instance, providing an additional level of abstraction and control to ensure the smooth flow of network traffic between clients and servers.

Do I need nginx with Heroku?

You don't have to--if unspecified Heroku will use WEBrick by default, but they recommend using unicorn as the web server instead (https://devcenter.heroku.com/articles/ruby-default-web-server) for performance since WEBrick is a single-threaded single process and might break under high load.


1 Answers

I have a template which is kind of similar, but difference is that it requires 3 applications in heroku.
Since each container runs in separate application, all of them are exposed to outer world.

This template uses travis to build and deploy containers to heroku.
Template has 3 images
* Frontend(Nginx - React)
* Backend(Nodejs - express)
* Server(Nginx)

I have referred below urls for my template.
https://medium.com/@javierfernandes/continuous-deployment-con-docker-travis-heroku-c24042fb830b
Heroku (Docker) PORT environment varibale in nginx

Below is repository url.
https://github.com/pramodramdas/heroku_multi_dockers

Steps

  • Create 3 applications in heroku.
  • Get api key from heroku -> account settings -> Api Key
  • Create following environment variables in travis

    HEROKU_USERNAME=_ //underscore
    HEROKU_PASSWORD= //Api key from heroku
    HEROKU_API_KEY= //same api key as above
    HEROKU_APP_BACKEND= //heroku back end app name without ".herokuapp.com"
    HEROKU_APP_CLIENT= //heroku front end app name without ".herokuapp.com"
    HEROKU_APP_NGINX= //heroku nginx app name without ".herokuapp.com"
    DOCKER_USERNAME= //dockerhub username
    DOCKER_PASSWORD= //dockerhub password

  • Create following environment variables in nginx heroku app

    HEROKU_APP_BACKEND_URL= //heroku back end app url example: xxxxxx.herokuapp.com
    HEROKU_APP_CLIENT_URL= //heroku front end app url example: xxxxxx.herokuapp.com

My nginx server config.

upstream client {
  server $HEROKU_APP_CLIENT_URL;
}

upstream backend {
  server $HEROKU_APP_BACKEND_URL;
}

server {
  listen $PORT;

  location / {
    proxy_pass http://client;
    proxy_set_header Host $HEROKU_APP_CLIENT_URL;
  }

  location /api {
    proxy_pass http://backend;
    proxy_set_header Host $HEROKU_APP_BACKEND_URL;
  }
}

front end bundle is severed through separate nginx server inside Frontend container. Below is config

server {
  listen $PORT;

  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
  }
}

Docker file should have commands to copy bundle to nginx and

CMD /bin/bash -c "envsubst '\$PORT \$HEROKU_APP_CLIENT_URL \$HEROKU_APP_BACKEND_URL' < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'

at end of docker file in order to pick env variables.

Below is travis config

sudo: required
language: node_js 
node_js: 
  - "9"
services:
  - docker

before_install:
  - wget -qO- https://toolbelt.heroku.com/install.sh | sh
  - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
  - echo "$HEROKU_PASSWORD" | docker login -u "$HEROKU_USERNAME" --password-stdin registry.heroku.com

script:
  - docker build -t $DOCKER_USERNAME/docker_client ./frontend_heroku;
  - docker tag $DOCKER_USERNAME/docker_client registry.heroku.com/$HEROKU_APP_CLIENT/web;
  - docker build -t $DOCKER_USERNAME/docker_backend ./backend_heroku;
  - docker tag $DOCKER_USERNAME/docker_backend registry.heroku.com/$HEROKU_APP_BACKEND/web;
  - docker build -t $DOCKER_USERNAME/docker_nginx ./nginx_heroku;
  - docker tag $DOCKER_USERNAME/docker_nginx registry.heroku.com/$HEROKU_APP_NGINX/web;

deploy:
  provider: script
  script: 
    # push to dockerhub & heroku 
    docker push $DOCKER_USERNAME/docker_client;
    docker push registry.heroku.com/$HEROKU_APP_CLIENT/web;
    heroku container:release web --app $HEROKU_APP_CLIENT;
    docker push $DOCKER_USERNAME/docker_backend;
    docker push registry.heroku.com/$HEROKU_APP_BACKEND/web;
    heroku container:release web --app $HEROKU_APP_BACKEND;
    docker push $DOCKER_USERNAME/docker_nginx;
    docker push registry.heroku.com/$HEROKU_APP_NGINX/web;
    heroku container:release web --app $HEROKU_APP_NGINX;
  on: 
    branch: master 
like image 110
Pram Avatar answered Sep 22 '22 14:09

Pram