Giter Site home page Giter Site logo

rendora / rendora Goto Github PK

View Code? Open in Web Editor NEW
2.0K 40.0 108.0 185 KB

dynamic server-side rendering using headless Chrome to effortlessly solve the SEO problem for modern javascript websites

Home Page: https://rendora.co

License: Apache License 2.0

Dockerfile 0.75% Go 97.93% Makefile 1.32%
ssr react vue angular reactjs vuejs go golang chrome-headless chrome-devtools

rendora's Introduction

Rendora

Rendora

Go Report Card CircleCI GoDoc License Join the chat at https://discord.gg/6yyErk8

Rendora is a dynamic renderer to provide zero-configuration server-side rendering mainly to web crawlers in order to effortlessly improve SEO for websites developed in modern Javascript frameworks such as React.js, Vue.js, Angular.js, etc... Rendora works totally independently of your frontend and backend stacks

Rendora's Diagram

Main Features

  • Zero change needed in frontend and backend code
  • Filters based on user agents and paths
  • Single fast binary written in Golang
  • Multiple Caching strategies
  • Support for asynchronous pages
  • Prometheus metrics
  • Choose your configuration system (YAML, TOML or JSON)
  • Container ready

What is Rendora?

Rendora can be seen as a reverse HTTP proxy server sitting between your backend server (e.g. Node.js/Express.js, Python/Django, etc...) and potentially your frontend proxy server (e.g. nginx, traefik, apache, etc...) or even directly to the outside world that does actually nothing but transporting requests and responses as they are except when it detects whitelisted requests according to the config. In that case, Rendora instructs a headless Chrome instance to request and render the corresponding page and then return the server-side rendered page back to the client (i.e. the frontend proxy server or the outside world). This simple functionality makes Rendora a powerful dynamic renderer without actually changing anything in both frontend and backend code.

What is Dynamic Rendering?

Dynamic rendering means that the server provides server-side rendered HTML to web crawlers such as GoogleBot and BingBot and at the same time provides the typical initial HTML to normal users in order to be rendered at the client side. Dynamic rendering is meant to improve SEO for websites written in modern javascript frameworks like React, Vue, Angular, etc...

Read more about dynamic rendering from these articles by Google and Bing. Also you might want to watch this interesting talk at Google I/O 2018

How does Rendora work?

Rendora is listening by default to the port 3001 but can be changed using the config file; for every request coming from the frontend server or the outside world, there are some checks or filters that are tested against the headers and/or paths according to Rendora's configuration file to determine whether Rendora should just pass the initial HTML returned from the backend server or use headless Chrome to provide a server-side rendered HTML. To be more specific, for every request there are 2 paths:

  1. If the request is whitelisted as a candidate for SSR (i.e. a GET request that passes all user agent and path filters), Rendora instructs the headless Chrome instance to request the corresponding page, render it and return the response which contains the final server-side rendered HTML. You usually want to whitelist only web crawlers like GoogleBot, BingBot, etc...

  2. If the request isn't whitelisted (i.e. the request is not a GET request or doesn't pass any of the filters), Rendora will simply act as a transparent reverse HTTP proxy and just conveys requests and responses as they are. You usually want to blacklist real users in order to return the usual client-side rendered HTML coming from the backend server back to them.

Install and run Rendora

First, run a headless Chrome instance

If Chrome/Chromium is installed in your system, you can run it using

google-chrome --headless --remote-debugging-port=9222

note: Mac users may have a google-chrome: command not found error. If that's the case, run the following command and repeat the previous step:

alias google-chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"

or simply using docker

docker run --tmpfs /tmp --net=host rendora/chrome-headless

note: the tmpfs flag is optional but it's recommended for performance reasons since rendora/chrome-headless runs with flag --user-data-dir=/tmp

Then, run Rendora

you can build and run Rendora from source code, (NOTE: please read the configuration manual before running Rendora)

git clone https://github.com/rendora/rendora
cd rendora
# MAKE SURE YOU HAVE GO V1.11+ INSTALLED
make build
sudo make install
rendora --config CONFIG_FILE.yaml

or simply using docker

docker run --net=host -v ./CONFIG_FILE.yaml:/etc/rendora/config.yaml rendora/rendora

Documentation

You can read the docs here or here

Configuration

Configuration is discussed in detail in docs here or here

A minimal config file example

target:
    url: "http://127.0.0.1" # this is the base url addressed by the headless Chrome instance, it can be simply your website url
backend:
    url: "http://127.0.0.1:8000" # your backend server url

filters:
    userAgent: # .i.e. only whitelist useragents containing the keywords "bot", "slurp", "bing" or "crawler"
        defaultPolicy: blacklist
        exceptions:
            keywords:
                - bot
                - slurp
                - bing
                - crawler

A more customized config file

listen:
    address: 0.0.0.0
    port: 3001
cache:
    type: redis
    timeout: 6000
    redis:
        address: localhost:6379
target:
    url: "http://127.0.0.1" 
backend:
    url: "http://127.0.0.1:8000"
headless:
    waitAfterDOMLoad: 0
    internal:
      url: http://localhost:9222
output:
    minify: true
filters:
    userAgent:
        defaultPolicy: blacklist
        exceptions:
            keywords:
                - bot
                - slurp
                - bing
                - crawler
    paths:
        defaultPolicy: whitelist
        exceptions:
            prefix:
             - /users/

FAQs

What is the difference between Rendora and Puppeteer?

Puppeteer is a great Node.js library which provides a generic high-level API to control headless Chrome. On the other hand, Rendora is a dynamic renderer that acts as a reverse HTTP proxy placed in front of your backend server to provide server-side rendering mainly to web crawlers in order to effortlessly improve SEO.

What is the difference between Rendora and Rendertron?

Rendertron is comparable to Rendora in the sense that they both aim to provide SSR using headless Chrome; however there are various differences that can make Rendora a much better choice:

  1. Architecture: Rendertron is a HTTP server that returns SSR'ed HTML back to the client. That means that your server must contain the necessary code to filter requests and asks rendertron to provide the SSR'ed HTML and then return it back to the original client. Rendora does all that automatically by acting as a reverse HTTP proxy in front of your backend.

  2. Caching: Rendora can be configured to use internal local store or Redis to cache SSR'ed HTML.

  3. Performance: In addition to caching, Rendora is able to skip fetching and rendering unnecessary content CSS, fonts, images, etc... which can substantially reduce the intial DOM load latency.

  4. Development: Rendertron is developed in Node.js while Rendora is a single binary written in Golang.

  5. API and Metrics: Rendora provides Prometheus metrics about SSR latencies and number of SSR'ed and total requests. Furthermore, Rendora provides a JSON rendering endpoint that contains body, status and headers of the SSR response by the headless Chrome instance.

Acknowledgements

Many thanks to @mafredri for his effort to create cdp, a great Chrome DevTools Protocols client in Golang.

Follow rendora news and releases on Twitter

George Badawi - 2018

rendora's People

Contributors

bordalix avatar geokb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rendora's Issues

ERR_CONNECTION_REFUSED

with the configuration down below, everything looks just fine,but when I visit http://localhost:3001/, I only got **ERR_CONNECTION_REFUSED**, can anyone told me how to debug with it, a lot of thanks.

chrome-headless
image

rendora
image

local react project
image

configuration

listen:
    address: 0.0.0.0
    port: 3001
cache:
    type: redis
    timeout: 6000
    redis:
        address: localhost:6379
target:
    url: "http://127.0.0.1:3000" 
backend:
    url: "http://127.0.0.1:3000"
headless:
    waitAfterDOMLoad: 0
    internal:
      url: http://localhost:9222
output:
    minify: true
filters:
    userAgent:
        defaultPolicy: blacklist
        exceptions:
            keywords:
                - bot
                - slurp
                - bing
                - crawler
    paths:
        defaultPolicy: whitelist
        exceptions:
            prefix:
             - /users/

go build fail

➜ rendora git:(master) go build go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/text" (https fetch: Get https://golang.org/x/text?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sync" (https fetch: Get https://golang.org/x/sync?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: error loading module requirements

These resource addresses are 404

invalid URL

run ./rendora --config config.yml

Get http://::1:9222/json/new: invalid URL port ":1:9222"

Failed to adjust OOM score of renderer with pid 30: Permission denied (13)

I am getting the following permission denied on the chrome-headless service, when running on a k8s cluster on Digital Ocean and GCP.


Image: rendora/chrome-headless:latest

Complete log:

Fontconfig warning: "/etc/fonts/fonts.conf", line 100: unknown element "blank"
[0811/114937.698064:ERROR:gpu_process_transport_factory.cc(967)] Lost UI shared context.

DevTools listening on ws://0.0.0.0:9222/devtools/browser/a0a6536d-82d6-42d2-986f-acf4267dd9bc
[0811/114937.706665:ERROR:zygote_host_impl_linux.cc(259)] Failed to adjust OOM score of renderer with pid 30: Permission denied (13)

A couple of months ago I was able to deploy and use it without any issues. Now I am getting this.

Performance

Could you please explain if rendora + chrome headless can process concurrent requests in parallel? Or are all of the requests synchronous? I ran a simple benchmark and that's what I got:

wrk -H 'User-Agent: bot' http://127.0.0.1:3001
Running 10s test @ http://127.0.0.1:3001
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.01s     0.00us   1.01s   100.00%
    Req/Sec     0.11      0.33     1.00     88.89%
  9 requests in 10.09s, 334.15KB read
  Socket errors: connect 0, read 1, write 0, timeout 8
Requests/sec:      0.89
Transfer/sec:     33.10KB

Config(http://backend.d is a simple SPA, fetches dummy data from API, performance ~ 3000rps):

listen:
    address: 0.0.0.0
    port: 3001
target:
    url: "http://backend.d"
backend:
    url: "http://backend.d"
headless:
    waitAfterDOMLoad: 1000
    internal:
        url: http://localhost:9222
    timeout: 5
output:
    minify: true
debug: true
cache:
    type: none
filters:
    userAgent:
        defaultPolicy: blacklist
        exceptions:
            keywords:
                - bot
                - bing
                - crawler
                - curl

How to use in combination with nginx?

Can you give an example nginx configuration in combination with rendora?

E.g. how would I use Rendora in combination with the nginx site below.

Nginx site:

server {
	server_name www.example.com;
	listen 443 ssl http2 default_server;
	listen [::]:443 ssl http2 default_server ipv6only=on;

	root /var/www/example/public;
	index index.php index.html index.htm;

	location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

}

Rendora + Angular 6 ?

Hi guys, first i want say - big thanks for you job!
I try to use rendora with angular 6 - SPA, and all my attempts to make it works well, do not succeed.
On backend i use Node.js - and they return angular dist.
For testing I successfully setup and run rendora+headless chrome. I set target:url and backend:url - my local site host - for example: url: "http://localhost:80". Next i try open http://localhost:3001 - and my site open good and all works well, but if i set some crawlers bot user agent and reload page - i wait about 20-30 sec and page not load correctly (missed css style and some other) and not load successfully. I think may be i do some wrong, can somebody please write some instruction how setup rendora with angular 6 + node.js or tell what i do wrong ? I will be grateful. (p.s. now i use rendertr*n - they work well but - solution have low performance and no cache.)

2019-01-07 03 28 40

Provide a JavaScript Hook to Indicate to Rendora that Page is Done Rendering

I am using Rendora to pre-render my site, but I recently setup a healthcheck to make sure that it is working and I noticed that at certain times of the day the pre-rendered response that Rendora gives does not contain the complete content of the page. I'm pretty sure that the reason for this is that the page has simply not finished asynchronously grabbing the content for the page from the backend API.

The problem is that the only solution to making sure that the content is present before Rendora returns a response is to increase the time that Rendora waits for the page to Render. Increasing the wait time will mean a lower ranking in search engines. If the wait time has to be increased because the page is still rendering that is fine, the problem is that sometimes it needs more time and other times it doesn't. Things like server load at the time can cause a response to take longer than normal and then result in a search engine hit coming back with an empty page.

Is there a way we could possibly add a hook of some sort that my SPA could use to notify Rendora that the rendering is complete? That way, no matter how short or long the page took to render, Rendora will know precisely when to return a response. Obviously it would be optional and every other site you hook up with Rendora would remain unchanged if it doesn't want to use the feature.

To keep things simple, you could even have it setup so that I just console.log("Rendora: ready") and Rendora will instantly return the page when it sees that in the console.

This would make me feel much better about Rendora and knowing that it knows when to return my rendered page.

Does It Support Websocket?

My stack is like:
External World <-> nginx <-> rendora <-> nginx <-> daphne <-> django

I am using websocket connections. When I was doing
External World <-> nginx <-> daphne <-> django

It worked well. But when I implemented rendora and added another proxy to nginx, it does not work. Websocket connection fails while handshakes. My nginx conf is like below:

server {
        listen 8000;

        location / {
                include proxy_params;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_pass http://unix:/home/ubuntu/myproject/myproject.sock;
        }
}

server {
        server_name mydomain;
        charset utf-8;

        location /static {
                alias /home/ubuntu/myproject/apps/web-build/static;
        }
 location /      {
                include proxy_params;
                proxy_pass http://127.0.0.1:3001;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }

    listen 443 ssl; # managed by Certbot
   ...
}

So location / 443 port sends all requests to 127.0.0.1:3001 where rendora is listening. And rendora forward them to 127.0.0.1:8000 nginx proxy to connect to daphne unix socket.
Rendora works well except the websocket requests.
It would be helpful if there is a nginx configuration example.

How to setup Rendora correctly? Rendora does not return api call results

I have set up a server for my vue project, I installed caddy to serve my files up and running and its working, according to rendora docs I have installed and started chrome headless browser and have rendora up and running too with this config options:

{
  "backend": {
    "url": "http://127.0.0.1:80"
  },
  "target": {
    "url": "https://mywebsite.com"
  },
  "headless": {
    "waitAfterDOMLoad": 0,
    "internal": {
      "url": "http://127.0.0.1:9222"
    }
  },
  "output": {
    "minify": true
  },
  "filters": {
    "userAgent": {
      "defaultPolicy": "whitelist"
    }
  }
}

This is my Caddy config file:

https://mywebsite.com {

  root /opt/www.mywebsite/dist/

  # vue-router mode is 'history', so all urls should resolve to root.
  rewrite {
      regexp .*
      to {path} /
  }

  log {
      rotate_size 50   # Rotate after 50 MB
  }

}

when i check my netstat it looks like everything is ok but when i curl my website from my local terminal even my defaultPolicy is whitelist it doesn't return full html so i guess there is something wrong.

Is config files folder important? it is in the www.mywebsite folder with the dist/ folder. Is there a way besides curl-ing from my local to check rendora?

If it's not working what am i doing wrong?

Returning 304

Hey guys, I'm looking for u to see if anyone can help, because I tried a lot and nothing seems to work. I have the follow stack:
An AWS ECS Fargate Service exposing the Rendora (with cache disabled for test), in front of this a Load Balancer and in front of this Load Balancer I have Cloudfront also with cache disabled for test. This is my actual Rendora config:

target:
  url: http://localhost:8080 #This is the address for the React SPA Application, Fargate doesn't use container linkings
backend:
  url: http://localhost:8080 #This is the address for the React SPA Application, Fargate doesn't use container linkings
headless:
  waitAfterDOMLoad: 3000
  internal:
    url: http://localhost:9222
cache:
  type: none
debug: true
server:
  enable: true
filters:
  userAgent:
    defaultPolicy: blacklist
    exceptions:
      keywords:
        - googlebot
        - Yahoo! Slurp
        - bingbot
        - yandex
        - baiduspider
        - facebookexternalhit
        - twitterbot
        - rogerbot
        - linkedinbot
        - embedly
        - quora link preview
        - showyoubot
        - outbrain
        - pinterest/0.
        - developers.google.com/+/web/snippet
        - slackbot
        - vkShare
        - W3C_Validator
        - redditbot
        - Applebot
        - WhatsApp
        - flipboard
        - tumblr
        - bitlybot
        - SkypeUriPreview
        - nuzzel
        - Discordbot
        - Google Page Speed
        - Qwantify
        - pinterestbot
        - Bitrix link preview
        - XING-contenttabreceiver
        - Chrome-Lighthouse'
        - laboritbot

When I call the Rendora API /render it works like a charm, when I reach my page through a browser, it works also. But, when I try to curl using one of my defined bots, it returns 304 everytime. I noticed that in browser the initial call also returns 304, but render oks, and on the API of Rendora it also renders even returning 304.

Is there anything that am I doing wrong?

Thank u in advance.

Question: running rendora docker together with a docker nginx container

First of all kudos for this awesome project. It solves an actual paint point while working with SPAs.

I have a custom setup I am not able to make work and I am wondering if it is even possible.

The VPS looks like this:

A docker container built from a custom nginx image that serves the react files.

The custom nginx image has a custom ngnix.conf copied to /etc/nginx/nginx.conf and the react dist files copied to /var/www/html/myapp at build time.

docker run --name my-nginx-app -d --network my-network -p 80:80 my-custom-nginx-image

Everything works but when I try to force SSR.

Just running rendora and the chrome headless images do nothing although I am able to render the SSR'ed content through the API, when enabled, posting to /render

What am I doing wrong?

Support for "networkidle2"

Most SPAs will use async data and currently rendora only supports waitAfterDOMLoad: milliseconds.

Wait a fixed time is not good enough at most times. Is it possible to add an option like puppeteer's

await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});

Rendora cannot even render a "Hello-World" React Project

After following this tutorial:
https://hashnode.com/post/instantly-solving-seo-and-providing-ssr-for-modern-javascript-websites-independently-of-frontend-and-backend-stacks-cjpuy274b01br3zs1zr46awfz

I realised that Rendora seemed broken. No matter what I do, I cannot seem to connect to the port listened-to by Rendora, and therefore cannot get any SSR-ed content.

My Config:

listen:
port: 3001

backend:
url: http://127.0.0.1:3000

target:
url: http://127.0.0.1

filters:
userAgent:
defaultPolicy: whitelist

Example Project:
https://github.com/po-trottier/rendora-test
To run the project, start 2 terminal, in the first one write "npm start" in the second one write "docker-compose up". You will need docker-desktop and node installed.

Important Note:
I also tried to run it with a VueJS Project running on NGINX and got the same result.

Running rendora from docker does not work. docker: Error response from daemon: create ./CONFIG_FILE.yaml

Steps to repro:

Run the command from documentation
docker run --net=host -v ./CONFIG_FILE.yaml:/etc/rendora/config.yaml rendora/rendora

What I have tried:

  1. git clone repo && cd to config_examples && run with docker run --net=host -v ./CONFIG_FILE.yaml:/etc/rendora/config.yaml rendora/rendora
    Return value is
    docker: Error response from daemon: create ./CONFIG_FILE.yaml: "./CONFIG_FILE.yaml" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.
    See 'docker run --help'.

  2. git clone repo && cd to config_examples && docker run --net=host -v config.yml:/etc/rendora/config.yml rendora/rendora
    Return value is
    error: read /etc/rendora/config.yml: is a directory

  3. git clone repo && docker run --net=host --mount source=config_examples,target=/etc/rendora/ rendora/rendora error: Config File "config" Not Found in "[/rendora /etc/rendora]"

Docker 2.1.0.4
Engine 19.03.4
Channel stable

Support for forcing HTTP status code through HTML (for SPA)

Since, SPA handles 404 pages in the client side, it needs a mechanism to handle HTTP status code through HTML

For example, https://github.com/GoogleChrome/rendertron#status-codes provides below syntax to pass HTTP status code from HTML:

<meta name="render:status_code" content="??" />

FWIW, tagging active fork authors in case if they have better solution implemented in their fork. @PureLandFlying @plan-my-binge @muhammadmuhlas @mehdipourfar

Add sitemap.xml as paths example

XML files are HTML'ized by chrome headless. Which means that the result is not the original xml. It is a problem with sitemap.xml which need to stay in XML format (for google bot to index it). As this is a common issue I suggest to add this to configuration example:

filters:
    userAgent:
        defaultPolicy: blacklist
        exceptions:
            keywords:
                - bot
                - slurp
                - bing
                - crawler
                - baiduspider
    paths:
        defaultPolicy: whitelist
        exceptions:
            exact:
                - /sitemap.xml

Or eventually a warning some where in the documentation

How to set up rendora with Firebase hosting?

Hello,

Could you provide some guidance on how to set up rendora to work with a SPA (vue, angular, react, etc.) served from a static source such as firebase hosting or an AWS bucket?

Thanks,
Tom

DOMContentEventFired Recv: context deadline exceeded

Hi guys, I will like to know if there is someone who can help me with this issue.

I have a SPA page created with Angular (I also try a static Html file) but when I try to get the render HTML on the browser I got nothing.

I tried 3 different ways to test the page and I got these results:

  1. Browser: http://127.0.0.1:3001/ : Nothing on the browser, I do not get an error.

  2. curl --header "Content-Type: application/json" --data '{"uri": "/"}' -X POST 127.0.0.1:9242/render. I got {"error":"cdp.Page: DOMContentEventFired Recv: context deadline exceeded"}

  3. curl -v -A "google" http://127.0.0.1:3001/index.html I got this:

Trying 127.0.0.1...
TCP_NODELAY set
Connected to 127.0.0.1 (127.0.0.1) port 3001 (#0)
GET //index.html HTTP//1.1
Host: 127.0.0.1:3001
User-Agent: google
Accept: /*/

HTTP//1.1 503 Service Unavailable
Date: Wed, 06 Nov 2019 01:14:53 GMT
Content-Length: 0

Connection #0 to host 127.0.0.1 left intact
HTTP//1.1 503 Service Unavailable
Date: Wed, 06 Nov 2019 01:14:53 GMT
Content-Length: 0

Connection #0 to host 127.0.0.1 left intact

My app is hosted in port 8023 and when I try with the browser and curl everything work ok
Here I am going to put my files and commands:

  • Chrome
 docker run --tmpfs /tmp --net=host rendora/chrome-headless
Fontconfig warning: "/etc/fonts/fonts.conf", line 100: unknown element "blank"
[1106/012055.317903:ERROR:gpu_process_transport_factory.cc(967)] Lost UI shared context.

DevTools listening on ws://0.0.0.0:9222/devtools/browser/41d2732e-d369-4e29-80bb-f21032a6ae57
  • Rendora
~docker run --net=host -v ~/config.json:/etc/rendora/config.json rendora/rendorara
Configuration loaded
Connected to headless Chrome
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /metrics                  --> github.com/gin-gonic/gin.WrapH.func1 (2 handlers)
[GIN-debug] POST   /render                   --> main.APIRender (2 handlers)
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode) 
  • Config.json
{
	"backend": {
		"url": "http://127.0.0.1:8023"
	},
	"debug": true,
	"server": {
		"enable": true
	},
	"listen": {
		"port": 3001
	},
	"target": {
		"url": "http://127.0.0.1:8023"
	},
	"headless": {
		"waitAfterDOMLoad": 5000,
		"timeout": 5
	},
	"filters": {
		"userAgent": {
			"defaultPolicy": "whitelist"
		}
	}
}

I have also run this commands (follow ome intructions in other issues): curl --header "Content-Type: application/json" -X GET 127.0.0.1:9242/metrics and I got this:

# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0.000162951
go_gc_duration_seconds{quantile="0.25"} 0.000238887
go_gc_duration_seconds{quantile="0.5"} 0.000269361
go_gc_duration_seconds{quantile="0.75"} 0.002994253
go_gc_duration_seconds{quantile="1"} 0.003041415
go_gc_duration_seconds_sum 0.007446245
go_gc_duration_seconds_count 8
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 9
# HELP go_info Information about the Go environment.
# TYPE go_info gauge
go_info{version="go1.11.4"} 1
# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes 1.023784e+06
# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
# TYPE go_memstats_alloc_bytes_total counter
go_memstats_alloc_bytes_total 2.546352e+06
# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
# TYPE go_memstats_buck_hash_sys_bytes gauge
go_memstats_buck_hash_sys_bytes 1.444222e+06
# HELP go_memstats_frees_total Total number of frees.
# TYPE go_memstats_frees_total counter
go_memstats_frees_total 11565
# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started.
# TYPE go_memstats_gc_cpu_fraction gauge
go_memstats_gc_cpu_fraction 7.82608871501652e-06
# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
# TYPE go_memstats_gc_sys_bytes gauge
go_memstats_gc_sys_bytes 2.371584e+06
# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.
# TYPE go_memstats_heap_alloc_bytes gauge
go_memstats_heap_alloc_bytes 1.023784e+06
# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.
# TYPE go_memstats_heap_idle_bytes gauge
go_memstats_heap_idle_bytes 6.3668224e+07
# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
# TYPE go_memstats_heap_inuse_bytes gauge
go_memstats_heap_inuse_bytes 2.850816e+06
# HELP go_memstats_heap_objects Number of allocated objects.
# TYPE go_memstats_heap_objects gauge
go_memstats_heap_objects 4732
# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.
# TYPE go_memstats_heap_released_bytes gauge
go_memstats_heap_released_bytes 6.3668224e+07
# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.
# TYPE go_memstats_heap_sys_bytes gauge
go_memstats_heap_sys_bytes 6.651904e+07
# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.
# TYPE go_memstats_last_gc_time_seconds gauge
go_memstats_last_gc_time_seconds 1.5730034928940895e+09
# HELP go_memstats_lookups_total Total number of pointer lookups.
# TYPE go_memstats_lookups_total counter
go_memstats_lookups_total 0
# HELP go_memstats_mallocs_total Total number of mallocs.
# TYPE go_memstats_mallocs_total counter
go_memstats_mallocs_total 16297
# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.
# TYPE go_memstats_mcache_inuse_bytes gauge
go_memstats_mcache_inuse_bytes 6912
# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.
# TYPE go_memstats_mcache_sys_bytes gauge
go_memstats_mcache_sys_bytes 16384
# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.
# TYPE go_memstats_mspan_inuse_bytes gauge
go_memstats_mspan_inuse_bytes 48488
# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.
# TYPE go_memstats_mspan_sys_bytes gauge
go_memstats_mspan_sys_bytes 65536
# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.
# TYPE go_memstats_next_gc_bytes gauge
go_memstats_next_gc_bytes 4.194304e+06
# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.
# TYPE go_memstats_other_sys_bytes gauge
go_memstats_other_sys_bytes 1.277818e+06
# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.
# TYPE go_memstats_stack_inuse_bytes gauge
go_memstats_stack_inuse_bytes 589824
# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.
# TYPE go_memstats_stack_sys_bytes gauge
go_memstats_stack_sys_bytes 589824
# HELP go_memstats_sys_bytes Number of bytes obtained from system.
# TYPE go_memstats_sys_bytes gauge
go_memstats_sys_bytes 7.2284408e+07
# HELP go_threads Number of OS threads created.
# TYPE go_threads gauge
go_threads 10
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.67
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1.048576e+06
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 8
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 1.4688256e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.57300223184e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1.24878848e+08
# HELP process_virtual_memory_max_bytes Maximum amount of virtual memory available in bytes.
# TYPE process_virtual_memory_max_bytes gauge
process_virtual_memory_max_bytes -1
# HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served.
# TYPE promhttp_metric_handler_requests_in_flight gauge
promhttp_metric_handler_requests_in_flight 1
# HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code.
# TYPE promhttp_metric_handler_requests_total counter
promhttp_metric_handler_requests_total{code="200"} 0
promhttp_metric_handler_requests_total{code="500"} 0
promhttp_metric_handler_requests_total{code="503"} 0
# HELP rendora_latency_ssr SSR Latency
# TYPE rendora_latency_ssr histogram
rendora_latency_ssr_bucket{le="50"} 0
rendora_latency_ssr_bucket{le="100"} 0
rendora_latency_ssr_bucket{le="150"} 0
rendora_latency_ssr_bucket{le="200"} 0
rendora_latency_ssr_bucket{le="250"} 0
rendora_latency_ssr_bucket{le="300"} 0
rendora_latency_ssr_bucket{le="350"} 0
rendora_latency_ssr_bucket{le="400"} 0
rendora_latency_ssr_bucket{le="500"} 0
rendora_latency_ssr_bucket{le="+Inf"} 0
rendora_latency_ssr_sum 0
rendora_latency_ssr_count 0
# HELP rendora_requests_ssr SSR Requests
# TYPE rendora_requests_ssr counter
rendora_requests_ssr 0
# HELP rendora_requests_total Total Requests
# TYPE rendora_requests_total counter
rendora_requests_total 3

I have read all the documentation provided by rendora, I have read all the issues in github and try all possibilities based on comments (https://github.com/rendora/rendora/issues). That include some tutorials in other pages (https://hashnode.com/post/instantly-solving-seo-and-providing-ssr-for-modern-javascript-websites-independently-of-frontend-and-backend-stacks-cjpuy274b01br3zs1zr46awfz and another chinese page) but nothings is working, what can I do?

How to configure Rendora with Angular 8 app and Apache2

I can't understand how should I configure Rendora to use it in my case.
I have some domain e.g. mydomain.com
Currently I have my Angular 8 app running on my VPS server with configured Apache2 and mydomain.com
I need to configure and run Rendora for server side rendering for (mostly) Facebook scraper.
I can change configuration of my Apache and serve app on local address and port. Is target and backend url should be the same in that case?
But how to setup Rendora to listen on my domain address? I can't set value of Listen.Address to domain name because it requires ip address. Do I have to make some redirect in .htaccess for local address and port where Rendora is started? But then it would be like this:
User > Apache2 on mydomain.com ->redirects to Rendora on local address and port -> renders site which is served by Apache2 on local address and port
Is this correct?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.