I have this web app. Frontend is written with VueJS, backend with Django rest framework, and I am using MongoDB with docker volumes.
On the Home page of my web app, Frontend sends a GET request to backend on /api/skills
endpoint.
When I handle things locally, everything is fine. I dockerize the frontend, backend, MongoDB and they all talk to each other in the same Docker network.
This is looking nice on local development. The part that does the fetching looks like this.
fetchSkillData: function () {
const localUrl = "http://0.0.0.0:8000/api/skills";
axios
.get(localUrl)
.then((values) => {
values.data.forEach((data) => {
this.technologies.push(data);
this.hideSpinner();
});
})
.catch(console.error);
this.hideSpinner();
}
I am not getting a CORS issue or anything else.
However, on production, I have some issues.
This is the Dockerfile for frontend:
# build stage
FROM node:13-alpine as build-stage
RUN mkdir -p /home/app
COPY ./frontend /home/app
WORKDIR /home/app
RUN npm install
RUN npm install --save ant-design-vue
RUN npm install --save mavon-editor
RUN npm install --save axios
RUN npm install --save raw-loader
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /home/app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
This is the Dockerfile for backend:
FROM python:alpine
ENV MONGO_DB_USERNAME=admin \
MONGO_DB_PWD=password
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /home/app
COPY requirements.txt /home/app
# install requirements
RUN pip3 install -r /home/app/requirements.txt
COPY ./azure_website_backend /home/app
WORKDIR /home/app
EXPOSE 8000
CMD ["python","manage.py","runserver","0.0.0.0:8000","--settings=azure_website_backend.settings"]
And this is the app.yml file for Docker compose:
version: "3"
services:
vue-frontend:
image: burakhanaksoy/vue-frontend:1.0
ports:
- 8080:8080
django-backend:
image: burakhanaksoy/django-backend:1.0
ports:
- 8000:8000
mongodb:
image: mongo
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express
ports:
- 8081:8081
depends_on:
- mongodb
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=password
- ME_CONFIG_MONGODB_SERVER=mongodb
volumes:
mongo-data:
driver: local
When I deploy it on Azure, frontend cannot talk to backend, the same api endpoint has this issue now
I added a CORS middleware on django. So I don't think this issue is related to CORS.
I think the issue stems from me still sending a request to 0.0.0.0
. Probably the IP is dynamically changing but I am still sending a request to 0.0.0.0
. But I don't know how to fix this. I looked lots and lots of documents and others' questions but I am very novice on deployment so I couldn't figure it out. I appreciate any help.
Also, I know that I shouldn't send to 0.0.0.0
because Azure logs always show a different host port everytime I deploy.
Update
I am trying to integrate nginx with vuejs to make use of proxy_pass
.
This is how my dockerfile looks like for Vue
# build stage
FROM node:13-alpine as build-stage
RUN mkdir -p /home/app
COPY . /home/app
WORKDIR /home/app
RUN npm install
RUN npm install --save ant-design-vue
RUN npm install --save mavon-editor
RUN npm install --save axios
RUN npm install --save raw-loader
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /home/app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
And this is nginx.conf
:
events { }
http{
server {
listen 80;
server_name localhost;
location / {
root path/to/vue.js/Project;
index index.html index.htm;
include /etc/nginx/mime.types;
proxy_pass http://localhost:8080/;
}
}
}
When I build image and run this container. I get 500 Internal Server Error from nginx. This means I integrated nginx but did not configured it properly?
This is what I get
Update 2
Nginx logs the following error on Docker Desktop
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/11/13 10:38:20 [error] 32#32: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "0.0.0.0:8080"
2021/11/13 10:38:20 [error] 32#32: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8080/favicon.ico", host: "0.0.0.0:8080", referrer: "http://0.0.0.0:8080/"
2021/11/13 10:39:11 [error] 32#32: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "0.0.0.0:8080"
2021/11/13 10:39:13 [error] 24#24: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "0.0.0.0:8080"
2021/11/13 10:39:13 [error] 24#24: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8080/favicon.ico", host: "0.0.0.0:8080", referrer: "http://0.0.0.0:8080/"
2021/11/13 10:40:29 [error] 25#25: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "0.0.0.0:8080"
2021/11/13 10:40:29 [error] 25#25: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8080/favicon.ico", host: "0.0.0.0:8080", referrer: "http://0.0.0.0:8080/"
CodePudding user response:
Try this:
fetchSkillData: function () {
const localUrl = "/api/skills";
axios
.get(localUrl)
.then((values) => {
values.data.forEach((data) => {
this.technologies.push(data);
this.hideSpinner();
});
})
.catch(console.error);
this.hideSpinner();
}
Or this:
async fetchSkillData(){
try {
const resp = await axios.get('/api/skills');
console.log(resp.data);
} catch (err) {
// Handle Error Here
console.error(err);
}
}
CodePudding user response:
If you deploy on Azure
you will have another hostname then when you deploy locally. Appearently you port to 0.0.0.0 locally, but when you deploy a docker container on Azure it will not do anything unless you also configured a Virtual Machine or AKS. That depends on your setup.
Virtual machines
Your Virtual Machine will have a custom hostname which will be the same as your Virtual Machine.
AKS
If you configured AKS you must create a deployment where you link to your docker container to spin up some replica's. More about deployments on K8s docs. Once you did a deployment you need a service to expose your deployment outside the cluster. You can use a variety of services, but usually yoiu have to configure ClusterIP
and Ingress. The hostname of your deployment equals themetdata.name
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-custom-host-name
Vue app
To use environment variables with Vue3 you have to pass those before you build your front-end. Those environment variables will be interpolated in your code via: process.env.VUE_APP_BACKEND_BASE_URL
. For Vue3 you must prefix environment variables with VUE_APP_
or use a .env
file. So add the following env before you run your build script in the pipeline:
VUE_APP_BACKEND_BASE_URL=http://[BACKEND_HOST]:8000 npm run build
Docker compose
In docker-compose
you have to set the env var as well and rebuild the application using docker-compose up
or docker compose up
. Please note the hostname
in docker compose is the name of your service.
version: "3.8"
services:
vue-frontend:
image: burakhanaksoy/vue-frontend:1.0
ports:
- 8080:8080
environment:
- VUE_APP_BACKEND_BASE_URL=django-backend:8000
django-backend:
image: burakhanaksoy/django-backend:1.0
ports:
- 8000:8000
mongodb:
image: mongo
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express
ports:
- 8081:8081
depends_on:
- mongodb
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=password
- ME_CONFIG_MONGODB_SERVER=mongodb
volumes:
mongo-data:
driver: local