Smokin Joe
Smokin Joe

Reputation: 453

Able to get my Docker Container onto Heroku but I have no idea how to access endpoints

I've followed the directions here: https://devcenter.heroku.com/articles/container-registry-and-runtime

And then I followed the quick instructions to allocate a dyno: https://medium.com/@MatheusCAS/deploying-docker-to-heroku-344985da5426

I'm now able to get the wonderful message that the app is running:

2018-04-04T23:13:48.082637+00:00 heroku[api.1]: Starting process with command `flask run --host 0.0.0.0 --port 5000`
2018-04-04T23:13:48.785247+00:00 heroku[api.1]: State changed from starting to up
2018-04-04T23:13:50.342651+00:00 app[api.1]:  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
2018-04-04T23:13:50.346134+00:00 app[api.1]:  * Restarting with stat

However I have legitimately zero clue how to access any of my defined endpoints! I want to say that the api is running within the container, but I can't "expose" it and its endpoints to the outside World. Most every URL I visit or curl just provides the Application error html response.

Here's my Dockerfile:

FROM python:3.6
ENV TZ UTC
ADD ./requirements.txt /opt/code/requirements.txt
WORKDIR /opt/code
RUN mkdir -p /opt/logs && \
   mkdir -p /opt/media && \
  apt-get update && apt-get install --no-install-recommends -y \
  gcc \
  build-essential &&\
  pip install --no-cache-dir -r requirements.txt && \
  apt-get purge -y \
  gcc \
  build-essential && \
  apt-get clean autoclean && \
  apt-get autoremove -y && \
  rm -rf /var/lib/{apt,dpkg,cache,log}/
EXPOSE 5000
ENV FLASK_APP api_name/wsgi.py
ENV FLASK_CONFIG Dev
ENV FLASK_DEBUG 1
ADD . /opt/code/
RUN python /opt/code/setup.py develop
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "5000"]
ARG SOME_ENV_VAR
ENV SOME_ENV_VAR "$SOME_ENV_VAR"

And my docker-compose.yml:

version: '2'

services:
  api:
    build:
      context: .
      args:
        - SOME_ENV_VAR=${SOME_ENV_VAR}
    container_name: api_name
    image: api_name
    volumes:
      - ../api-name:/opt/code
    ports:
      - "5000:5000"

I realize that EXPOSE 5000 isn't recognized by Heroku, could that be an issue? Should I try removing all port stuff, performing a build/push of the container?

Any help would be greatly appreciated.

EDIT:

So I've created an additional web: service in my docker-compose.yml (literally copy&pasted the api: portion with changing name of the image), performed a build and pushed it to Heroku. Seems like things may be closer to actually working but I'm still unable to reach .. well, any endpoints. At the moment my logs are showing me:

2018-04-04T23:44:38.275695+00:00 heroku[web.1]: Starting process with command `flask run --host 0.0.0.0 --port 5000`
2018-04-04T23:44:40.252177+00:00 app[web.1]:  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
2018-04-04T23:44:40.258019+00:00 app[web.1]:  * Restarting with stat
2018-04-04T23:44:40.694791+00:00 app[web.1]:  * Debugger is active!
2018-04-04T23:44:40.696554+00:00 app[web.1]:  * Debugger PIN: ###
2018-04-04T23:44:40.737185+00:00 app[web.1]:  * Running on http://0.0.0.0:55008/ (Press CTRL+C to quit)
2018-04-04T23:44:41.095223+00:00 heroku[web.1]: State changed from starting to up
2018-04-04T23:44:41.199265+00:00 app[web.1]:  * Debugger is active!
2018-04-04T23:44:41.199497+00:00 app[web.1]:  * Debugger PIN: ###

Anyone got any ideas? Why does it seem to be running two servers?

Upvotes: 2

Views: 2786

Answers (3)

mindjoy
mindjoy

Reputation: 1

Having the Dockerfile read a dynamic port works as follows

CMD ["sh","-c","flask run --host 0.0.0.0 --port ${PORT}"]

Upvotes: 0

Smokin Joe
Smokin Joe

Reputation: 453

OK, I figured it out. My issue is that I embarrassingly didn't realize that I could never perform a docker-compose build web locally WITH remote Heroku environment variables! So obvious when I say it out loud but for whatever reason it was over my head yesterday.

Anyway, in order to remedy this and the issue of starting the server twice I changed out the CMD line in my Dockerfile from:

CMD ["flask", "run", "--host", "0.0.0.0", "--port", "5000"]

to:

CMD python my_api/app.py

While making sure to have the proper app.run located in that app.py file:

import os
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port)

And bam! Everything works as it should!

Upvotes: 1

Robert Moskal
Robert Moskal

Reputation: 22553

Your in luck! The environment variable interpolation in docker-compose works pretty well. This should expose your endpoint. It's the same technique you use in every heroku application.

ports:
  - "${PORT}:5000"

The endpoint will be served on port 80 of your application.

Upvotes: 1

Related Questions