Elixir/Phoenix Project: Establish Hosting Service
Noel Worden
Posted on October 7, 2020
Goals:
- Establish a hosting service
- Update README with deploy steps
- Setup custom domain to point to new environment
Establish a hosting service
A project running locally on my machine is great, but it doesn't mean much if that's the only place it exists. It might seem a bit premature, considering that at this point my entire project is still the default Phoenix splash page. But getting a hosting environment setup early means that new features will be able to go live as soon as they are merged. I started the process by digging around the web to see what others had done (noticing a pattern yet?). And I was a bit surprised that there is a whole service targeted specifically to hosing Elixir/Phoenix projects that I had not heard of: Gigalixir. What I was not surprised by was that there is an entire Deployment section of the Phoenix hexdocs, and in that section there is a whole subsection of how to deploy to Gigalixir.
But, before I go any further, I'm sure someone out there is thinking "why not Heroku?". In a nutshell, Heroku is not setup to give access to all of the features of an Elixir/Phoenix app, like node clustering. Not being partial to any particular hosting service, I figured why not setup my hosting with a service that is made for Elixir/Phoenix?
I ended up walking through the Gigalixir Getting Started Guide, and I have to say, the process was pretty painless. The Gigalixir docs are very detailed, and searchable. Because of the level of detail in their docs, I'm not going to write out my entire process, because I literally just followed the docs through step by step. I will note that I got a bit hung up in the Specify Versions section, because my local versions of elixir
and erlang
were newer than what were specified in the docs.
My local:
elixir
-> 1.10.4
erlang
-> 23
Docs specs:
elixir
-> 1.10.3
erlang
-> 22.3
I attempted to declare these new versions in the elixir_buildpack.config
file that Gigalixir uses to set environment versioning, but when I tried to push up to the service was giving an error stating that those versions couldn't be found. I tinkered with things for a bit, but the only way I could get a push to this new staging environment to be successful was to use the environment specs given in the docs. It's definitely less than desirable to have a local version be different than in a staging environment, but it's a minor version difference, and I know that my next step in this app is to dockerize everything, and there I will take the steps to ensure the versions match.
Another thing to note is that while setting up my Github repository I switched my primary branch name from master
to main
. It seems that Gigalixir has not quite caught up with this optional change, and in the Deploy step it has this:
git push gigalixir master
But, thats basically shorthand, stating that master
from Github should be pushed to master
in the staging environment. Since I don't have a master
branch, I get the following error:
The fix is pretty simple, it just requires a more verbose command:
git push gigalixir main:master
That command is stating that the main
branch of Github should be pushed to the master
branch of staging
One last note that was not noted in the Getting Started Guide is that the remote can be renamed. By default Gigalixir named the remote gigalixir
but I am more used to referencing remotes by their purpose, like staging
or production
. So I ran this command to update the name of my remote:
git remote rename gigalixir staging
Although there were a few small hiccups, all in all the process to setup a staging environment for the project was relatively painless. I have setup a few Heroku environments back in the day, and this process seems remarkably similar. I would strongly recommend at least skimming through the entirety of the Gigalixir docs as they are chock full of useful information.
Update README with deploy steps
In the vein of trying to keep within the ream of best practices I felt like it would be beneficial to document the deploy steps in the README. I've been on more than a few projects where I was the second or third engineer onboarded and there was no documentation on how to perform relatively essential tasks. This is what I included in the project's README:
Deploying to staging
Hosted by Gigalixir, docs can be found here
- It should be noted that the docs are very good, and searchable
- Once the CLI is installed,
gigalixir help
is also very detailed
Project URLs
Install Gigalixir CLI (with homebrew)
brew tap gigalixir/brew && brew install gigalixir
Log into Gigalixir
gigalixir login
Verify login was successful
gigalixir account
Setup git remote
- Navigate to project folder
gigalixir git:remote atlas-staging
Confirm remote
git remote -v
If desired, rename remote (which defaulted to gigalixir
) to staging
git remote rename gigalixir staging
Push to staging
- Any branch can be pushed to the staging site
- Branches need to be pushed to Github before being pushed to staging
git push staging <branch name>:master
Main vs Master
- This project's main branch is named
main
, but Gigalixir is expecting it to be namedmaster
- Because of this, when pushing
main
to staging, it cannot be done with the shorthand:git push staging master
- Until a fix is made by Gigalixir, the following syntax must be used to push:
git push staging main:master
- Because of this, when pushing
Executing mix
Commands in Staging
The app is currently setup to be able to run mix commands on the staging environment
The run
command
- This can be used to run a shell command as a job in a separate container
gigalixir run ...
Using run
and mix
- Any
mix
command available locally can be executing on staging utilizingrun
gigalixir run mix <command here>
Executing a migration
gigalixir run mix ecto.migrate
- The logs do not automatically show, to view the logs
gigalixir logs
Viewing the app
To open the app in a browser
gigalixir open
With this information, along with the slightly tweaked default Spin up the Project
steps, a new developer should be able to pull down the project, get it spun up, and push work to staging all from the docs. I don't really plan on anyone besides me working on this in the foreseeable future, but solid documentation should be the goal of all projects, right?
Setup custom domain
Before I even started this project I dug around for a domain that I felt would be appropriate. It would be a bummer if I got 3 months into this project and I couldn't acquire a domain that had a name is a similar vein. I was able to purchase anglingatlas.com
, so I named the project and repo atlas
(I didn't want to type out AnglingAtlas
every time I had to reference something in the project).
Gigalixir makes it pretty easy to assign a custom domain to the staging (or any other) environment. The one-liner can be found here. I should also point out that the Gigalixir web interface is pretty user-friendly as well. Now my staging environment can be found at https://staging.theanglingatlas.com/
Closing thoughts
I kind of gravitated to all of these devops tasks because it's an aspect of projects that I haven't dealt with directly in quite some time. I was curious what it actually took to get all of this stuff in place. And since I was so far down this road I figured I might as well get it all taken care of. Once this is all squared away, I'll be able to just worry about the features. The last piece of this (I think) is going to be dockerizing the project.
There aren't a ton of changes in the repo since a lot of this section was configuring Gigalixir, but here is what it looks like after all of this configuration.
References
- https://hexdocs.pm/phoenix/deployment.html#content
- https://www.gigalixir.com/
- https://gigalixir.readthedocs.io/en/latest/faq.html
- https://github.com/git-guides/git-remote
This post is part of an ongoing series. I encourage any critique, feedback, or suggestions in the comments.
Posted on October 7, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.