Reputation: 1372
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:
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.
Upvotes: 8
Views: 8312
Reputation: 998
i am not writing anything new from @Pram, just what i had to do.
this resulted in 3 heroku apps.
/etc/nginx/conf.d/default.conf
upstream frontend {
server $FRONTEND_URL;
}
upstream backend {
server $BACKEND_URL;
}
server {
listen $PORT;
location / {
proxy_pass http://frontend;
proxy_set_header Host $FRONTEND_URL;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://backend;
proxy_set_header Host $BACKEND_URL;
proxy_set_header Cookie $http_cookie;
}
}
Dockerfile
FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf
CMD /bin/bash -c "envsubst '\$PORT \$FRONTEND_URL \$BACKEND_URL' < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'
Upvotes: 1
Reputation: 2501
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
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
Upvotes: 12