AUGERClement

AUGERClement

Proposition for an official Docker Compose Guide

As I wrote a week ago in this post, I found the lack of official documentation for Docker compose rather annoying, and I met a lot of problems trying to setup a compose stack for my api. So I wanted to try to write a guide which, if approved, could be added to the official doc. Feedback needed. keep in mind that I am not experienced with Docker, so I could have wrote inexact stuff.

Create a Docker compose stack for your Phoenix app

What we’ll need

We are continuing from the “Deploying with Releases” guide, and by having used the --docker flag in mix phx.gen.release

Goal

The goal is to integrate our dockerised phoenix app in a Compose stack containing the app and the database.

The compose file

We will start by adding a file “docker-compose.yml” at the root of the project. The file should contain the following :

services:
    db:
        image: postgres
        restart: always
        container_name: database
        volumes:
            - pg-data:/var/lib/postgresql/data
        environment: # Used by the postgres image to setup a default user. For security reason, you should avoid using the postgres user
            POSTGRES_USER: pg_user
            POSTGRES_PASSWORD: pg_pass
            POSTGRES_DB: hello_database
    
    app:
        container_name: hello-app
        restart: always
        build:
            context: .
            dockerfile: Dockerfile
        depends_on:
            - db
        ports: # Docker need to expose ports for you to access your app.
            - 4000:4000
        environment:
            DATABASE_URL: "ecto://pg_user:pg_pass@db/hello_database" # Template : "ecto://db_user:db_password@ip_or_compose_service_name/db_name"
            SECRET_KEY_BASE: really_long_secret # Can literally be anything, but generally generated randomly by tools like mix phx.gen.secret

volumes:
    pg-data:
        external: true # Must use "docker volume create --name=pg-data before

By using docker compose up, you will now have your containers running, but it’s not over yet, the last part is the migration of your schema in the newly instancied database service

A word about volume

As you may know, Docker is really shining when it doesn’t have to persist data, because container are stateless by default. However, when using a database, and needing to save data, we need volume to map the space from within the container to outside. Moreover, by using an external volume, we can ensure the data is stored somewhere we can easily find it.

A word about environment

In this docker-compose file, we set our environment directly, for simplicity’s sake. It is not a good reflex. When you will push your compose.yml, you’ll put up your credentials in plain day, between others problems. You may prefer to use a .env file, but this subject isn’t the point of this guide, so we won’t go further.

The migration

Once both the containers are started, we need to migrate our schema in the newly created postgres. To do so, we will use a variante of the _build/prod/rel/my_app/bin/my_app eval "MyApp.Release.migrate we saw in the previous chapter.

First, we need to enter the Docker container of our phoenix app, by clicking the CLI button in the Docker Desktop GUI. Or, if you prefer a terminal, using it’s docker id we can get with docker ps along with docker exec -it <container_id> /bin/sh.

Then, because the Dockerfile simply copied the release folder in the container, we need to remove everything before the bin folder. Leaving us with bin/my_app eval "MyApp.Release.migrate"

And that’s it. You now have a Docker Compose Stack of two containers, which will be restarted automatically if one of them goes down, and deploying your app on another machine is now as easy as git clone, docker compose up.

Most Liked

Exadra37

Exadra37

The port as it is is exposing the app to the internet on your PC, because 4000:4000 is the same as 0.0.0.0:4000:4000, and what you want in localhost is 127.0.0.1:4000:4000. For production setup where the docker container is the one directly handling the requests from the internet, then you want to use 0.0.0.0, but if the docker container is behind Nginx, Traefik or other, via docker compose, then you can remove the ports all together. If you have an hybrid dolution, where you have Nginx on the host serving the docker container, then use 127.0.0.1.

I don’t recommend to use this, because if you then need to stop the container he will restart immediately. Instead use unless-stopped.

darethas

darethas

I do not see where depends_on is being deprecated.

I use depends_on long form with a condition, and in my database setup, I specify a healthcheck using the standard installed pg_isready command (in the case of PostgreSQL dependenceis) like so:

services:
  web:
    image: foo:123
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:14.4
    healthcheck:
      test: [ "CMD", "pg_isready", "-q", "-U", "postgres" ]
      timeout: 45s
      interval: 10s
      retries: 10
rm-rf-etc

rm-rf-etc

I agree that the Elixir community needs to do better with docker-compose examples. It allows people to try Elixir on localhost quickly and easily without going through all the system setup.

But please, start with the most minimal configuration you can. Remove postgres, do an example that simply starts a bare bones webserver and responds with ‘hello world’. I’m so tired of every Ex example out there forcing me into setting up Phoenix and Postgres when I just want to run an Elixir server. If I decide I need Phoenix and I need Postgres, let me do that later.

I feel like this community really doesn’t understand the value of the ‘hello world’ idea.

Where Next?

Popular in Discussions Top

WildYorkies
It seems that the more I read, the more I find Elixir users speaking about all the ways that Elixir is not good for x, y, and z use cases...
New
100phlecs
Are there any downsides, like perf issues, to putting all functional components in CoreComponents as long as you prefix it with the conte...
New
crispinb
On reading dhh’s latest The One Person Framework it strikes me that Phoenix with LiveView is already pretty much this. However, never hav...
New
AlexMcConnell
The reason that Rails is as popular as it is is because it’s very easy for relatively inexperienced developers to get a lot of work done....
588 19675 166
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
AstonJ
Can you believe the first professionally published Elixir book was published just 8 years ago? Since then I think we’ve seen more books f...
New
joeerl
I’m playing with Elixir - It’s fun. I think @rvirding does give Elixir courses these days. Re: files and database - when I given Erlang ...
New
kostonstyle
Hi all How can I compare haskell with elixir, included tools, webservices, ect. Thanks
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54250 245
New

We're in Beta

About us Mission Statement