Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS fails when using Docker containers for frontend and backend

The following code is working great outside docker containers. Now I would like to add a container for the backend and another for the frondend. So I create two Dockerfiles (that are probably uninteresting) and the following docker-compose file. I change axios.get('http://127.0.0.1:5000/api/test') to axios.get('http://backend:80/api/test') in the vue component. I'm able to ping the backend container from the frontend container and I'm able to receive the api result via curl. But axios is not able to make this api request anymore. And in the firefox console I get the error:

Error: "Network Error"
Cross-Origin request blocked [...] Reason: CORS request did not succeed

But I'm able to run the backend outside docker at one computer in my network and the frontend at another. So Cross-Origin is no problem outside docker. What's the problem here? I have no idea.


docker-compose.yml

version: '2'
services:
    backend:
        build: ./backend
        container_name: backend
        ports:
          - "80:80"
        environment:
          - FLASK_APP=app/main.py
          - FLASK_DEBUG=1
          - 'RUN=flask run --host=0.0.0.0 --port=80'
        networks:
          - some-net

    frontend:
        build: ./frontend
        container_name: frontend
        ports:
          - "90:80"
        networks:
          - some-net

networks:
    some-net:
        driver: bridge

original code

backend in python

from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources=r'/api/*')

@app.route('/api/test')
def test():
    return jsonify({
        "foo": "bar"
    })

if __name__ == '__main__':
    app.run(debug=True)

frondend (only vue.js component)

<template>
<div class="hello">
    <h1>Message is: {{ msg }}</h1>
</div>
</template>

<script>
import axios from 'axios'

export default {
name: 'HelloWorld',
data () {
    return {
        msg: ''
    }
},
created () {
    axios.get('http://127.0.0.1:5000/api/test').then(response => {
        console.log(response.data)
        this.msg = response.data.foo
    }).catch(error => {
        console.log(error)
    })
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
like image 709
user2534685 Avatar asked Sep 03 '25 13:09

user2534685


1 Answers

It would seem that you are mistaking how to reference docker containers from outside all containers.

axios.get('http://127.0.0.1:5000/api/test')...

Should refer to where the docker container is listening. Inside a container, this would indeed be backend, but outside, i.e. in your web browser, it would be a reference to the host running the container, followed by the port. Since you've mounted it on port 80 on the host (and 90 for the frontend), you should update the get to :

axios.get('http://{hostname or ip}:80/api/test')

If it's all running on the same host, then you could use 127.0.0.1 or localhost for your testing.

like image 59
Neil Twist Avatar answered Sep 05 '25 01:09

Neil Twist