How can I deploy docker-compose app to heroku?

Viewed 930

I'd like to deploy the python django dockerapp to heroku. But I got psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known error after git push heroku master.

The files are as follows.

How can I solve this issue? Thanks.

  • docker-compose.yml
version: '3'

services:
  db:
    image: postgres
    environment:
       POSTGRES_DB: testdb
       POSTGRES_USER: testuser
       POSTGRES_PASSWORD: testpw

  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
  • heroku.yml
setup:
  addons:
    - plan: heroku-postgresql
      as: db
  config:
    S3_BUCKET: db
build:
  docker:
    web: Dockerfile
run:
  web: python manage.py runserver 0.0.0.0:8000
  worker:
    image: web
  • The commands I run:
git init ; git add -A ; git commit -m .
heroku create # // nameless-anchorage-47384 
heroku git:remote -a nameless-anchorage-47384
heroku stack:set container
git push heroku master ; heroku logs --tail
  • The log I got:
2020-03-14T02:49:34.183660+00:00 heroku[web.1]: Starting process with command `/bin/sh -c python\ manage.py\ runserver\ 0.0.0.0:8000`
2020-03-14T02:49:36.844857+00:00 app[web.1]: Watching for file changes with StatReloader
2020-03-14T02:49:36.845227+00:00 app[web.1]: Performing system checks...
2020-03-14T02:49:36.845228+00:00 app[web.1]:
2020-03-14T02:49:36.931900+00:00 app[web.1]: System check identified no issues (0 silenced).
2020-03-14T02:49:37.084523+00:00 app[web.1]: Exception in thread django-main-thread:
2020-03-14T02:49:37.084566+00:00 app[web.1]: Traceback (most recent call last):
2020-03-14T02:49:37.084603+00:00 app[web.1]: File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
2020-03-14T02:49:37.084974+00:00 app[web.1]: self.connect()
2020-03-14T02:49:37.085013+00:00 app[web.1]: File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 195, in connect
2020-03-14T02:49:37.085282+00:00 app[web.1]: self.connection = self.get_new_connection(conn_params)
2020-03-14T02:49:37.085316+00:00 app[web.1]: File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
2020-03-14T02:49:37.085892+00:00 app[web.1]: connection = Database.connect(**conn_params)
2020-03-14T02:49:37.085931+00:00 app[web.1]: File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 126, in connect
2020-03-14T02:49:37.086645+00:00 app[web.1]: conn = _connect(dsn, connection_factory=connection_factory, **kwasync)       
2020-03-14T02:49:37.086785+00:00 app[web.1]: psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known
2020-03-14T02:49:37.086810+00:00 app[web.1]:
2020-03-14T02:49:37.086836+00:00 app[web.1]:
2020-03-14T02:49:37.086836+00:00 app[web.1]: The above exception was the direct cause of the following exception:
2020-03-14T02:49:37.086837+00:00 app[web.1]:
2 Answers

I don't think you can. I had to do the free "Postgres addon" then connect to a database by using the DATABASE_URL environment variable they expose.

Looks to me like you might need to replace the usage of the db hostname with the os.environ.get('DATABASE_URL') which is defaulted using the heroku database plugins.

So wherever you're passing in the database connection uri just update it to point to the heroku DATABASE_URL ( https://devcenter.heroku.com/changelog-items/438 )

See:

From what I'm seeing it's not so much using a docker-compose.yml file to deploy, but writing a custom heroku.yml file.

https://devcenter.heroku.com/articles/build-docker-images-heroku-yml#heroku-yml-overview

heroku.yml Overview

A heroku.yml manifest has 4 top-level sections:

setup - Specifies the add-ons and config vars to create during app provisioning
build - Specifies the Dockerfile to build
release - Specifies the release phase tasks to execute
run - Specifies process types and the commands to run for each

They have this as an example, which is different from the compose.yml file:

Example heroku.yml file:

setup:
  addons:
    - plan: heroku-postgresql
      as: DATABASE
  config:
    S3_BUCKET: my-example-bucket
build:
  docker:
    web: Dockerfile
    worker: worker/Dockerfile
  config:
    RAILS_ENV: development
    FOO: bar
release:
  command:
    - ./deployment-tasks.sh
  image: worker
run:
  web: bundle exec puma -C config/puma.rb
  worker: python myworker.py
  asset-syncer:
    command:
      - python asset-syncer.py
    image: worker
Related