I am trying to migrate my python changes to my docker project, however when I try to run the command python manage.py db migrate I get the error unknown database 'main', however when I look inside of my docker-compose.yml file I see that main is indeed defined inside of the MYSQL_DATABASE variable inside of the container db. I have tried some solutions found on StackOverflow as well as Github like getting the restart: always out of my docker-compose.yml script and making a Windows PowerShell script that will run to restart my docker container as found here: MYSQL Docker container gives "unknown database" error, and trying to change my DATA_SAVE_PATH variable and other such variables in my docker-compose.yml: https://github.com/laradock/laradock/issues/1017 and I have also tried to change the MYSQL_DATABASE variable to a different name but that doesn't work either.
Here is the full error that I am receiving when I run my code:
sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1049, "Unknown database 'main'")
(Background on this error at: http://sqlalche.me/e/13/e3q8)
Here is my docker-compose.yml script:
version: '3.9'
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- 8001:5000
volumes:
- .:/app
depends_on:
- db
db:
image: mysql:5.7.22
restart: always
environment:
MYSQL_DATABASE: main
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
volumes:
- .dbdata:/var/lib/mysql
ports:
- 33067:3306
Here is my Dockerfile:
FROM python:3.9
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app
CMD python main.py
Here is my main.py file:
from flask_cors import CORS
from sqlalchemy import UniqueConstraint
from vegaaimain.vegamain import main
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = 'mysql://root:root#db/main'
CORS(app)
db = SQLAlchemy(app)
class VegaScriptRun(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=False)
title = db.Column(db.String(200))
description = db.Column(db.String(400))
image = db.Column(db.String(200))
main()
class VegaScriptUser(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer)
title = db.Column(db.String(200))
description = db.Column(db.String(400))
image = db.Column(db.String(200))
UniqueConstraint('user_id', 'title', 'description', 'image', name='user_experiment_unique')
#app.route('/')
def index():
return 'Hello'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
And finally my manage.py file, and requirements.txt file:
from main import app, db
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
requirements.txt
Flask==1.1.2
Flask-SQLAlchemy==2.4.4
SQLAlchemy==1.3.20
Flask-Migrate==3.0.0
Flask-Script==2.0.6
Flask-Cors==3.0.9
requests==2.25.0
mysqlclient==2.0.1
pika==1.1.0
wolframalpha==5.0.0
What exactly am I missing or doing wrong here, thank you!
I solved this problem by looking in my .dbdata folder and found my service, I then changed the MYSQL_DATABASE variable and the app configuration to the same variable as MYSQL_DATABASE which was vegatest instead of main.
So I ran the same command python manager.py db migrate and I got a successful migration.
Related
I am attempting to build a bridge between my flask application and my database using two separate containers rather than the mysql connector.
I am using flask_mysqldb for my app.
---docker-compose
App
|
|--app.py
|--dockerfile
db
|
|--dockerfile
|--db.sql
This is My Docker-compose file
version: '2'
services:
pythonapp:
build: ./NewtestPythonProject
command: sh -c "sleep 10s ; python3 ./main.py"
ports:
- '5000:5000'
depends_on:
- mysql
mysql:
build: ./MyDbDockerFile
restart: always
environment:
MYSQL_DATABASE: 'profile'
MYSQL_ROOT_PASSWORD: '1234'
ports:
- '3306:3306'
This is my Database Dockerfile
FROM mysql:latest
COPY ./dcs.sql /docker-entrypoint-initdb.d/
This is my app dockerfile
FROM python:3.9
WORKDIR /usr/app/src
COPY . /usr/app/src/
RUN pip3 install -r requirements.txt
EXPOSE 5000
This is My Connection String
from flask import *
from flask_mysqldb import MySQL
import yaml,re
import MySQLdb.cursors
from passlib.hash import pbkdf2_sha256
app = Flask(__name__)
app.secret_key = 'This'
#-----------------------------database connection-----------
db = yaml.load(open("db.yaml"),Loader=yaml.FullLoader)
app.config["MYSQL_HOST"] = db['mysql_host']
app.config["MYSQL_USER"] = db['mysql_user']
app.config["MYSQL_PASSWORD"] = db['mysql_password']
app.config["MYSQL_DB"] = db['mysql_db']
MySQL = MySQL(app)
Db.yaml
mysql_host: "localhost"
mysql_user: "root"
mysql_password: "1234"
mysql_db: "profile"
Change in Db.yaml the line mysql_host: "localhost" to mysql_host: "mysql" because the localhost is the same container.
This question already has answers here:
Deploying a minimal flask app in docker - server connection issues
(8 answers)
Closed 2 years ago.
I have simple flask app which uses SQLLite database.
Here is my app.py code
from flask import Flask
from flask_restful import Api
from flask_jwt import JWT
from datetime import timedelta
from db import db
from security import authenticate, identity
from resources.user import UserRegister
from resources.product import Product, ProductList
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = '#hsgvTyb#3gd###123'
api = Api(app)
#app.before_first_request
def create_tables():
db.create_all()
jwt = JWT(app, authenticate, identity) # /auth
app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds=1800)
api.add_resource(Product, '/product/<string:name>')
api.add_resource(ProductList, '/products')
api.add_resource(UserRegister, '/register')
if __name__ == '__main__':
db.init_app(app)
app.run(port=5000, debug=False)
DockerFile as below:
FROM python:3
ADD app/ /app
WORKDIR /app
RUN apt-get update
RUN pip install -r requirements.txt
CMD python app.py
docker-compose.yml as below:
version: "2"
services:
app:
container_name: test-146957-app
build:
context: ../
dockerfile: deployments/app/Dockerfile
ports:
- "5000:5000"
Now when I execute docker-compose up command it is showing container is running but I hit any endpoints from postman, it does not return any response.
You have to add host=0.0.0.0 as Flask run parameter. See the documentation for details: https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.run
So, I've got this flask app that works fine when I run it via the terminal, but for some reason, if I start up a docker container, it instantly exits with 'exit code zero'.
Here is the folder structure:
https://imgur.com/a/BOGCt6S
docker-compose.yml:
version: '3.2'
services:
flask-app:
build: ./Flask_App
volumes:
- ./Flask_App/static:/Flask_App/static
- ./Flask_App/db:/Flask_App/db
ports:
- '5001:5001'
# restart: unless-stopped
Dockerfile:
FROM python:3
# Setup env
COPY requirements.txt ./
RUN pip install -r requirements.txt
# Setup App
RUN mkdir -p /Flask_App
COPY . /Flask_App
WORKDIR /Flask_App
EXPOSE 5001
ENTRYPOINT [ 'python3' ]
CMD [ 'app.py' ]
and the app.py file: (I know its just imports, but it works fine when I run it via the terminal on the host, so it probably is working ok)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_bootstrap import Bootstrap
from forms import *
app = Flask(__name__)
app.config.from_pyfile('config.py')
Bootstrap(app)
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
from views import *
if __name__ == '__main__':
app.run(host=app.config['HOST'], port=app.config['PORT'], debug=app.config['DEBUG'])
and just in case, here is a part of the 'config.py' file:
DEBUG = False
HOST = '0.0.0.0'
PORT = 5001
As said by David Maze in a comment, the single quotes(') I used in ENTRYPOINT and CMD should be changed to double quotes ("), since they are supposed to be JSON arrays.
I'm trying to get gunicorn working with nginx in a docker compose file. My python code is just a flask CRUD app.
The entry point for my flask app is at ./flask_app/app.py and I've got the following for a docker compose yaml file
version: '3'
services:
flask_app:
container_name: flask_app
restart: always
build: ./flask_app
ports:
- "8000:8000"
command: gunicorn -w 1 -b :8000 app:server
nginx:
container_name: nginx
restart: always
build: ./nginx
ports:
- "80:80"
depends_on:
- flask_app
and here's my app file
from flask import Flask
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_pyfile('config.py')
db = SQLAlchemy(app)
ma = Marshmallow(app)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=6000, debug=True)
However when I run the above I'm getting the following error
Recreating ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_flask_app ... error
ERROR: for ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_flask_app Cannot start service flask_app: OCI runtime create failed: container_linux.go:296: starting container process caused "exec: \"gunicorn\": executable file not found in $PATH": unknown
ERROR: for flask_app Cannot start service flask_app: OCI runtime create failed: container_linux.go:296: starting container process caused "exec: \"gunicorn\": executable file not found in $PATH": unknown
ERROR: Encountered errors while bringing up the project.
As far as I can tell it doesn't seem my app = Flask(__name__) variable and I'm not sure why. I'm basing my approach on this working example https://github.com/sladkovm/docker-flask-gunicorn-nginx.
Does anyone have any ideas?
EDIT: In my flask_app directory I have a Dockerfile that the docker_compose file is pointing to. Here is what it looks like:
FROM python:3.6.2
RUN mkdir -p /flask_app/app
WORKDIR /flask_app/app
COPY . /flask_app/app
RUN pip install --no-cache-dir -r requirements.txt
COPY . /flask_app/app
This may not be the solution for the original poster's problem, but in case anyone else new to docker is on this page searching for a solution, maybe this will help.
If you're building with docker-compose, remember that docker-compose up doesn't actually rebuild images (https://github.com/docker/compose/issues/1487), so perhaps your old requirements file without gunicorn is still being used.
To fix this, rebuild with docker-compose build and you should be fine.
Hopefully this helped someone.
try
pip install gunicorn
pip freeze > requirements.txt
and then
docker-compose build
docker-compose up -d
enjoy
When trying to build the image, i'm getting the error below. I am also adding the related project files.
Dockerfile
docker-compose.yml
init.py
manage.py
Error:
Building users-service
Step 1/7 : FROM python:3.6.1
ERROR: Service 'users-service' failed to build: Get https://registry-1.docker.io/v2/: dial tcp 52.206.156.207:443: getsockopt: connection refused
Here is my Dockerfile
FROM python:3.6.1
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ADD ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
ADD . /usr/src/app
CMD python manage.py runserver -h 0.0.0.0
Here is the docker-compose.yml
version: '2.1'
services:
users-service:
container_name: users-service
build: .
volumes:
- '.:/usr/src/app'
ports:
- 5001:5000 # expose ports - HOST:CONTAINER
init.py
from flask import Flask, jsonify
# instantiate the app
app = Flask(__name__)
# set config
app.config.from_object('project.config.DevelopmentConfig')
#app.route('/ping', methods=['GET'])
def ping_pong():
return jsonify({'status': 'success',
'message': "pong"})
manage.py
from flask_script import Manager
from project import app
# configure your app
manager = Manager(app)
if __name__ == '__main__':
manager.run()