Error running project with docker compose - python

I'm doing a practice application to learn docker, I'm doing the application with Python and fast Api along with its tutorial, I'm using everything with dockerfile and docker compose, which has a connection to the postgresql database, for that I'm using a orm sqlalchemy, running my application 'normally' from the command line, the project runs without any problem, but when running it with docker compose it generates several errors like the following:
ModuleNotFoundError: No module named 'routers'
When I 'solve' it, it generates another error which I have not been able to solve and I do not understand which is the following:
ModuleNotFoundError: No module named 'sqlalchemy'
Well, if I have sqlalchemy install, requirements.txt:
SQLAlchemy==1.4.39
This is my Python code, this is the main one:
from fastapi import FastAPI
from .routers import roles
app = FastAPI()
app.include_router(roles.router)
And this is the code where the error is generated:
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from db.postgres_connection import SessionLocal, engine
from models import roles
from schemas import roles as schemas
roles.Base.metadata.create_all(bind=engine)
router = APIRouter()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
#router.get('/api/v1/roles/', response_model=list[schemas.RoleBase])
async def get_roles(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
roles = get_roles(db, skip=skip, limit=limit)
return roles
This is my Dockerfile:
FROM python:3.10.5-slim-buster
WORKDIR /code
COPY ./app ./code/app
COPY ./requirements.txt /code/
RUN pip install -r requirements.txt
EXPOSE 8000
CMD [ "uvicorn", "app.main:app", "--reload" ]
This is my docker compose file:
version: '3.9'
services:
web:
build: .
ports:
- '8000:8000'
volumes:
- .:/app
db:
image: postgres
restart: always
environment:
POSTGRES_USER: hamel
POSTGRES_PASSWORD: contrasena
POSTGRES_DB: bankmel
volumes:
- /home/isla/storage:/var/lib/postgresql/data
ports:
- '5432:5432'
structure folder:

you got a couple of problems
In the docker file change, your copy path code is creating one more directory under code.
COPY ./app ./app
then you will have a couple of other problems in your code.

Modify your Dockerfile as follows, I'm sure this error will be fixed:
FROM python:3.10.5-slim-buster
WORKDIR /code
COPY ./app ./app
COPY ./requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
EXPOSE 8000
CMD [ "uvicorn", "app.main:app", "--reload" ]
also in docker-compose.yml you should change volume in web as follows:
volumes:
- .:/code

Related

docker compose up raises ModuleNotFound

Trying to bring my fastAPI app together with docker compose. It works out of the docker but on docker it doesn't see my modules like endpoints and others. Not sure what Am doing wrong...
from endpoints import pizza_endpoints, order_endpoints
ModuleNotFoundError: No module named 'endpoints'
endpoints is folder with init and its imports are .py files
dockerfile:
FROM python:3.9-slim
COPY ./backend /backend
ENV PYTHONPATH "${PYTHONPATH}:/backend"
ENV PYTHONUNBUFFERED 1
WORKDIR /backend
EXPOSE 8000
RUN pip3 install -r requirements.txt
docker compose:
version: '3.9'
services:
backend:
build: .
command: bash -c 'while !</dev/tcp/db/5432; do sleep 1; done; uvicorn backend.main:app --host 0.0.0.0'
ports:
- 8008:8000
environment:
- DATABASE_URL=postgresql://postgres:postgres#db:5432/pypizza
depends_on:
- db
db:
image: postgres:13-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
expose:
- 5432
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=pypizza
volumes:
postgres_data:
main.py:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from endpoints import pizza_endpoints, order_endpoints
from dependency import database
from SQL import models
models.Base.metadata.create_all(database.engine)
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins = ["*"],
allow_credentials = True,
allow_methods = ["*"],
allow_headers = ["*"]
)
app.include_router(pizza_endpoints.router, prefix="/pizza")
app.include_router(order_endpoints.router, prefix="/order")
#app.get("/")
async def welcome_page():
return {"message": "hello"}

Changes on template files inside volume not showing on Flask frontend

I am using a docker-compose Flask implementation with the following configuration
docker-compose:
version: '3'
services:
dashboard:
build:
context: dashboard/
args:
APP_PORT: "8080"
container_name: dashboard
ports:
- "8080:8080"
restart: unless-stopped
environment:
APP_ENV: "prod"
APP_DEBUG: "False"
APP_PORT: "8080"
volumes:
- ./dashboard/:/usr/src/app
dashboard/Dockerfile:
FROM python:3.7-slim-bullseye
ENV PYTHONUNBUFFERED True
ARG APP_PORT
ENV APP_HOME /usr/src/app
WORKDIR $APP_HOME
COPY requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
CMD exec gunicorn --bind :$APP_PORT --workers 1 --threads 8 --timeout 0 main:app
dashboard/main.py:
import os
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
If I apply any change to the index.html file in my host system using VSCode, these changes won't apply when I refresh the page. However, I have tried getting into the container with docker exec -it dashboard bash and cat /usr/src/app/templates/index.html and they are reflected inside the container, since the volume is shared between the host and the container.
If I stop the container and run it again the changes are applied, but as I am working on frontend doing that all the time is pretty annoying.
Why the changes won't show on the browser but they are replicated on the container?
You should use: TEMPLATES_AUTO_RELOAD=True
From https://flask.palletsprojects.com/en/2.0.x/config/
It appears that the templates are preloaded and won't update until you enable this feature.

http://localhost/5000 not working in docker flask

can't open file '/web/manage.py': [Errno 2] No such file or directory
exited with code 2
NOTE: Tried all similar problems solution posted, did not work.
No matter what I do, not able to get http://localhost/5000 to work. Even if the above error goes away by removing volume and command from docker-container.
Below is docker-compose.yml
services:
web:
build: ./web
command: python /web/manage.py runserver 0.0.0.0:8000
volumes:
- './users:/usr/src/app'
ports:
- 5000:5000
env_file:
- ./.env.dev
Below is Dockerfile:
# pull official base image
FROM python:3.9.5-slim-buster
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
# copy project
COPY . /usr/src/app/
BELOW IS manage.py:
from flask.cli import FlaskGroup
from project import app
cli = FlaskGroup(app)
if __name__ == "__main__":
cli()
BELOW IS init.py:
from flask import Flask, jsonify
app = Flask(__name__)
#app.route("/")
def hello_world():
return jsonify(hello="world")
Below is the structure:
The ones marked in red appeared when I ran this command: docker-compose build
enter image description here
A couple of changes to do.
The cli command in your docker-compose.yml file needs to be:
command: python /usr/src/app/manage.py run -h 0.0.0.0 -p 8000
There the command name is run and not runserver. Also the host ip to bind and port to listen are configured as different command options.
Also the configured port mapping for the service needs to map to the container port from the command:
ports:
- 5000:8000
In your manage.py module, FlaskGroup should be provided create_app option which is factory not the app instance.
You can implement this as a lambda function.
cli = FlaskGroup(create_app=(lambda:app))
Edit
The source files are not mounted in the container volume that why you're getting "no such file manage.py".
You need to mount your source files in the container volume under /usr/src/app.
volumes:
- './web:/usr/src/app'

Flask docker compose reload when changing source code? [duplicate]

I want my flask server to detect changes in code and reload automatically.
I'm running this on docker container.
Whenever I change something, I have to build and up again the container. I have no idea where's wrong. This is my first time using flask.
Here's my tree
├── docker-compose.yml
└── web
├── Dockerfile
├── app.py
├── crawler.py
└── requirements.txt
and code(app.py)
from flask import Flask
import requests
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello Flask!!'
if __name__ == '__main__':
app.run(debug = True, host = '0.0.0.0')
and docker-compose
version: '2'
services:
web:
build: ./web
ports:
- "5000:5000"
volumes:
- ./web:/code
Please give me some advice. Thank you in advance.
Flask supports code reload when in debug mode as you've already done. The problem is that the application is running on a container and this isolates it from the real source code you are developing. Anyway, you can share the source between the running container and the host with volumes on your docker-compose.yaml like this:
Here is the docker-compose.yaml
version: "3"
services:
web:
build: ./web
ports: ['5000:5000']
volumes: ['./web:/app']
And here the Dockerfile:
FROM python:alpine
EXPOSE 5000
WORKDIR app
COPY * /app/
RUN pip install -r requirements.txt
CMD python app.py
I managed to achieve flask auto reload in docker using docker-compose with the following config:
version: "3"
services:
web:
build: ./web
entrypoint:
- flask
- run
- --host=0.0.0.0
environment:
FLASK_DEBUG: 1
FLASK_APP: ./app.py
ports: ['5000:5000']
volumes: ['./web:/app']
You have to manually specify environment variables and entrypoint in the docker compose file in order to achieve auto reload.
Assuming your file structure is the below:
Dockerfile: (note WORKING DIR)
FROM python:3.6.5-slim
RUN mkdir -p /home/project/bottle
WORKDIR /home/project/bottle
COPY requirements.txt .
RUN pip install --upgrade pip --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Docker Compose:
version: '3'
services:
web:
container_name: web
volumes:
- './web:/home/project/bottle/' <== Local Folder:WORKDIR
build: ./web
ports:
- "8080:8080"
This is my example:
version: "3.8"
services:
local-development:
build:
context: .
dockerfile: Dockerfiles/development.Dockerfile
ports:
- "5000:5000"
volumes:
- .:/code
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return "hello world"
if __name__ in "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
debug=True enables Flask to change as your code changes.
Docker already plugs into your fs events to change the code "in the container".
If the compose is running different services (app and rq, for instance) you need to set up the volumes on both, or it won't work.

flask with docker returning 404 on all routes except root

I have been investigating related questions but could not find a correct solution to this issue. All of my routes work locally. However, when I run docker-compose up to containerize my app, my app will start but all routes except for the root "hello world" route returns a 404 error.
I've attempted setting "SERVER_NAME" in app.config and appending an extra "/" on my route urls like other posts have suggested but to no avail.
Any suggestions on how to fix this?
app/app.py
#app.route("/") # <-- this route works
def hello_world():
return "Hello, world!"
#app.route("/test", methods=["POST"]) # <-- this one doesn't
def test():
return "Test POST route"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Dockerfile:
FROM tiangolo/uwsgi-nginx-flask:python3.6
COPY requirements.txt /
WORKDIR /
RUN pip install -r ./requirements.txt --no-cache-dir
COPY app/ /app/
WORKDIR /app
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
CMD flask db upgrade && python app.py
docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
env_file:
- .env
You need to mount the source code folder in the docker compose rather than the dockerfile, otherwise you need to rebuild the image every time the code changes. In docker compose you can use volumes property to do this. You can read more here https://docs.docker.com/compose/compose-file/
Example
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
env_file:
- .env
volumes:
- ./app:/app

Categories

Resources