Software engineer. Currently working with TypeScript, Ruby and Terraform to build digital solutions! Enthusiast about Elixir, OTP, design patterns and best practices.
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.
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.
Software engineer. Currently working with TypeScript, Ruby and Terraform to build digital solutions! Enthusiast about Elixir, OTP, design patterns and best practices.
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.
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()}"
Software engineer. Currently working with TypeScript, Ruby and Terraform to build digital solutions! Enthusiast about Elixir, OTP, design patterns and best practices.
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.
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.
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.
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 theMIX_ENV
environment variable with value "test", so when themix 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.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()}"
That
Mix.env()
is one way to achieve that. Personally I would still useString.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
.env