I plan to do this as a series of posts covering all steps from setting up the project to deploying it on some PaaS platform. This won’t be a detailed course of Elixir or Phoenix, but I will add links to more detailed references here and there.
Hopefully, in the end, I fell in love with Elixir and Phoenix. The pure functional environment and scalability of the Elixir platform are intriguing.
I prefer to learn new technologies by implementing a real project or a product. It is fine for me to work through an excellent book like Programming Phoenix 1.4 and implement the learning project. But I only develop a deeper understanding when I have implemented my own ideas or something from a well-understood problem domain.
I love read-it-later services! Unfortunately, I have not found one that fully meets my requirements. And I tried all of them. So, this seems to be a good learning project. It also covers many nice aspects:
- adding a decent CSS framework (Tailwind CSS)
- User Management and Registration
- interacting with a Database
- Building a web frontend
- An API to connect a browser plugin to
- An admin interface
But we start as usual by installing the required tools and configuring the development project.
Set up the development environment
For macOS and Windows it is fairly easy to set up your development environment using a tool like Homebrew or Chocolatey. Just open a shell and run some simple commands. To follow this series you need Elixir, Phoenix, PostgreSQL and Node.js. (Node.js is required for the asset pipeline.)
On macOS brew install elixir postgresql node On Windows choco install elixir postgresql12 nodejs
mix local.hex mix archive.install hex phx_new 1.5.3
Now everything is in place to start our shiny new project.
If you need more background on this. Check out the installation document on the Phoenix website.
Create the initial project
Phoenix works just like all the other modern full-featured web frameworks when creating a new project – you run a command to scaffold your project. In case of Phoenix it is a mix task.
mix phx.new read_it_later
The output of the command looks like that.
* creating read_it_later/config/config.exs * creating read_it_later/config/dev.exs * creating read_it_later/config/prod.exs * creating read_it_later/config/prod.secret.exs * creating read_it_later/config/test.exs * creating read_it_later/lib/read_it_later/application.ex * creating read_it_later/lib/read_it_later.ex ... Fetch and install dependencies? [Yn] y * running mix deps.get * running cd assets && npm install && node node_modules/webpack/bin/webpack.js --mode development * running mix deps.compile We are almost there! The following steps are missing: $ cd read_it_later Then configure your database in config/dev.exs and run: $ mix ecto.create Start your Phoenix app with: $ mix phx.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phx.server
Configure the database connection
If your mind works a bit like mine does, you read over the sentence “Then configure your database in config/dev.exs and…” and just typed
mix phx.server into your console window.
BAMM! You made the same mistake I always make and get some ugly database errors. Do yourself a favor, open the file
config/dev.exs and change the settings for the development database connection.
# Configure your database config :read_it_later, ReadItLater.Repo, username: "oa", password: "", database: "read_it_later_dev", hostname: "localhost", show_sensitive_data_on_connection_error: true, pool_size: 10
In case of macOS and Homebrew the default user for PostgreSQL is your shell user with an empty password. In my case, it is oa.
Now you can run the following two commands. The first will create the development database with the name
read_it_later_dev. The second will start the development server.
mix ecto.create mix phx.server
Now, start your browser and open the URL http://localhost:4000/. You should see the default start page of a fresh Phoenix project.
Anatomy of a Phoenix project
Let’s finish up this post with a short overview of the directory structure and some important files.
├── _build │ └── ... ├── assets │ ├── css │ ├── js │ ├── ... │ ├── static │ └── webpack.config.js ├── config │ ├── config.exs │ ├── dev.exs │ ├── prod.exs │ ├── prod.secret.exs │ └── test.exs ├── deps │ └── ... ├── lib │ ├── read_it_later │ ├── read_it_later.ex │ ├── read_it_later_web │ └── read_it_later_web.ex ├── mix.exs ├── mix.lock ├── priv │ ├── gettext │ ├── repo │ └── static └── test └── ...
buildis the output directory of the Elixir compiler.
assetscontains the typical static files (CSS, JS, images). But it also contains a preconfigured modern asset pipeline based on webpack.
- In the folder
configyou find the overall config file
config.exsand the customizations for the environments’ development (dev), production (prod) and testing (test).
libis the folder where your source code is located. Normally, the mix task that creates a new project creates two packages –
read_it_later_web. At first this might be confusing, but if you have understood a little about the project structure of a Phoenix project, it makes perfect sense.
privcontains contain non-source-code files of your project. Database migrations, i18n files, etc.
- Well, the content of
testshould be obvious.
I share the code to this project on github. Every post gets its own tag on the repository, so you can easily switch to the code of a given post.
Summary and next steps
So far, this was pretty straight forward but also somewhat boring. You now know what I am up to, and we created an initial project. I shared some insights I had during this early stage of my learning project.
Next up, I will add Tailwind CSS to the project because I love this utility-first CSS library. It is a great basis for a design system.