1

I am developing a FastAPI project and using SQLAlchemy and Alembic. I'm running everything in Docker containers with Docker Compose. Now, I'm worried about something. I would like to take advantage of the alembic revision --autogenerate command, but it requires a connection to the database, obviously, as it compares to the current schema.

I came up with the following solution, which I'm unhappy with:

  1. I spin up just the database container docker-compose up -d database

  2. Then I put a connection string on a .env file inside the particular FastAPI service I'm working on

  3. I use load_dotenv() on the env.py file to set the DATABASE_URL environment variable which is used to connect to the dtabase

  4. Now I can do alembic revision --autogenerate

It works, but I'm unhappy with it for many reasons. It doesn't feel very professional, it feels there are lots of "manual stuff" and there are things that simply don't feel natural.

For example: the connection string I'm manually putting on the .env file is just stupid. This is something I need only when coding, it has nothing to do with running the app. Second, the actual connection string to run the app is provided in the environment files from Docker Compose, it doesn't make sense to have it in an additional .env

What is the most professional way of dealing with this? How people deal with generating the migrations with Alembic when using Docker Compose?

4
  • Do you commit the resulting migrations to source control when you're done? Do you have other integration-type testing that needs a similar database setup? I might directly set a DATABASE_URL environment variable without involving a file, but otherwise what you describe seems like a reasonable enough setup. Commented Sep 22 at 17:42
  • 1
    I would go for actions (github or something else you are using) and the workflow can commit the generated revisions as well and there you just need to set up the github (or whatever you are using) secrets once if you have a db up and running, so I would drop doing it in docker. But at the end of the day the safest way is to make them manually as with existing data in a db (suppose prod) there will be some manual data migrations you will have to do as well. Commented Sep 22 at 21:42
  • I run alembic from within my application's docker container with exec and the dev db is already running on another docker container in the same docker network. Are running your application (fastapi) INSIDE a docker container or actually just locally outside of docker? How will you run your migrations when you deploy? Commented Sep 23 at 5:11
  • @DavidMaze I commit the migrations to the git repository, but I still don't have other integration-type testing in place Commented Sep 23 at 18:17

1 Answer 1

0

I will make a few assumptions here

  1. You have multiple services in you compose.yml file, including a fast-api service and a database service.
  2. Your fast-api service depends on the database service
  3. In your dev environment, you want to be able to generate migration files with alembic revision --autogenerate and have them appear in your working directory, so you can commit them to version control.

I had the same issue and solved it using a bind mount volume. The key is that bind mount volumes are offer two-way synchronization between the host (your local project) and the container. Changes made in either place will reflect in another

You can mount a bind mount volume on your fast-api service in compose.yml

services:
  fast-api:
    build: .
    depends_on:
      - database
    volumes:
      - .:/app # Replace /app with the WORKDIR you specified in a Dockerfile. In this case, I assume it's app.
    environment:
      - DATABASE_URL: #your db URL

Now, when you run your alembic command against the fast-api service:

docker compose run fast-api alembic revision --autogenerate

Files generated in container's app/alembic/versions/ will reflect in your local ./alembic/versions. The advantage with this is that you will not need to manually copy your DATABASE_URL anywhere.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.