How to deploy to mimic a simple heroku.yml?

Hi,

How can I deploy my app to follow this simple heroku.yml. I read your docs about blueprints and play around with the UI, but can’t figure out how to do it:

setup:
  addons:
    - plan: heroku-postgresql
      as: DATABASE
    - plan: heroku-redis
      as: REDIS
  config:
    DJANGO_SETTINGS_MODULE: my_saas_app.settings_production
build:
  docker:
    django: Dockerfile.heroku
release:
  image: django
  command:
    - python manage.py migrate --noinput
run:
  web:
    command:
      - gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 my_saas_app.asgi:application -k uvicorn.workers.UvicornWorker
    image: django
  worker:
    command:
      - celery -A my_saas_app worker -l INFO --beat --concurrency 2
    image: django

Hi,

The Blueprint spec covers most options in one big example. You’d create a render.yaml in the root of your repo, defining the services that make up the project.

Do you have an example of what you’ve tried so far? What part are you having trouble with? Are you getting any error messages?

Alan

So in that heroku.yml, I would define 4 stages: setup → build → release → run. In ‘setup’, it will add databases & redis. In ‘build’, it will build a docker image based on Dockerfile. In ‘release’, it will run db migration. Then in ‘run’, it will start the service based on the docker image from the ‘build’ stage.

I’m not sure how to replicate this workflow in render.yml. It looks like a list of services with no stages, so equivalent to the ‘setup’ stage of heroku. So for example, how would I run ‘python manage.py migrate --noinput’ after Dockerfile build is available, then start ‘web’ and ‘worker’ service with their respective commands afterwards?

With Render, services are separate, not combined under an “app” like Heroku. Each service using a Native Runtime has a build (install dependencies, run build scripts, etc.), pre-deploy (run migrations, etc.) and start command (boot the service).

However, if your project is Docker-based, and you want to build each service from a Dockerfile, in you would set “docker” as the runtime for each service in the Blueprint (render.yaml).

With the Docker runtime, the build command is replaced by building the Dockerfile, the pre-deploy command can be set to run a command against the built image, and the start command is replaced by the ENTRYPOINT/CMD of the Dockerfile.

Each Render service using the Docker runtime builds and maintains its own image. However, if you want to use the exact same image, you can deploy prebuilt images (blueprint docs)

By default, the Docker runtime will look for a Dockerfile in the root of your repo and build that. It would then run the preDeployCommand if specified (This requires paid instance types) and finally, it would boot the image, defaulting to use the ENTRYPOINT/CMD specified in the Dockerfile.

If your project doesn’t match that default behavior for the docker runtime, you can update the Blueprint with additional Docker options:

  • Point to another dockerfilePath, e.g. ./docker/Dockerfile.prod
  • Run a different command to boot the image with dockerCommand: (overrides both ENTRYPOINT & CMD)

Alan

Thanks Alan! That’s a very detailed & helpful answer. I will try to work this out and report back.

Alright after some trials & errors I was able to deploy it. But now I run into this error, which I didn’t have on localhost & heroku:

raise AnymailRequestsAPIError(

anymail.exceptions.AnymailRequestsAPIError: Mailgun API response 401 (Unauthorized): 'Forbidden'

Stackoverflow seems to suggest that it may have something to do with the location of the domain & server:

That doesn’t seem like it is a Render issue. It would imply an incorrect Mailgun config, maybe incorrect/missing credentials.

Alan

I have resolved this. Turn out in the Secret files in Env Groups, I have a space between the variable and the value. So previously it was:

MAILGUN_API_KEY ='.....'

I fix it by removing the space before ‘=’:

MAILGUN_API_KEY='.....'

The thing is I have been using this exact file in localhost and Digital Ocean App Platform, and it works just fine. But Render doesn’t seam to tolerate the space and doesn’t raise any error either.

Feedback to the Render team, I think you guys should learn from Digital Ocean App Platform on how to bulk import env variables. They allow user to copy & paste the .env file into their UI, and automatically parse & display a list of environment variables for users to verify & edit. Very clear & no hidden error.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.