Minimal Developer Setup for Phoenix, MySQL, and Docker.

I recently set up a new project using Phoenix, MySQL, and Docker.

I decided on Phoenix because it has the best out of the box scalability properties of any web framework I know of. I’m a fan of the Elixir programming language and its interoperability with Erlang. It uses the BEAM virtual machine under the hood which has served telecom applications for decades under strict requirements of high availability and fault tolerance.

I went with Docker because it allows me to deploy the project anywhere containers are supported and it’s the container technology I’m most familiar with.

Why not PostgreSQL? Default phoenix projects are configured to use PostgreSQL. I like MySQL better because of its support for row based replication which allows for easier maintenance and no downtime database upgrades.

Let’s get started!

First off, let’s get our docker images and containers configured. You’ll need to install docker-compose.

Dockerfile

For Phoenix, we’ll use the official docker elixir:alpine image.

Why Alpine? Alpine is designed for security, simplicity, and resource efficiency. It has a smaller image size and minimal software dependencies. This results in quicker boot times.

We need to install Phoenix and its dependencies in the container. Add a Dockerfile to your project root. Change the APP_HOME environment variable in the Dockerfile to the project directory of your own app. This should match the {path_in_container} value you’ll use in the next step when creating the volume definition.

For MySQL we’ll use the official docker mysql image.

Bring the two images together in a docker-compose.yml file where you will declare the composition of your services.

docker-compose.yml

When defining the volume for your web container use the format:

— {your_project_directory}:{path_in_container}.

In my project I have the following directory structure:

Image for post
Image for post
directory structure

The volume definition in my docker-compose.yml file maps the ./sec_crawler project directory and it’s contents to the absolute path /sec_crawler in the web container.

You can also mount the assets and _build directories as volumes to your container to avoid transferring all of those files (aka. node_modules) across the VM boundary for quicker builds. That’s a bit more advanced so we’ll skip it for now.

You won’t have a project directory yet, so let’s set that up.

Create an empty .env file in your top level directory and build your services:

> touch .env
> docker-compose build

Generate the phoenix project using this command, (replace {project_name} with your app name):

> docker-compose run web mix phx.new . --app {project_name} --database mysql

Input Y to the “Fetch and install dependencies?” prompt.

We’ll need to configure Phoenix to talk to the database. Let’s generate a password for the root user. You’ll certainly want to use something more secure in production.

Image for post
Image for post
generate password

Edit the .env file and add this environment variable to it.

MYSQL_ROOT_PASSWORD="C+BcX1OLnaM6HWCQRDkUXw=="

Next, open up the file in {project_directory}/config/dev.exs and set the database password from the environment variable value and the hostname to the name of your database container.

Image for post
Image for post
config/dev.exs

Now create your database and schema.

> docker-compose run web mix ecto.create

If you get an error message, check that your db is ready for connections by checking the db container log for the message:

2021-01-15T21:37:14.820519Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.22'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.

Once the db is ready for connections try the ecto.create command again.

Now you can launch your web application with:

> docker-compose up

Open http://localhost:4000 in your browser and view your new Phoenix, MySQL, Docker application in all of its glory!

Cheers and happy coding!

Image for post
Image for post
Melia Capital

I’m on a mission to make finance and technology more accessible. I’m a computer programmer, engineer, data and distributed systems enthusiast.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store