Using docker in development can be very convenient, but running your actual app (you know, the one you’re coding) in docker introduces various headaches.
What genuinely surprises me, is that often teams don’t consider the obvious: just run your app directly on your machine. I find it to be the sweet spot of dev setup. Let’s see what it would look like.
Create a docker-compose.yml
file in your app’s root and only declare your databases in it. For example, this file gives you
localhost:5432
localhost:6379
localhost:9000
version: '3'
services:
postgres:
image: postgres:10.3-alpine
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
redis:
image: redis:3.2.11-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
minio:
image: minio/minio
volumes:
- minio-data:/data
ports:
- "9000:9000"
entrypoint: sh
command: -c "mkdir -p /data/dev /data/test && /usr/bin/minio server /data"
environment:
MINIO_ACCESS_KEY: access_key
MINIO_SECRET_KEY: secret_key
volumes:
postgres-data:
redis-data:
minio-data:
Create a .tool-versions
file in app’s root. Here’s an example for elixir and node setup.
elixir 1.6.4-otp-20
erlang 20.2.4
nodejs 10.8.0
Asdf is like rvm, nvm, and other version managers combined. It has an extensive list of things it can manage.
Now you can bootstrap the application by running
asdf install
docker-compose up
and in another terminal you run the app itself:
mix phx.server
That’s it. Now you have the benefit of quick and simple dev setup without giving up all the convenience of interacting with your app directly, without containers in the middle.
The cool part is that your database.yml
can be committed to the repo, it will always look the same:
default: &default
adapter: postgresql
username: postgres
host: localhost
development:
<<: *default
database: myapp_dev
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp
However, there’s a minor issue when using this setup in Rails. You might get an error when trying to install the pg gem or run a rake db:structure:dump
command. Both of these actions rely on postgres being installed locally. To work around it simply add postgres to your .tool-versions
— asdf supports it. You will not be actually running this postgres, only using its cli as a client, and satisfying pg’s dependencies.