Reputation: 1858
I would like to deploy a basic Flask app on Heroku.
Here is the basic structure of my app:
├── Dockerfile
├── Makefile
├── README.rst
├── app
│ ├── __init__.py
│ └── app.py
├── heroku.yml
├── poetry.lock
├── pyproject.toml
└── tests
├── __init__.py
└── test_app.py
I would like the app to de re-deployed every time I merge a PR into the master branch of my project, so I set this up via an Automatic Deploy option in Heroku.
I'm able to successfully run this app locally as well as through a docker container (also locally), however, Heroku fails to deploy the app. The first error that I encountered was No default language could be detected for this app
which led me to enable a build pack for this app (python). After setting the build pack, I get the following error: App not compatible with buildpack: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/python.tgz ... ! push failed
. I've found a few related discussion (like this one) which seem to suggest that Poetry could be the problem and that I need a requirements.txt
, but even after generating one I still get the same error.
Does anyone know what's going on here? I feel that something is fundamentally wrong because I shouldn't even need a build pack -- the docker image should take care of that. And FYI, heroku.yml
contains the following:
build:
docker:
web: Dockerfile
Please let me know if I should share more information about my app setup.
Many thanks!
UPDATE 1:
I've managed to push my docker image to Heroku via heroku container:push web -a APP_NAME
followed by heroku container:release web -a APP_NAME
, however when I open the app https://APP_NAME.herokuapp.com/ I see that it failed to start, which is not surprising as my dockerfile does not end with RUN python app.py
-- if I add that line and rerun the above commands, then the whole process stops when the image gets built, the last line is "Running on ..." -- I don't think that running it asynchronously is the right solution here either.
Any suggestions? If I manage to get the Heroku container working, then I imagine it means I cannot get Heroku to rebuild my image every time I update the master branch, instead, I would need to do it myself.
Upvotes: 3
Views: 775
Reputation: 1858
I got it working. Here is what I did:
app.py
to the top level, (appdir/app.py
as opposed to appdir/app/app.py
)gunicorn
Procfile
on top level of your project which should contain web: gunicorn app:app
python app.py
but gunicorn app:app
heroku container:push web -a APP_NAME; heroku container:release web -a APP_NAME
I still haven't worked out how Continuous Integration fits in here (in other words, does Heroku itself offer anything here?) though, so if anyone has any suggestions, please let me know
UPDATE
Just wanted to add that for CI I ended up using GitHub actions. I created a file under .github/workflows/deploy.yaml
which contains the following:
- name: deploy
env:
HEROKU_API_KEY: ${{ secrets.HEROKU_API_TOKEN }}
HEROKU_APP_NAME: "covid-monitor"
run: |
heroku container:login
heroku container:push web -a $(appname)
heroku container:release web -a $(appname)
Note that for this to work you need to add the Heroku API token to GitHub secrets.
Upvotes: 3