skip to Main Content

I have a SPA (Single Page App) with JS and an index.html.

I’m serving it with my backend Golang app from /public dir.

I’m deploying this Golang app on Heroku: everything works!

Now I’m building an SSR (Server Side Rendered) app using Svelte Kit (or NextJS, I still have to decide).

GIVEN:

The SSR app is a NodeJS app which requires a dedicated Heroku dyno: I think I cannot serve it like I do now from /public dir.

Leaving aside the additional cost for the dedicated dyno, now there are also new problems of the additional latency given by:

  1. frontend SSR app (on frontend.herokuapp.com) needs to call backend.herokuapp.com;

  2. new CORS calls for the different domains

QUESTION:

Is there a way to deploy both apps on the same dyno?

Maybe with a proxy (ex: nginx or HA) in front of them so that I can have a single domain with both:

  1. myapp.heroku.com –> serving SSR app (index.html which can call my backend using /api and NOT backend.herokuapp.com/api)

  2. myapp.heroku.com/api –> which can be called from the frontend app without CORS calls

Am I totally crazy?

CONTEXT:

It’s a small app with few views.

2

Answers


  1. As per the questions and suggestions on the internet, the answer is NO.

    According to many communities and experts, Heroku’s model is to run one app per dyno (and often many dynos for a single app).

    But wait, there is a case in which two servers are deployed to a single dyno and it worked too.
    You can check it here: https://medium.com/@nadayar/heroku-fu-multiple-servers-on-one-dyno-6fc68d57b373

    Hope this solves you problem!

    Login or Signup to reply.
  2. Heroku allows only one port per Dyno (hence only one application is able to receive and process web requests), however there is a workaround that allows combining 2 apps in one Dyno using the Heroku Docker Registry.

    The solution involves creating one Dockerfile which has both applications and that will launch both when deployed on Heroku.
    Only one application (web frontend) will bind to the Heroku port and therefore accepting requests from the web. The second application (backend) will not be available outside the container while the first app is able to reach it.

    Example of Dockerfile with 2 Java services (other languages/frameworks would be possible too):

    RUN mkdir -p /software
    
    # copy first app (run on $PORT)
    ADD target/app1.jar /software/app1.jar
    # copy second app (run always on 8888)
    ADD lib/app2.jar /software/app2.jar
    
    ADD startup.sh /software/startup.sh
    
    USER root
    RUN chmod a+x /software/startup.sh
    
    CMD /software/startup.sh
    

    The startup.sh must launch both applications in parallel

    java -Dserver.port=$PORT $JAVA_OPTS -jar /software/app1.jar &
    java -Dserver.port=8888 -jar /software/app2.jar && fg
    

    The web requests to the Dyno (app.herokuapp.com) will resolve to the web frontend (app1 in the example above). The frontend can connect to the backend using the local address/port

    http://localhost:8888/
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search