google cloud platform host website, but only working for index.html - google-cloud-sdk

I would like to use google cloud platform to host my website (some files with only html and some files with php). But it only shows the index.html page without any images and all the link are not working. I think my app.yaml file is not correct.
Case background:
I am using google cloud sdk in my mac.
gcloud app deply (this is the command to deploy my website)
Here with app.yaml file:
runtime: php55
api_version: 1
handlers:
- url: /.*
script: index.html

You need to add static_dir or static_files elements to handlers in your app.yaml.
Using static_dir, for example:
runtime: php55
api_version: 1
handlers:
- url: /
script: index.html
- url: /images
static_dir: images

Related

App engine URL not found on server when there is a dot in the URL

I am using GCP App engine to host my Vue application. And in this application, I have a dynamic route defined as /imp/:id/:email/:type. In the email parameter I have a valid email with the format john#gmail.com. This type of request to the server is returning The requested URL /imp/****/john#gmail.com/gm was not found on this server. When I remove the . in the email the request is directed to the server correctly. My app.yaml is defined as follows:
runtime: nodejs14
service: frontend-app
handlers:
# Serve all static files with urls ending with a file extension
- url: /(.*\..+)$
static_files: dist/\1
upload: dist/(.*\..+)$
# catch all handler to index.html
- url: /.*
static_files: dist/index.html
upload: dist/index.html
I am using other workarounds like moving the email to a query parameter now but I would like to understand how I can fix this. Thank you,

GCP VueJS API URL resolving to base url not api url

I'm using Google App Engine to host a VueJS App, and I'm trying to get my app to talk to my backend API.
I'm using an ENV Variable to declare the path to my API, however when the request is placed in GCP the url defaults to https://example.com/undefined/api/resource when it should be https://api.example.com/api/resource and also not have undefined.
As i'm getting the undefined error i suspect App Engine is not able to supply the VUE_APP_API_URL to the front end.
How do I get my VueJS app to find and use the env variable in app engine and use the correct api url?
Front end URL is like example.com
API URL is like api.example.com
Accessing the variable with process.env.VUE_APP_API_URL
app.yaml
runtime: nodejs10
env_variables:
VUE_APP_API_URL: "https://api.example.com"
handlers:
- url: /(.*\..+)$
static_files: dist/\1
upload: dist/(.*\..+)$
- url: /.*
static_files: dist/index.html
upload: dist/index.html

VueJS router history mode with Traefik

I need to do rewrite a URL of my application like this: https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations
I'm using Traefik as a reverse proxy and Docker Compose.
Here is my raw configuration in Docker:
application:
build: ./domain.app
volumes:
- ./domain.app/dist:/app
networks:
- net
labels:
- "traefik.frontend.rule=Host:domain.me"
- "traefik.port=8081"
- "traefik.backend=domain.me"
- "traefik.frontend.entryPoints=http,https"
With that configuration:
https://domain.me is working
https://domain.me/anything returns 404
How can I fix this rewrite rule?
For vue.js router history mode you want to catch all Routes that do not point to a resource on the server and forward them to your index.html. For Example:
https://example.com --> /index.html
https://example.com/route/to/subsite --> /index.html
But you still want to be able to access resources that are on the server. E.g.:
https://example.com/path/to/kitten.jpg --> /path/to/kitten.jpg not /index.html
In order to do that you have to find a Backend Server supporting Catch-All Fallback. You can use the ones noted in the vue.js Guide (Apache, Nginx, Node, IIS)
Why can't I use traefik for this?
As stated above you still want to be able to serve static resources. But traefik is just a router. It does only has access to the information of the request, not to the information of the server. But in order to decide if to serve the index.html or the static resource you must have access to the resources.
You could route all the traffic to the index.html using Traefik's PathPrefixStripRegex:but this would result in serving index.html for every request, even if you would have wanted kitten.jpg.

Vue.js Router: history mode and AWS S3 (RoutingRules)

I have a Vue.js application up and running with Amazon S3 and Cloudflare.
When I open the index and browse to /dashboard, everything works fine. But when I open a route like dashboard directly in a new tab or refresh the page, I get the following error back from S3:
404 Not Found
Code: NoSuchKey
Message: The specified key does not exist.
Key: unternehmen
RequestId: 6514F8A1F4C29235
HostId: +BVrPLJSGdzSYogzWZ4GMBXkgkdSJWRVJVhcSs4EI/lmMUR422aCtCxpBGU6AMe5VkS1UbEn/Lc=
Just read that the problem is Vue.js history mode: https://router.vuejs.org/de/essentials/history-mode.html
I would like to solve the problem with a routing rule in my Amazon S3 Bucket. How would the Apache RewriteRule look for S3?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Tried the following but it does not work:
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<HostName>domain.com</HostName>
<ReplaceKeyWith>index.html</ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
If I do it like that I just get my Header and Footer rendered but nothing more.
Thank you!
I know this answer comes late but in case someone else is looking for another way to solve this in cloudfront, there's no need to create custom pages on s3 redirecting users when pages are not found. Instead of doing it, custom error responses can be created in cloudfront for the distribution.
This will always redirect to /index.html in case a file is not found and that will make the app route trigger.
If you use static hosting on AWS S3 and this is SPA app (React, Vue, Angular etc) you should set index.html as error page:
I'm hosting a static PWA made in Vue on S3 using "Static website hosting" and it works as expected.
What I did was quite simple - I've added this:
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<ReplaceKeyWith></ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
To the Properties of the S3 bucket. See image below:
For my S3 bucket, everytime you try to access a file that doesn't exist you will receive a 403 (forbidden) instead of a 404. That is why I've changed the HttpErrorCodeReturnedEquals to 403. I've also replaced the ReplaceKeyWith with an empty string as "index.html" as not triggering the correct route.
I hope it helps.
Cheers,
Alex
I think this problem has two components:
1.
If a request is made directly (outside of the Javascript App) to a sub path such as /jobs then S3 returns a 404, because the path/object doesn't exist. The simplest way to fix this is from within S3 itself, where you redirect all error pages back to index.html.
However this doesn't work from a CDN such as Cloudfront, and presumably Cloudflare.
A good trick is to use files inside S3 that redirect users like this:
jobs/ -> /index.html
jobs -> /index.html
For example if someone makes a request to site/ they will get the following html file:
"redirect":"<html><head><meta http-equiv=\"refresh\" content=\"0; url=http://example.com/site/index.html\" /></head>
<body>Redirecting to Home</body></html>"
Secondly...
If I do it like that I just get my Header and Footer rendered but
nothing more.
This is a problem I've had where the router-view doesn't initialise properly, even though the component that contains the router-view has loaded.
What I have done for now is redirect my router when the main "App" component is created:
created () {
console.log('route', this.$route.path)
this.$router.replace(this.$route.query.redirect || '/')
}
This has the added bonus of removing the index.html from your path (Which was put there by your new redirections) whilst forcing your router-view to render...
My #app component is the parent component, with a navbar, footer, and the router-view that renders all of the sub pages/components.
One way to make this work in with routing in history mode and without using CloudFront is to create the files that your URIs would point to. So let's say you use index.html as your entry point and have only one other page which you give path page2.html.
Then you should adapt your build and deploy process to do the following:
Build your source into a production distribution (E.g. using npm run build)
Make sure that for your router links you create a file per path that is a copy of the original file. In case of the example I mention it would be creating a copy of 'dist/index.html' to 'dist/page2.html'
Copy the dist folder contents to your S3 bucket
Note that the order of step 1 and 2 is important.
This can be easily done in a script that publishes your website.
I have just used this approach with the result I wanted; allowing refreshinag a page and opening links in a new tab.
Drawbacks I see is:
- overhead of storing the copies of the files
- have to make sure if you add a page not to forget to update your build and deploy scripts.
The selected answer (403 and 404) did not work for me.
It was only after I added a similar 400 rule did my VUE app function in history mode.
for anyone using an AWS SAM template:
CloudFront:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
...
CustomErrorResponses:
- ErrorCode: 404
ResponseCode: 200
ResponsePagePath: /index.html
- ErrorCode: 403
ResponseCode: 200
ResponsePagePath: /index.html
- ErrorCode: 400
ResponseCode: 200
ResponsePagePath: /index.html

myPage.com instead of mypage.com/WebContent

I have created my webpage in eclipse as Dynamic Web Project and uploaded the WebContent folder to the server (WebContent contains index.html js, imgs and css). When I call myPage.com, it works only with the url myPage.com/WebContent. Afterthat I have uploaded the content of the folder WebContent directory to the server root. Now when I call myPage.com, it display empty page. mypage.com/index.html display empty page too.
How to upload WebContent, sothat the index.html display woithout using WebContent in the url?
This can be achieved by:
Using URLRewrite. This thing changes URLs according to the patterns you configure. More to read: http://tomcat.apache.org/tomcat-8.0-doc/rewrite.html
Using redirects in the root folder - if someone requested the folder, it automatically sends you to another folder. This can be done by placing index.html in root folder containing: <meta http-equiv="refresh" content="0; url=http://mypage.com/WebContent" />;
Using Virtual Host - description for Tomcat 6.