Error deploying Django/Postgres app for the first time

Hello,

I’m deploying my first app (Django/Postgres) and hitting an error when running: fly deploy

Possibly it is something to do with the psycopg2 package, but I’m not sure how to handle that.

Output from logs:

Error release_command failed running on machine 7d891129aed484 with exit code 1.
Check its logs: here's the last 100 lines below, or run 'fly logs -i 7d891129aed484':
  Pulling container image registry.fly.io/myapp1:deployment-RS0FZ01GYA31S8V88DF7QG5HTZ
  Unpacking image
  Successfully prepared image registry.fly.io/myapp1:deployment-RS0FZ01GYA31S8V88DF7QG5HTZ
  Configuring firecracker
  Starting init (commit: ed64554)...
  Preparing to run: `python manage.py migrate` as root
  2023/04/18 11:48:03 listening on [fdaa:1:e227:a7b:eb:808:5472:2]:22 (DNS: [fdaa::3]:53)
  Traceback (most recent call last):
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
      self.connect()
    File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 225, in connect
      self.connection = self.get_new_connection(conn_params)
    File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 203, in get_new_connection
      connection = Database.connect(**conn_params)
    File "/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
      conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
  psycopg2.OperationalError: connection to server at "myapp1-db.flycast" (fdaa:1:e227:0:1::2), port 5432 failed: SSL SYSCALL error: Success
  The above exception was the direct cause of the following exception:
  Traceback (most recent call last):
    File "/code/manage.py", line 22, in <module>
      main()
    File "/code/manage.py", line 18, in main
      execute_from_command_line(sys.argv)
    File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
      utility.execute()
    File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
      self.fetch_command(subcommand).run_from_argv(self.argv)
    File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 414, in run_from_argv
      self.execute(*args, **cmd_options)
    File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 460, in execute
      output = self.handle(*args, **options)
    File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 98, in wrapped
      res = handle_func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 91, in handle
      self.check(databases=[database])
    File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 487, in check
      all_issues = checks.run_checks(
    File "/usr/local/lib/python3.10/site-packages/django/core/checks/registry.py", line 88, in run_checks
      new_errors = check(app_configs=app_configs, databases=databases)
    File "/usr/local/lib/python3.10/site-packages/django/core/checks/model_checks.py", line 36, in check_all_models
      errors.extend(model.check(**kwargs))
    File "/usr/local/lib/python3.10/site-packages/django/db/models/base.py", line 1461, in check
      *cls._check_indexes(databases),
    File "/usr/local/lib/python3.10/site-packages/django/db/models/base.py", line 1864, in _check_indexes
      connection.features.supports_covering_indexes
    File "/usr/local/lib/python3.10/site-packages/django/utils/functional.py", line 49, in __get__
      res = instance.__dict__[self.name] = self.func(instance)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/features.py", line 84, in is_postgresql_11
      return self.connection.pg_version >= 110000
    File "/usr/local/lib/python3.10/site-packages/django/utils/functional.py", line 49, in __get__
      res = instance.__dict__[self.name] = self.func(instance)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 354, in pg_version
      with self.temporary_connection():
    File "/usr/local/lib/python3.10/contextlib.py", line 135, in __enter__
      return next(self.gen)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 639, in temporary_connection
      with self.cursor() as cursor:
    File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 284, in cursor
      return self._cursor()
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 260, in _cursor
      self.ensure_connection()
    File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 243, in ensure_connection
      with self.wrap_database_errors:
    File "/usr/local/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__
      raise dj_exc_value.with_traceback(traceback) from exc_value
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
      self.connect()
    File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 225, in connect
      self.connection = self.get_new_connection(conn_params)
    File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
      return func(*args, **kwargs)
    File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 203, in get_new_connection
      connection = Database.connect(**conn_params)
    File "/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
      conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
  django.db.utils.OperationalError: connection to server at "myapp1-db.flycast" (fdaa:1:e227:0:1::2), port 5432 failed: SSL SYSCALL error: Success
  Starting clean up.
  [    3.133052] reboot: Restarting system
  machine restart policy set to 'no', not restarting
Error: release command failed - aborting deployment. error release_command machine 7d891129aed484 exited with non-zero status of 1

Dockerfile:

ARG PYTHON_VERSION=3.10-slim-buster

FROM python:${PYTHON_VERSION}

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN mkdir -p /code

WORKDIR /code

COPY requirements.txt /tmp/requirements.txt
RUN set -ex && \
    pip install --upgrade pip && \
    pip install -r /tmp/requirements.txt && \
    rm -rf /root/.cache/

COPY . /code

RUN python manage.py collectstatic --noinput

EXPOSE 8000

# TODO: replace demo.wsgi with <project_name>.wsgi
CMD ["gunicorn", "--bind", ":8000", "--workers", "2", "myapp1.wsgi"]

Do I need to add something to the Dockerfile to get this to work?
Total noob here.

Thank you in advance!

Hello @yellowlabrat, I noticed a couple of lines missing in your Dockerfile. psycopg2 requires external packages to work properly. Try to add the following line to your Dockerfile after your WORKDIR /code command:

RUN apt-get update && apt-get install -y \
    libpq-dev \
    gcc \
    && rm -rf /var/lib/apt/lists/*

You may want to consider this article on Deploying Django to Production · Fly. I found it helpful when I deployed my Django application to fly.io and the deployment process went smoothly

Hope it helps.

2 Likes

Hi @Ederene20, I wanted to say thank you for the tip!
That extra piece added to the Dockerfile let me get past the error.
I’m on to a new set of errors I’ve not been able to solve (database connection issues), but at least my original question has been answered.
Thank you again for taking the time!

Which database are you using ? Sqlite and problem with the URI/path ? If using postgres mysql or whatever just use dj-database-url · PyPI (also works with sqlite but there’s an URI gotcha, I had to “sqlite:////mnt/myvolume/mydb.sqlite” with 4 forward slashes ).

You can try to run the container locally before deploying since it takes tons of time and can quickly become frustrating.

Here’s a working example from a project of mine running django + huey (tiny replacement of celery) with overmind (you can also use processes for that if you want to decouple and scale separately) if it can help :

DockerFile

FROM python:3.11.0-slim-bullseye

RUN apt-get update \
    && apt-get install -y build-essential libpq-dev wget vim htop tmux golang-go kitty-terminfo \
    && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
    && rm -rf /var/lib/apt/lists/*

# install overmind 

WORKDIR /home/Downloads 

COPY ./install_overmind.sh . 

RUN ./install_overmind.sh

WORKDIR /usr/src/app

COPY ./requirements.txt ./requirements.txt 

RUN pip install --no-cache-dir -r requirements.txt \
    && rm -rf requirements.txt

COPY . . 

CMD ./runserver.sh 

runserver.sh

#!/bin/bash

python manage.py collectstatic --noinput

python manage.py makemigrations
python manage.py migrate


overmind start -f ./OvermindProcfile

Procfile for overmind

django: gunicorn MyApp.asgi:application --workers 3 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 
# celery: celery -A MyApp worker -l info
huey: python manage.py run_huey

Hi Heroe,

That’s what I’m currently, using, the Postgres generated database from “fly launch” command, and in my settings.py file I sent over, it is using the dj-database-url code like this:

DATABASES = {}
MAX_CONN_AGE = 600
if "DATABASE_URL" in os.environ:
    # This means we are running on the cloud server, so use its config variables
    DATABASES['default'] = config('DATABASE_URL')
    DATABASES["default"] = dj_database_url.config(
        conn_max_age=MAX_CONN_AGE, ssl_require=True)

Let me know if that helps or you need anything else.

Well I mean here you’re not passing any database URL to dj_database_url, you’re just overwriting DATABASES_DEFAULT and your first assignment serves no purpose, your application thus don’t know anything about your DB and it’s normal that it doesn’t work.

The correct way would be :


DATABASE_URL = os.environ.get("DATABASE_URL")
DATABASES["default"] = dj_database_url.config(
        default =  DATABASE_URL,
        conn_max_age=MAX_CONN_AGE, 
        ssl_require=True)

But again just try to run the same locally with local postgres + URI even if not Dockerized, that’d be way easier to spot since here it doesn’t have anything to do with the remote environment, that’s just a python + specific library misunderstanding.

@Heroe, wow, I just realized I thought I was responding to support and that they hadn’t even looked at the files I had given them. So sorry for not reading through your whole message and just replying back strangely. :grinning:

To answer your question… yes, this is postgres, and I changed my settings.py database connection to the one that you suggested and that didn’t change the results. I’m still getting the same error:

File "/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
      conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
  django.db.utils.OperationalError: connection to server at "myapp1-db.flycast" (fdaa:1:e227:0:1::4), port 5432 failed: SSL SYSCALL error: Success

I also broke down and got a support plan and emailed. So far, this is what I’ve heard back:

Regarding the myapp1-db app, I see the VM associated with the app is currently stopped, but I’m not sure if that would cause this issue as it should wake on request. Can you also try running fly postgres connect -a myapp1-db and let me know if you have issues connecting to it through flyctl?
fly postgres connect · Fly Docs

So, I tried that and am getting the error:
Error: no active leader found

I did some googling on that and found this thread on this community: Postgres is down, cannot restart. Error no active leader found. - #12 by dad

Ultimately, it seemed like this worked for most people:
flyctl machine restart my_db_id

But it didn’t work for me, so I’ll see what support says and keep posting to this thread until it is resolved.