Issues with Angular + Spring Boot + PostgreSQL App on GitPod

Hi,

I am trying to run an Angular + Spring Boot + PostgreSQL App in Gitpod.

The app consists of 3-tiers - the front-end Angular app, the back-end Spring Boot API, and lastly a PostgreSQL database.

The app works fine on the local host.

.gitpod.Dockerfile

FROM gitpod/workspace-postgres

#Install Angular CLI and JDK 1.8
RUN npm install -g @angular/cli@8.3.29

RUN bash -c “. /home/gitpod/.sdkman/bin/sdkman-init.sh
&& sdk install java 8.0.275.hs-adpt”

.gitpod.yml file

image:
file: .gitpod.Dockerfile

#exposed back-end API port
ports:
-port: 5555

Back-end Spring Boot API

The back-end Spring Boot API needs SSL because we store certain information in secure cookies. Therefore SSL is enabled with a self-signed certificate.

CORS is enabled and we correctly set up a CORS Filter (see below). CSRF has been disabled.

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
//.ignoringAntMatchers("/auth", “/auth/logout”)
//.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
//.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(
“/auth”,
“/reporting/viewResource/",
"/register/
”,
“/password/forgot”,
“/password/reset”,
“/v2/api-docs”,
“/actuator/",
“/configuration/ui”,
“/swagger-resources”,
“/configuration/security”,
"/v3/api-docs/
”,
“/swagger-ui/",
“/swagger-ui.html”,
"/webjars/
”,
“/swagger-resources/configuration/ui”,
“/swagger-resources/configuration/security”,
“/browser/index.html#”,
“/browser/**”
)
.permitAll()
.antMatchers(HttpMethod.POST, REGISTER)
.permitAll()
.antMatchers(HttpMethod.POST, CONFIRM)
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager(), context, userRepository))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), context));
}

@Configuration
public class CorsConfig {

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("DELETE");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

}

The back-end compiles and runs fine on port 5555.

PostgreSQL Database

We are using gitpod/workspace-postgres as the image and therefore we already have a postgres database with gitpod user setup and this all works.

Front-end Angular app

We ran the front-end angular app using the following command:
ng serve --disable-host-check --host 0.0.0.0

The app UI comes up correctly, but we are unable to login to the application.

In summary

1. Back-end API CSRF is disabled
2. Back-end API SSL is enabled (we have to enable this or our app will not work)
3. The back-end is running fine on port 5555 using https
4. The front-end is running fine on port 4200 (default Angular port) and brining up with UI
5. The front-end Angular environment.ts file is as follows:*

export const environment = {
production: false,
apiUrl: ‘/api’,
};

6. The front-end proxy.config.json file is as follows:
{
“/api”: {
“target”: “http://5555-a1b757c0-92ba-4110-9fbd-d34e9e47466e.ws-us03.gitpod.io”,
“secure”: false,
“pathRewrite”: {
“^/api”: “”
},
“changeOrigin”: true
}

NOTE: We had to use http (instead of https) above because GitPod wraps http with https. If we use https, we get a different error that is as folBad Request

This combination of host and port requires TLS

Errors we get when we try to login (with the URL in proxy set to http)

Access to XMLHttpRequest at ‘https://5555-a1b757c0-92ba-4110-9fbd-d34e9e47466e.ws-us03.gitpod.io/login’ (redirected from ‘https://4200-a1b757c0-92ba-4110-9fbd-d34e9e47466e.ws-us03.gitpod.io/api/login’) from origin ‘https://4200-a1b757c0-92ba-4110-9fbd-d34e9e47466e.ws-us03.gitpod.io’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

GET https://5555-a1b757c0-92ba-4110-9fbd-d34e9e47466e.ws-us03.gitpod.io/login net::ERR_FAILED

Can you please help? Has anyone been able to successfully run a Angular/SpringBoot/DB app using GitPod?

Here is a link to the workspace snapshot: https://gitpod.io/#snapshot/73c6f655-8883-4a29-8d88-24dc7bfdbf26

Thank you.

Sunil

Hi @sunilkosuri!

I’m not exactly sure what the problem is here yet, but I’m happy to help as best I can.

Although I don’t know much about Angular, I’ve been able to make an Angular app work in Gitpod before: https://github.com/Chocobozzz/PeerTube (with a Node.js backend and PostgreSQL database). Maybe this can serve as a relevant example here.

Excellent that you’ve come this far! :raised_hands:

This should be fine.

This might be an issue, although I’m not sure yet.

It all depends on whether you need to provide access to the backend from outside the workspace or not:

  • In principle, all the services running in your workspace can talk to each other using localhost just like they would on your laptop (nothing special about Gitpod here, but they should indeed use localhost or 127.0.0.1 and not Gitpod proxy URLs)

  • However, if you need to expose the backend server to the outside (e.g. if your client app makes backend requests from the front-end), then Gitpod becomes special. This only works if your backend runs HTTP (no SSL), allowing the Gitpod proxy to wrap the unencrypted HTTP content (e.g. served on http://localhost:1234/hello/) inside an encrypted HTTPS connexion (e.g. served on a Gitpod proxy URL like https://1234-abcc123.gitpod.io/hello/). This doesn’t work if your backend already runs SSL, and it’s often a bit tricky to tell the backend it should use HTTP on localhost:1234 but the outside stuff should still use HTTPS on a different domain & port (Gitpod proxy URL).

I don’t fully remember, but I think Angular is able to help with this proxying by making your front-end server talk directly to the backend in the same container, while making your front-end client request everything (including backend stuff) from the same domain & port.

Here I notice a difference with the PeerTube example listed above, which seems to have apiUrl: '':

But since I don’t know what this does exactly, I’m not sure what’s needed in your case.

Here, the target URL looks very suspicious to me, because it contains a (temporary) workspace ID in it: You seem to have gotten workspace ID a1b757c0-92ba-4110-9fbd-d34e9e47466e when you wrote this, but if you commit this change then start a new workspace, the ID will be different and this might break your configuration.

Instead, you should whenever possible use localhost URLs, or relative URLs without a domain (e.g. just "/").

And if you really need a public absolute URL, you can get it programmatically in Gitpod by running gp url 5555 in your workspace (e.g. in a Terminal). You can then pass the value to you app via an environment variable (e.g. GITPOD_URL=$(gp url 5555) ./start-my-app.sh) or a CLI argument (e.g. ./start-my-app.sh --gitpod-url=$(gp url 5555)).

As a comparison, here is PeerTube’s proxy.config.json that seems to use localhost in their target URL:

Interesting. Have you tried to make your servers add a Access-Control-Allow-Origin HTTP header in their responses? For example, you could set it to always send:

Access-Control-Allow-Origin: *

This could disable CORS policy checks for your development servers, and thus get rid of the error.

Many thanks for providing a snapshot! :100: That’s very helpful.

As an extra step to help troubleshoot your problem, could you please configure a tasks section in your .gitpod.yml? This can make Gitpod start all the relevant commands when the workspace starts, e.g.:

tasks:
  - name: Backend
    command: cd example && # ???
  - name: Frontend
    command: cd exampleClient && ng serve --disable-host-check --host 0.0.0.0

(Note: You’d have to replace the # ??? with the actual command required to start the backend server – as I’m not too familiar with Maven and/or Spring Boot I couldn’t guess it.)

1 Like