Separate frontend and backend with Heroku - heroku

I have an application, let's call it derpshow, that consists of two repositories, one for the frontend and one for the backend.
I would like to deploy these using Heroku, and preferably on the same domain. I would also like to use pipelines for both parts separate, with a staging and production environment for each.
Is it possible to get both apps running on the same domain, so that the frontend can call the backend on /api/*? Another option would be to serve the backend on api.derpshow.com and the frontend on app.derpshow.com but that complicates security somewhat.
What are the best practices for this? The frontend is simply static files, so it could even be served from S3 or similar, but I still need the staging and production environments and automatic testing and so and so forth.
Any advice is greatly appreciated!

For what you are trying to you must use webserver for serving static content and provide access to container(gunicorn, tomcat, etc...) holding your app. Also this is best practice.
Asume your use nginx as webserver, because its easier to setup. nginx config file would look like this
# Server definition for project A
server {
listen 80;
server_name derpshow.com www.derpshow.com;
location / {
# Proxy to gUnicorn.
proxy_pass http://127.0.0.1:<projectA port>;
# etc...
}
}
# Server definition for project B
server {
listen 80;
server_name api.derpshow.com www.api.derpshow.com;
location / {
# Proxy to gUnicorn on a different port.
proxy_pass http://127.0.0.1:<projectBg port>;
allow 127.0.0.1;
deny all;
# etc...
}
}
And thats it.
OLD ANSWER: Try using nginx-buildpack it allows you to run NGINX in front of your app server on Heroku. Then you need to run your apps on different ports and setup one port to api.derpshow.com and other to app.derpshow.com, and then you can restrict calls to api.derpshow.com only from localhost.

Would just like to contribute what I recently did. I had a NodeJS w/ Express backend and a plain old Bootstrap/vanilla frontend (using just XMLHttpRequest to communicate). To connect these two, you can simply tell express to serve static files (i.e. serve requests to /index.html, /img/pic1.png) etc.
For example, to tell express to serve the assets in directory test_site1, simply do:
app.use(express.static('<any-directory>/test_site1'));
Many thanks to this post for the idea: https://www.fullstackreact.com/articles/deploying-a-react-app-with-a-server/
Note that all these answers appear to be variations of merging the code to be served by one monolith server.
Jozef's answer appears to be adding an entire nginx server on top of everything (both the frontend and backend) to reverse proxy requests.
My answer is about letting your backend server serve frontend requests; I am sure there is also a way to let the frontend server serve backend requests.

Related

Problem deploying nginx on heroku in front of server on Go

I want to deploy to heroku nginx as a reverse proxy in front of my Go application.
I made a config file for nginx, but its samples presented here https://github.com/heroku/heroku-buildpack-nginx do not give an understanding of which port to specify in the proxy_pass directive to redirect to my application. These examples use unix socket listening instead of http.
upstream app_server {
server unix: /tmp/nginx.socket fail_timeout = 0;
}
But my application is running over http.
In addition, heroku uses random ports, which the application must retrieve from the PORT environment variable. However, now I have set this variable in the config for nginx. What port should my application run on now? If you specify your own port, this will not work, since heroku will say that the port is already busy.
I am completely discouraged by the difficulty of deploying a simple environment for my heroku application. None of the heroku instructions give a comprehensive understanding of how this can be done.
Please guide me on the right path.
P.S. For a couple of days of searching for an answer, I found only a lot of questions similar to mine and not a single answer.
Update.
I did as in this post Springboot application with nginx as proxy deploy on Heroku
But the author did not explain what she set in the APP_PORT variable. I set it to 3001 and got the same thing as here:
Nginx and Heroku. Serving Static Files

Move application from homestead to docker

My application consists of three domains:
example.com
admin.example.com
partner.example.com
All of these domains are handled by the same Laravel app. Each domain has its own controllers and view. Models and other core functionalities are shared between all three domains.
Currently my local dev-environment is build with Homestead (based on Vagrant), where each local domain (example.test, admin.example.test and partner.example.test) points to the same directory (e.g. /home/vagrant/app/public).
Because of deployment problems regarding different versions of OS, NPM, PHP, etc. I want to move to docker. I've read a lot of articles about multiple domains or apps with docker. Best practice seems to be to set up an Nginx reverse proxy which redirects all incoming requests to the desired app. Unfortunately, I haven't found examples for my case where all domains point to the same application.
If possible I would avoid having the same repository cloned three times for each docker container running one specific part of the app.
So what would be the best approach to set up a docker environment?
I created a simple gist for you to look at of how I would do it
https://gist.github.com/karlisabele/f7d91594c004e227e504473ce2c60508
The nginx config file is based on Laravel documetation (https://laravel.com/docs/5.8/deployment#nginx) and of course in production you would also want to handle SSL and map port 443 as well, but this should serve as POC for you.
Notice that in the nginx configuration I use the php-fpm service name to pass the request to php-fpm container. In docker the service names can be used as host names for corresponding service so the line fastcgi_pass php-fpm:9000; means that you are passing the request to php-fpm containers port 9000 (default port for the fpm image to listen to)
Basically what you want to do is simply define in the nginx that all 3 of your subdomains are handled by the same server configuration. Then nginx simply passes the request to php-fpm to actually process it.
To test, you can just copy the two files from gist in your project directory, replace YOUR_PROJECT_FOLDER in docker-compose.yml file with the actual location of your project (can be simply .:/var/www/html if you place the docker-compose.yml in the root of your project) then run docker-compose up -d. Add the domains to your hosts file (/etc/hosts un linux/mac) and you should be able to visit example.test and see your site.
Note: Depending on where your database is located, you might need to change the host for it if it's localhost at the moment, because it will try to connect to a mysql server from php-fpm container, which of course does not have it's own mysql-server running.

Reverse proxy same naked domain to different hosts

I'm managing the DNS of my domain with Cloudflare.
The marketing pages for are hosted with Netlify.
The main application is hosted with Heroku.
Is it possible with cloudflare + a naked domain (my-example.com) to have some paths being served by Netlify and other paths by Heroku?
Or am I forced to put one of the hosting services on a subdomain?
Disclaimer: I work for Netlify.
You can definitely do this without running your own server or paying anything extra.
Since Netlify already has a CDN, it's suboptimal to put cloudflare's CDN (activated with the 'orange cloud' in their settings) in front of Netlify's. Besides being inefficient, doing so breaks Netlify's atomic deploys and rollbacks and also slows down page service from our observations. It may work, but is not recommended. However, CloudFlare's DNS is quite performant and can be used without their CDN (turn off the 'orange cloud'). Their DNS works well with content hosted on Netlify's CDN.
Here's how to set things up to accomplish this via Netlify.
Deploy your static assets to a Netlify site at your main custom domain, let's say it's my-example.com. For testing purposes you can use the built-in sitename at Netlify (something-something-1234.netlify.com) instead of my-example.com. The below example redirects are "host agnostic" so will work with the Netlify hostname, Netlify deploy previews, AND the production hostname.
Find all the paths for your dynamic content - for this example, let's say it's /main/* and /app/* that are dynamic and your backend is hosted on Heroku.
Create proxy redirect rules to point to those paths. They could be hosted via CloudFlare's CDN to protect your API if you wanted to - Netlify proxying to CloudFlare-fronted sites on Heroku works fine. You could also choose just to proxy straight to Heroku which would be less complicated. Netlify has some DDoS protection built-in and is still "in front of" your Heroku app. Up to you.
Deploy those proxy rules and test.
Netlify's proxying (technically reverse proxying) can connect to whatever backend you'd like and does NOT show the URL to the visitor - it looks to them (URL bar in the browser, HTTPS connection) as though they are connected to my-example.com the whole time, but the content is returned from your backend (including HTTP status codes. This response is cached on Netlify's CDN if indicated by your Cache-Control: HTTP Header directives which the Heroku app sends. Note that CloudFlare WILL CHANGE your Cache-Control header in case you set it on content they proxy to! Netlify won't.)
Here's a common setup:
/main/* https://yourapp.herokuapp.com/main/:splat 200!
/app/* https://yourapp.herokuapp.com/main/:splat 200!
Note that if you deploy ANY assets under /main or /app to Netlify, they will be ignored due to the trailing ! on those rules. See https://www.netlify.com/docs/redirects/#note-on-shadowing for some more details about how that works and the alternatives (TL;DR: deploying some things like /main/logo.png on Netlify but nothing that Heroku should serve vs deploying ALL needed content for /main/* on Heroku).
Note that I suggest using identical paths on Netlify and Heroku (/main/*) rather than proxying to /somethingelse/* since it is easier to debug asset loading when paths match up. This isn't a requirement, though.
As mentioned in the comment, its possible using cloudflare enterprise service.
But you can do it with a simple nginx reverse proxy setup.
Have DNS resolve to nginx reverse proxy and based on the path, appropriately call the upstreams.
eg. example.com, and then direct queries for /path1 to 100.100.100.100 and for /path2 to 200.200.200.200

Serving a website using Caddy

I have created an application and want to serve it using caddy.
On my localhost if I run the application on 127.0.0.1:9000 and set it as proxy in
the caddyfile it works. I figured I have to serve my website similarly on my production as well.
Now I am trying to serve it on my ec2 instance. I tried serving it on localhost, 127.0.0.1 and even the domain directly itself but caddy does not work here. Oneof the things I noticed is that the url is automatically changing from http tp https, I figure it means that at least caddy is running and recognizing the request but is not actually able to find the content.
Below is my CaddyFile.
abc.xyz.com {
proxy / zbc.xyz.com:9000 {
transparent
}
}

Enable page caching on Nginx

I have a CDN for my website that uses Nginx and Drupal.
In my nginx configuration, I am trying to enable page level caching so requests like "website.com/page1" can be served from the CDN. Currently, I am only able to serve static files from the CDN(GET requests on 'website.com/sites/default/files/abc.png').
All page-level requests always hit the back-end web server.
What nginx config should I add in order for "website.com/page1" requests to also be served from the CDN?
Thanks!
If I understand you correctly, you want to setup another Nginx so that it works as a basic CDN in front of your current webserver (Nginx or Apache??) on which Drupal resides. You need to have a reverse proxy Nginx server to cache both static assets and pages. Since its not super clear to me what you wrote, this is what I assumed.
If you want a setup like this, then you should read the following article on how to setup reverse proxy

Resources