Hello I want to containarize my flask app and my mongo annd connect them. I have already containerize the flask app.
my current code:
Dockerfile for flask container
FROM python:3.8-buster
WORKDIR /ergasiav3
ADD . /ergasiav3
RUN pip install -r requirements.txt
CMD ["python","app.py"]
I have a db.py with the connection to the mongoDB, here is the code:
from flask_pymongo import pymongo
CONNECTION_STRING = "mongodb+srv://admin:admin#cluster0.sqowy.mongodb.net/InfoCinemas?retryWrites=true&w=majority"
client = pymongo.MongoClient(CONNECTION_STRING)
db = client.get_database('InfoCinemas')
Users = pymongo.collection.Collection(db, 'Users')
Movies = pymongo.collection.Collection(db, 'Movies')
I also created this docker-compose.yml which seems to work but I dont know how to get the mongo as an image too.
version: '3'
services:
infocinemas:
build: .
volumes:
- ./ergasiav3
ports:
- 5000:5000
Do I need to make a second Dockerfile or do I just make the docker-compose.yml for the conterization of mongoDB?
Thank you in advance!
You don't need a separate mongo container, your data is in atlas.
https://www.mongodb.com/compatibility/docker
I also have this same question today as I have just started docker.
No need of separate container if you are using atlas
The information is located at the last of article
Related
So i made a flask web-service that connects to a mongodb , the web-service will be in a docker container and the mongodb will be in another container. When i run the web-service locally on my computer it connects to the mongodb container and everything works fine. When i have them in 2 separated containers as described before, i can use GET methods just fine but POST methods never works, every time i try to make a change in the db or insert something the programm just freezes for some seconds and then i get the timeout error image of the error. One of the endpoints of the web-service that has a problem is this (i will also add the beginning of the file so you can see the connection with the db ):
from flask import Flask, request, Response, jsonify
import json
from pymongo import MongoClient
from datetime import date
client = MongoClient("mongodb://localhost:27017")
db=client["DigitalNotes"]
users=db["Users"]
admins=db["Admins"]
notes=db["Notes"]
app=Flask(__name__)
#app.route("/sign_up",methods=["POST"])
def sign_up():
try:
data=json.loads(request.data)
except Exception as e:
return Response("Bad json content",status=500,mimetype='application/json')
if data==None:
return Response("Bad request",status=500,mimetype='application/json')
if not "email" in data or not "username" in data or not "name" in data or not "password" in data:
return Response("Information incompleted",status=500,mimetype='application/json')
if users.count_documents({"email":data["email"]})==0 or users.count_documents({"username":data["username"]})==0:
user = {"email":data["email"],"username":data["username"],"name":data["name"],"password":data["password"]}
users.insert_one(user)
return Response(data["username"]+" was added to the DataBase",status=200,mimetype='application/json')
else:
return Response("A user with the given username or password already exists",status=200,mimetype='application/json')
and the Dockerfile that creates the container is this:
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y python3 python3-pip
RUN pip3 install flask pymongo
RUN pip3 install datetime
RUN mkdir /app
COPY app.py /app/app.py
EXPOSE 5000
WORKDIR /app
ENTRYPOINT ["python3","-u","app.py"]
The container of the mongodb is created in an docker-compose file which is this:
version: '2'
services:
mongodb:
image: mongo
restart: always
container_name: mongodb
ports:
- 27017:27027
volumes:
- ./mongodb/data:/data/db
flask-service:
build:
context: ./flask-service
restart: always
container_name: flask
depends_on:
- mongodb
ports:
- 5000:5000
environment:
- "MONGO_HOSTNAME=mongodb"
I just don't understand why it works fine locally and not in the containers. Can anyone please help??
The connection string of MongoDb in flask container should be mongodb://mongodb:27017 because between containers you should specify the service name.
I am running FastApi via docker by creating a sevice called ingestion-data in docker-compose. My Dockerfile :
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
# Environment variable for directory containing our app
ENV APP /var/www/app
ENV PYTHONUNBUFFERED 1
# Define working directory
RUN mkdir -p $APP
WORKDIR $APP
COPY . $APP
# Install missing dependencies
RUN pip install -r requirements.txt
AND my docker-compose.yml file
version: '3.8'
services:
ingestion-service:
build:
context: ./app
dockerfile: Dockerfile
ports:
- "80:80"
volumes:
- .:/app
restart: always
I am not sure why this is not picking up any change automatically when I make any change in any endpoint of my application. I have to rebuild my images and container every time.
Quick answer: Yes :)
In the Dockerfile, you copying your app into /var/www/app.
The instructions form the Dockerfile are executed when you build your image (docker build -t <imgName>:<tag>)
If you change the code later on, how could the image be aware of that?
However, you can mount a volume(a directory) from your host machine, into the container when you execute the docker run / docker-compose up command, right under /var/www/app. You'll then be able to change the code in your local directory and the changes will automatically be seen in the container as well.
Perhaps you want to mount the current working directory(the one containing your app) at /var/www/app?
volumes:
- .:/var/www/app
I have two docker containers.
Flask app
MongoDB
Flask app has a DockerFile that looks like this.
from alpine:latest
RUN apk add --no-cache python3-dev \
&& pip3 install --upgrade pip
WORKDIR /app
COPY . /app
RUN pip3 --no-cache-dir install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python3"]
CMD ["app.py"]
This is how I am connecting my local Mongo (Not Container) from Flask
mongo_uri = "mongodb://host.docker.internal:27017/myDB"
appInstance.config["MONGO_URI"] = mongo_uri
mongo = PyMongo(appInstance)
MongoDB is running on the container in mongodb://0.0.0.0:2717/myDB.
This is obvious when I run Flask container with local mongo uri which is mongodb://host.docker.internal:27017/myDB, everything works. But It shouldn't work when I try to connect the Mongo Container in the same way. Coz Flask container doesn't know anything about that Mongo Container.
My question is - how do I connect this Mongo Container with Flask Container so that I can query Mongo container from Flask Container.
Thanks in advance.
If I was you, I would use docker-compose.
Solution just using docker
You'd have to find out the IP address of your mongo container and put this IP in the flask configuration file. Keep in mind that the IP address of the container can change - for example if you use a newer image.
Find IP address:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
Solution using docker-compose
In your docker-compose file you'd define two services - one for flask and one for mongo. In the flask configuration file you can then access the mongo container with its service name as both services run in the same network.
docker-compose.yml:
services:
mongo:
...
flask:
...
flask configuration:
mongo_uri = "mongodb://mongo/myDB"
In this example mongo is the name for your mongo service.
I have two containers "web" and "db". I have an existing data file in csv format.
The problem is I can initialize the MySQL database with a schema using docker-compose or just run with parameters but how can I import the existing data? I have Python script to parse and filter the data and then insert it to db but I cannot run it in the "db" container due to the single image is MySQL.
Update1
version: '3'
services:
web:
container_name: web
build: .
restart: always
links:
- db
ports:
- "5000:5000"
db:
image: mysql
container_name: db
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_DATABASE: "test"
MYSQL_USER: "test"
MYSQL_PASSWORD: "test"
MYSQL_ROOT_PASSWORD: "root"
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
ports:
- "33061:3306"
There is a Python script for read data from a csv file and insert them to database, which works fine. Now I want to running the script once the MySQL container is set up. (I have done connection with Python and MySQL in container)
Otherwise, anyone has a better solution to import existing data?
MySQL docker image has the ability to execute shell scripts or sql files if these script/sql files mounted under /docker-entrypoint-initdb.d for a running container as described in here and here. So I suggest you to write an SQL file that reads the CSV file (which you should mount to your container so the sql file can read it) in order to restore it to MySQL maybe something similar to this answer or write a bash script to import csv into mysql whatever works for you.
You can check Initializing a fresh instance at the official dockerhub page for mysql
From Dockerfile, you can call a script (Entrypoint). In this script you can call your python script. For example:
DockerFile:
FROM php:7.2-apache
RUN apt-get update
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
This will run your entrypoint script in the App container. Make sure you've depends on attribute in you app container compose description.
I have looked through the questions on this site, but I have not been able to fix this problem.
I created and ran an image of my django app, but when I try to view the app from the browser, the page does not load (can't establish a connection to the server)
I am using docker toolbox, I am using OS X El Capitan and the Macbook is from 2009.
The container IP is: 192.168.99.100
The django project root is called "Web app" and is the directory containing manage.py. My Dockerfile and my requirements.txt files are in this directory.
My dockerfile is:
FROM python:3.5
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
My requirements.txt has django and mysqlclient
My django app uses Mysql, and I tried to view the dockerized django app in the browser with and without linking it to the standard mysql image. In both cases, I only see the following error:
problem loading page couldn't establish connection to server
When I did try linking the django container to the mysql container I used:
docker run --link mysqlapp:mysql -d app
Where mysqlapp is my mysql image and 'app' is my django image.
In my django settings.py, the allowed hosts are:
ALLOWED_HOSTS: ['localhost', '127.0.0.1', '0.0.0.0', '192.168.99.100']
Again, the image is successfully created when I used docker build, and it is successfully run as a container. Why is the page not loading in the browser?
I suggest to use yml file and docker compose. Below is a template to get you started:
[Dockerfile]
FROM python:2.7
RUN pip install Django
RUN mkdir /code
WORKDIR /code
COPY code/ /code/
where your files are located in code directory.
[docker-compose.yml]
version: '2'
services:
db:
image: mysql
web0:
build: .
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
depends_on:
- db
There might be a problem with your working directory path defined in Dockerfile. Hope above helps.
Solution provided by salehinejad seems to be good enough ,although i have not tested it personally but if you do not want to use yml file and want to go your way then you should expose the port by adding
-p 0:8000
in your run command
So your should look like this :
docker run -p 0:8000 --link mysqlapp:mysql -d app
I suspect you have not told Docker to talk to your VM, and that your containers are running on your host machine (if you can access at localhost, this is the issue).
Please see this post for resolution:
Connect to docker container using IP