DEV Community

loading...

Discussion on: Development environment for Elixir + Phoenix with Docker and Docker-compose

Collapse
hlappa profile image
Aleksi Holappa Author

Glad this helped you out!

The main point of running your application locally on Docker is the container environment it offers. You're running the application in the same container environment locally and perhaps on a cloud service provider infrastructure.

Also, it makes the database setup easy, you don't have to worry about starting up your local database on host system, configure it, update it etc. Third point being that, lets say that you're integrating your application to some other app and they have development Docker image available, you can just spin up this development image locally alongside of your application. This makes debugging even more easier if you face up problems. This is nice especially if there is some sort of microservice development going on.

Collapse
nycplayer profile image
Matt Van Horn

I have a question about your workflow (or the canonical docker-based workflow) - are you supposed to run tests in a different docker container? Or just locally w/ no container? Or is there a way to change the env to TEST for this container? I like to do red-green-refactor TDD, so quick & easy tests are a big thing for me. I got my tests running locally, but I assume that's not optimal because my local postgres and erlang versions (and db credentials) are different than what is in the container.

Thread Thread
hlappa profile image
Aleksi Holappa Author

Good question! I'm running my tests inside the local development container with command docker-compose run -e MIX_ENV=test web mix test. That command will replace the MIX_ENV environment variable with value "test", so when the mix test is executed the mix environment is set to test, not dev.

About the database url, the smartest way to use environment defined database URL is to use wildcard character in the database name, for example, postgres://postgres:postgres@db:5432/myapp_?. This way in the config files we can read that URL from container environment, replace the ? with our actual environment respectively (dev, test, even prod). By going this, you will always have separate databases locally for development and testing, and the development data does not affect test cases.

Thread Thread
nycplayer profile image
Matt Van Horn

Is that wildcard substitution something I do manually w/ String.replace or interpolation, or is there something built-in to the config function that I am unaware of?
So far the only thing I got to work was:
# .env
DATABASE_URL=postgres://postgres:postgres@db:5432/my_app_

# dev.exs
database_url = "#{System.get_env("DATABASE_URL")}#{Mix.env()}"

Thread Thread
hlappa profile image
Aleksi Holappa Author

That Mix.env() is one way to achieve that. Personally I would still use String.replace/3, since Elixir 1.9 introduced a new way to configure your application without Mix dependency in your config-files.

I would do it this way:

test.exs

database_url = System.get_env("DATABASE_URL")

config :myapp, Myapp.Repo,
  url: String.replace(database_url, "?", "test"),
  pool: Ecto.Adapters.SQL.Sandbox

.env

DATABASE_URL=postgres://postgres:postgres@db:5432/myapp__?