Implement Docker containerisation (#18)
* Begin initialising User backend Basket will be contained within the User class, perhaps.... * Resolve compile-time error * Complete minimal implementation * Create build and compose file * Make docker build more modular * IT RUNS Now to actually write unit tests * Attempt to debug docker file Currently works correctly when built individually, but docker-compose currently fails * Project broken into multipel Dockerfiles Docker Compose issues have been resolved in the given mount points in both compose files. User.java modified enough to resolve build error. * Add comments to proxy compose * Start unit testing * Finish implementing unit testing * Make build stable for both Docker and localhost * Incremental update Got past proxy errors, now to fix domain names * Resolve naming convention
This commit is contained in:
parent
12a4052582
commit
805f676321
21 changed files with 306 additions and 33 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
|||
docs/.settings
|
||||
docs/.project
|
||||
docs/.classpath
|
||||
backend-storage/
|
||||
|
|
21
README.md
21
README.md
|
@ -14,19 +14,38 @@ An online U-Fund system built in Java 17=> and ___ _replace with other platform
|
|||
|
||||
## Prerequisites
|
||||
|
||||
- Java 11=>17 (Make sure to have correct `JAVA_HOME` setup in your environment)
|
||||
### Bare-metal configuration
|
||||
- Java >=17 (Make sure to have correct `JAVA_HOME` setup in your environment)
|
||||
- Maven
|
||||
- NodeJS/`npm` >= 18
|
||||
- Angular >=16
|
||||
|
||||
### Docker configuration
|
||||
- Docker >=20
|
||||
- Docker Compose >= 2.0
|
||||
- Docker Compose may work properly on older versions, but that is not supported at this time
|
||||
|
||||
|
||||
## How to run it
|
||||
|
||||
### Bare-metal Configuration
|
||||
|
||||
1. Clone the repository and go to the `ufund-api` directory.
|
||||
2. Execute `mvn compile exec:java` in the terminal.
|
||||
3. Move to the `ufund-ui` directory.
|
||||
4. Execute `npm install && ng serve` in the terminal.
|
||||
5. Open your browser and navigate to http://localhost:4200
|
||||
|
||||
### Container Configuration
|
||||
In addition to the traditional stack, this project can also be run and/or deployed with a Docker containerization as well.
|
||||
|
||||
To start the service, simply run `docker compose up -d` in the root of this repository to start your containers.
|
||||
|
||||
To access the new service, open your browser and navigate to http://localhost:8080.
|
||||
|
||||
For security purposes, it is recommended that this be put behind a reverse proxy such as NginxProxyManager or Caddy. A simple Caddy example has been provided within `docker-compose.proxy.yml`. Note that your domain and email must both be specified to proxy to a public-facing URL.
|
||||
|
||||
|
||||
## Known bugs and disclaimers
|
||||
(It may be the case that your implementation is not perfect.)
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
[]
|
59
docker-compose.proxy.yml
Normal file
59
docker-compose.proxy.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Docker-compose version
|
||||
version: "3.8"
|
||||
|
||||
# By default, all services in the same docker compose file
|
||||
# are on the same internal network. This means inter-container
|
||||
# discovery and communication is contained to the device, and
|
||||
# is relatively safe.
|
||||
|
||||
services:
|
||||
#Backend container declaration
|
||||
backend:
|
||||
image: backend
|
||||
container_name: ufund_backend
|
||||
#Use Dockerfile, but only build the backend
|
||||
build: ./ufund-api
|
||||
#Tell Docker daemon to auto-start service on boot, unless manually stopped
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./backend-storage:/app/data
|
||||
|
||||
#Front-end container declaration
|
||||
frontend:
|
||||
container_name: ufund_frontend
|
||||
#Use Dockerfile, but build the frontend
|
||||
build:
|
||||
context: ./ufund-ui
|
||||
# Tell the backend where the frontend is
|
||||
args:
|
||||
BACKEND_API_PORT: 8080
|
||||
BACKEND_API_URL: ufund_backend
|
||||
#Tell Docker daemon to auto-start service on boot, unless manually stopped
|
||||
restart: unless-stopped
|
||||
# Caddy labels
|
||||
labels:
|
||||
# Domain name you want to host at
|
||||
caddy: localhost
|
||||
# Specifies which port in this container needs to be proxied
|
||||
caddy.reverse_proxy: "{{upstreams 80}}"
|
||||
|
||||
#Reverse Proxy container declaration
|
||||
caddy:
|
||||
#Caddy is a commonly used HTTPS reverse proxy
|
||||
image: docker.io/lucaslorentz/caddy-docker-proxy:2.8.9
|
||||
#Both HTTP and HTTPS ports need to be publicly exposed
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
#To allow for quick and convenient setup, Caddy requires access to the Docker socket
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
#Start caddy on reboot
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
# REPLACE THIS EMAIL
|
||||
# This is the email provided to LetsEncrypt, to which you will be sent an email
|
||||
# when your HTTPS certificate is bound to expire.
|
||||
caddy.email: your-email-here@example.com
|
||||
|
||||
|
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Docker-compose version
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
#Backend container declaration
|
||||
backend:
|
||||
image: backend
|
||||
container_name: ufund-backend
|
||||
#Use Dockerfile, but only build the backend
|
||||
build: ./ufund-api
|
||||
#Tell Docker daemon to auto-start service on boot, unless manually stopped
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./backend-storage:/app/data
|
||||
#Front-end container declaration
|
||||
frontend:
|
||||
container_name: ufund_frontend
|
||||
#Use Dockerfile, but build the frontend
|
||||
build:
|
||||
context: ./ufund-ui
|
||||
args:
|
||||
BACKEND_API_URL: "ufund-backend"
|
||||
BACKEND_API_PORT: "8080"
|
||||
#Tell Docker daemon to auto-start service on boot, unless manually stopped
|
||||
restart: unless-stopped
|
||||
#Expose Nginx port to a unique port
|
||||
ports:
|
||||
# Outbound port: 8080
|
||||
# Container port: 80
|
||||
- "8080:80"
|
33
ufund-api/Dockerfile
Normal file
33
ufund-api/Dockerfile
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Backend is built using Maven
|
||||
FROM maven:3.9.5 as backend-build
|
||||
#FROM maven:3.9.5
|
||||
# Specify the working directory within the build docker container
|
||||
WORKDIR /app
|
||||
#Copy the ufund-api folder in the current directory to the docker container
|
||||
COPY . /app/
|
||||
|
||||
# RUN ls -lah
|
||||
#
|
||||
# RUN mvn compile
|
||||
#
|
||||
# ENTRYPOINT ["mvn"]
|
||||
# CMD ["exec:java"]
|
||||
#Compile the project into a Java ARchive (.jar file)
|
||||
RUN mvn package
|
||||
|
||||
#OpenJDK containers are officially deprecated as per their overview page
|
||||
#Their dockerhub page suggests (among others) eclipse-temurin as an alternative
|
||||
#Using OpenJDK (or similar) as the base container results in smaller shipped container,
|
||||
#with lower attack surface
|
||||
FROM eclipse-temurin:17-jre
|
||||
#Set working directory in shipped container
|
||||
WORKDIR /app
|
||||
#Copy jar file from build container to the shipping container
|
||||
COPY --from=backend-build /app/target/ufund-api-3.0.0.jar /app/ufund-api-3.0.0.jar
|
||||
|
||||
RUN ls -lah /app
|
||||
#Open port 8080, to allow listening to REST communication
|
||||
EXPOSE 8080
|
||||
#Set runtime command to explicitly run the jar file
|
||||
ENTRYPOINT ["java"]
|
||||
CMD ["-jar", "/app/ufund-api-3.0.0.jar"]
|
34
ufund-ui/Dockerfile
Normal file
34
ufund-ui/Dockerfile
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Frontend is built using NodeJS
|
||||
FROM node:20.9.0 as frontend-build
|
||||
|
||||
# Docker Compose arguments
|
||||
ARG BACKEND_API_URL
|
||||
ARG BACKEND_API_PORT
|
||||
|
||||
#Explicitly set working directory in new docker container
|
||||
WORKDIR /app
|
||||
#Copy the frontend folder into the working directory
|
||||
COPY . /app/
|
||||
|
||||
#Modify environment file with set values
|
||||
RUN sed -i "s/localhost/$BACKEND_API_URL/g" /app/src/proxy.conf.mjs
|
||||
RUN sed -i "s/8080/$BACKEND_API_PORT/g" /app/src/proxy.conf.mjs
|
||||
|
||||
#Install all required NodeJS packages
|
||||
RUN npm install
|
||||
#Build NodeJS package (executes ng build)
|
||||
RUN npm run build #-- --configuration=docker
|
||||
|
||||
#Use Nginx as web server
|
||||
FROM nginx:1.25.3 as frontend
|
||||
#Copy the static files built by NodeJS into the Nginx server's proper location
|
||||
COPY --from=frontend-build /app/dist/ufund-ui /usr/share/nginx/html
|
||||
#Proxy out relevant parts of the URL
|
||||
COPY ./default.conf /etc/nginx/conf.d/default.conf
|
||||
ARG BACKEND_API_URL
|
||||
ARG BACKEND_API_PORT
|
||||
RUN sed -i "s/localhost:/$BACKEND_API_URL:/g" /etc/nginx/conf.d/default.conf
|
||||
RUN sed -i "s/8080/$BACKEND_API_PORT/g" /etc/nginx/conf.d/default.conf
|
||||
RUN cat /etc/nginx/conf.d/default.conf
|
||||
# Expose the HTTP port
|
||||
EXPOSE 80
|
|
@ -30,6 +30,8 @@
|
|||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"docker":{
|
||||
},
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
|
@ -58,12 +60,15 @@
|
|||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"proxyConfig": "src/proxy.conf.mjs",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "ufund-ui:build:production"
|
||||
"browserTarget": "ufund-ui:build:production",
|
||||
"proxyConfig": "src/proxy.conf.mjs"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "ufund-ui:build:development"
|
||||
"browserTarget": "ufund-ui:build:development",
|
||||
"proxyConfig": "src/proxy.conf.mjs"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
|
|
55
ufund-ui/default.conf
Normal file
55
ufund-ui/default.conf
Normal file
|
@ -0,0 +1,55 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
#access_log /var/log/nginx/host.access.log main;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location /users{
|
||||
proxy_pass http://localhost:8080;
|
||||
}
|
||||
location /cupboard{
|
||||
proxy_pass http://localhost:8080;
|
||||
}
|
||||
location /basket{
|
||||
proxy_pass http://localhost:8080;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
# redirect server error pages to the static page /50x.html
|
||||
#
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
|
||||
#
|
||||
#location ~ \.php$ {
|
||||
# proxy_pass http://127.0.0.1;
|
||||
#}
|
||||
|
||||
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
|
||||
#
|
||||
#location ~ \.php$ {
|
||||
# root html;
|
||||
# fastcgi_pass 127.0.0.1:9000;
|
||||
# fastcgi_index index.php;
|
||||
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
|
||||
# include fastcgi_params;
|
||||
#}
|
||||
|
||||
# deny access to .htaccess files, if Apache's document root
|
||||
# concurs with nginx's one
|
||||
#
|
||||
#location ~ /\.ht {
|
||||
# deny all;
|
||||
#}
|
||||
}
|
||||
|
15
ufund-ui/package-lock.json
generated
15
ufund-ui/package-lock.json
generated
|
@ -25,6 +25,7 @@
|
|||
"@angular/cli": "^16.2.6",
|
||||
"@angular/compiler-cli": "^16.2.0",
|
||||
"@types/jasmine": "~4.3.0",
|
||||
"@types/node": "^20.9.0",
|
||||
"jasmine-core": "~4.6.0",
|
||||
"karma": "~6.4.0",
|
||||
"karma-chrome-launcher": "~3.2.0",
|
||||
|
@ -3320,12 +3321,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz",
|
||||
"integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==",
|
||||
"version": "20.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz",
|
||||
"integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.25.1"
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
|
@ -11367,9 +11368,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.25.3",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/unicode-canonical-property-names-ecmascript": {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"@angular/cli": "^16.2.6",
|
||||
"@angular/compiler-cli": "^16.2.0",
|
||||
"@types/jasmine": "~4.3.0",
|
||||
"@types/node": "^20.9.0",
|
||||
"jasmine-core": "~4.6.0",
|
||||
"karma": "~6.4.0",
|
||||
"karma-chrome-launcher": "~3.2.0",
|
||||
|
|
19
ufund-ui/replace_environment_variables.js
Normal file
19
ufund-ui/replace_environment_variables.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
// https://dzone.com/articles/using-environment-variable-with-angular
|
||||
const fs = require("fs");
|
||||
|
||||
// this will get argument from command line
|
||||
let config = process.argv[2];
|
||||
|
||||
// read template file as string
|
||||
let template_environment = fs.readFileSync("./src/environments/environment.template.ts").toString();
|
||||
|
||||
// for every keys you have defined on environment this will loop over them and replace the values accordingly
|
||||
Object.keys(process.env).forEach(env_var => {
|
||||
template_environment = template_environment.replaceAll(`\${${env_var}}`,process.env[env_var])
|
||||
});
|
||||
|
||||
// if config is given use it on file name.
|
||||
if(config)
|
||||
fs.writeFileSync(`./src/environments/environment.${config}.ts`, template_environment);
|
||||
else
|
||||
fs.writeFileSync("./src/environments/environment.ts", template_environment);
|
|
@ -2,6 +2,7 @@ import { Component } from '@angular/core';
|
|||
|
||||
import { AccountService } from './services';
|
||||
import { User } from './models';
|
||||
import { environment } from '../environments/environment';
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
|
@ -14,6 +15,7 @@ export class AppComponent {
|
|||
|
||||
constructor(private accountService: AccountService){
|
||||
this.accountService.user.subscribe(x => this.user = x);
|
||||
//console.log(environment.apiUrl);
|
||||
}
|
||||
|
||||
logout(){
|
||||
|
|
|
@ -17,7 +17,7 @@ export class JwtInterceptor implements HttpInterceptor {
|
|||
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
const user = this.accountService.userValue;
|
||||
const isLoggedIn = user?.token;
|
||||
const isApiUrl = request.url.startsWith(environment.apiUrl);
|
||||
const isApiUrl = true;//request.url.startsWith(environment.apiUrl);
|
||||
if(isLoggedIn && isApiUrl){
|
||||
request = request.clone({
|
||||
setHeaders: { Authorization: `Bearer ${user.token}` }
|
||||
|
|
|
@ -24,7 +24,7 @@ export class AccountService {
|
|||
public get userValue(){ return this.userSubject.value; }
|
||||
|
||||
login(username: string, password: string){
|
||||
return this.http.post<User>(`${environment.apiUrl}/users/authenticate`, { username, password})
|
||||
return this.http.post<User>(`/users/authenticate`, { username, password})
|
||||
.pipe(map(user => {
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
this.userSubject.next(user);
|
||||
|
@ -39,21 +39,21 @@ export class AccountService {
|
|||
}
|
||||
|
||||
register(user: User){
|
||||
return this.http.post(`${environment.apiUrl}/users/register`,user);
|
||||
return this.http.post(`/users/register`,user);
|
||||
}
|
||||
getAll() {
|
||||
return this.http.get<User[]>(`${environment.apiUrl}/users`);
|
||||
return this.http.get<User[]>(`/users`);
|
||||
}
|
||||
|
||||
getById(id: string) {
|
||||
return this.http.get<User>(`${environment.apiUrl}/users/${id}`);
|
||||
return this.http.get<User>(`/users/${id}`);
|
||||
}
|
||||
|
||||
update(id: string, params: any) {
|
||||
return this.http.put(`${environment.apiUrl}/users/${id}`, params)
|
||||
return this.http.put(`/users/${id}`, params)
|
||||
.pipe(map(x => {
|
||||
// update stored user if the logged in user updated their own record
|
||||
if (id == this.userValue?.id) {
|
||||
if (id === this.userValue?.id) {
|
||||
// update local storage
|
||||
const user = { ...this.userValue, ...params };
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
|
@ -66,10 +66,10 @@ export class AccountService {
|
|||
}
|
||||
|
||||
delete(id: string) {
|
||||
return this.http.delete(`${environment.apiUrl}/users/${id}`)
|
||||
return this.http.delete(`/users/${id}`)
|
||||
.pipe(map(x => {
|
||||
// auto logout if the logged in user deleted their own record
|
||||
if (id == this.userValue?.id) {
|
||||
if (id === this.userValue?.id) {
|
||||
this.logout();
|
||||
}
|
||||
return x;
|
||||
|
|
|
@ -23,31 +23,31 @@ export class BasketService {
|
|||
) { }
|
||||
|
||||
getBasketNeeds() {
|
||||
let url = `${environment.apiUrl}/basket/${this.accountService.userValue?.id}`;
|
||||
let url = `/basket/${this.accountService.userValue?.id}`;
|
||||
console.log("GET " + url);
|
||||
return this.http.get<Needs[]>(url);
|
||||
}
|
||||
|
||||
addNeedToBasket(id: number) {
|
||||
let url = `${environment.apiUrl}/basket/${this.accountService.userValue?.id}`;
|
||||
let url = `/basket/${this.accountService.userValue?.id}`;
|
||||
console.log("POST " + url + " " + id);
|
||||
return this.http.post<Needs>(url, id, this.httpOptions).subscribe();
|
||||
}
|
||||
|
||||
removeNeedFromBasket(needID: number) {
|
||||
let url = `${environment.apiUrl}/basket/${this.accountService.userValue?.id}/${needID}`;
|
||||
let url = `/basket/${this.accountService.userValue?.id}/${needID}`;
|
||||
console.log("DELETE " + url);
|
||||
this.http.delete<Needs>(url).subscribe();
|
||||
}
|
||||
|
||||
getNeedFromBasket(needID: number) {
|
||||
let url = `${environment.apiUrl}/basket/${this.accountService.userValue?.id}/${needID}`;
|
||||
let url = `/basket/${this.accountService.userValue?.id}/${needID}`;
|
||||
console.log("GET " + url);
|
||||
return this.http.get<Needs>(url);
|
||||
}
|
||||
|
||||
checkout(needIDs: number[]) {
|
||||
let url = `${environment.apiUrl}/basket/${this.accountService.userValue?.id}/checkout`;
|
||||
let url = `/basket/${this.accountService.userValue?.id}/checkout`;
|
||||
console.log("POST " + url + " " + needIDs);
|
||||
this.http.post(url, needIDs, this.httpOptions).subscribe();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { HttpClient } from '@angular/common/http';
|
|||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { environment } from 'src/environments/environment';
|
||||
//import { environment } from 'src/environments/environment';
|
||||
import { Needs } from 'src/app/models';
|
||||
|
||||
@Injectable({
|
||||
|
@ -23,18 +23,18 @@ export class NeedsService {
|
|||
|
||||
public get needsValue() { return this.needsSubject.value; }
|
||||
register(needs: Needs) {
|
||||
return this.http.post(`${environment.apiUrl}/cupboard/need`, needs);
|
||||
return this.http.post(`/cupboard/need`, needs);
|
||||
}
|
||||
getAll() {
|
||||
return this.http.get<Needs[]>(`${environment.apiUrl}/cupboard/need`);
|
||||
return this.http.get<Needs[]>(`/cupboard/need`);
|
||||
}
|
||||
|
||||
getById(id: string) {
|
||||
return this.http.get<Needs>(`${environment.apiUrl}/cupboard/need/${id}`);
|
||||
return this.http.get<Needs>(`/cupboard/need/${id}`);
|
||||
}
|
||||
|
||||
update(id: number, params: any) {
|
||||
return this.http.put(`${environment.apiUrl}/cupboard/need/${id}`, params)
|
||||
return this.http.put(`/cupboard/need/${id}`, params)
|
||||
.pipe(map(x => {
|
||||
// update stored user if the logged in user updated their own record
|
||||
if (id == this.needsValue?.id) {
|
||||
|
@ -50,6 +50,6 @@ export class NeedsService {
|
|||
}
|
||||
|
||||
delete(id: number) {
|
||||
return this.http.delete(`${environment.apiUrl}/cupboard/need/${id}`)
|
||||
return this.http.delete(`/cupboard/need/${id}`)
|
||||
}
|
||||
}
|
||||
|
|
3
ufund-ui/src/environments/environment.docker.ts
Normal file
3
ufund-ui/src/environments/environment.docker.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const environment = {
|
||||
// apiUrl: "http://BACKEND_URL:BACKEND_PORT"
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
export const environment = {
|
||||
apiUrl: 'http://localhost:8080'
|
||||
apiUrl: '${BACKEND_URL}:${BACKEND_PORT}'
|
||||
}
|
||||
|
|
12
ufund-ui/src/proxy.conf.mjs
Normal file
12
ufund-ui/src/proxy.conf.mjs
Normal file
|
@ -0,0 +1,12 @@
|
|||
export default[
|
||||
{
|
||||
context: [
|
||||
"/users",
|
||||
"/cupboard",
|
||||
"/basket",
|
||||
],
|
||||
target: 'http://localhost:8080',
|
||||
secure: false,
|
||||
changeorigin: true,
|
||||
}
|
||||
];
|
|
@ -3,7 +3,7 @@
|
|||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/app",
|
||||
"types": []
|
||||
"types": ["node"]
|
||||
},
|
||||
"files": [
|
||||
"src/main.ts"
|
||||
|
|
Loading…
Add table
Reference in a new issue