Subscribe to access all episodes. View plans →
Published January 21, 2022
Phoenix 1.6
In this episode we’ll create a Phoenix 1.6 application and deploy it to Gigalixir. There are 3 ways to deploy to Gigalixir. Be sure to check out the Gigalixir docs to see the benefits of each. In this Episode we’ll use the Mix method to deploy to Gigalixir.
We’ll need an application to deploy, so let’s create one. We’ll go to the command line and run: mix phx.new teacher
$ mix phx.new teacher
...
Then let’s move into the new teacher
directory …. and create our app’s database with mix ecto.create
.
$ cd teacher
$ mix ecto.create
The database for Teacher.Repo has been created
Now let’s test that everything is working locally. We’ll start up our server.
$ mix phx.server
...
And if we open our browser to localhost:4000
- great - our app is running. Now that we know it’s working locally, let’s get it ready to be deployed. In order to deploy our application to Gigalixir, we’ll need to first install Gigalixir’s command-line interface or CLI.
The docs have instructions for how to install the CLI and since I’m on a Mac I’ll copy the command and paste it into the terminal. Let’s confirm everything was installed with gigalixir --help
and great we see all the different commands the CLI gives us.
Now if you don’t already have a Gigalixir account you can create one with gigalixir signup
and you already have an account you can sign in to it with gigalixir login
.
$ gigalixir login
...
Now that we’re signed into Gigalixir, let’s get our app ready to be deployed. There are really only a few changes we’ll want to make. Let’s open the config/runtime.exs
and we’ll want to use SSL for our database connection. To do that let’s uncomment the the ssl: true
line in our Repo
config.
config/runtime.exs
...
config :teacher, Teacher.Repo,
ssl: true,
...
Then we’ll go to our config/prod.exs
and let’s force all incoming requests to our application to use SSL, redirecting HTTP to HTTPS. To do that we’ll go to the Endpoint
config add force_ssl: [rewrite_on: [:x_forwarded_proto]]
.
config/prod.exs
...
config :teacher, TeacherWeb.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto]],
url: [host: "example.com", port: 80],
cache_static_manifest: "priv/static/cache_manifest.json"
...
Because Phoenix 1.6 uses esbuild
to compile our assets and Gigalixir images use npm
we’ll need need configure npm
to deploy our assets. To do that we’ll create a package.json
in the /assets
directory. And I’ll paste in the config from the Gigalixir docs.
assets/package.json
{
"scripts": {
"deploy": "cd .. && mix assets.deploy && rm -f _build/esbuild"
}
}
Now we just need to specify the versions of Elixir, Erlang, and Node we want to deploy our app with. Let’s create an elixir_buildpack.config
and inside it we’ll specify the elixir_version
we want to use and the erlang_version
. One note on version, you’ll probably want to use the same versions that your app is using in development and may be different than the versions I’m using here.
elixir_buildpack.config
elixir_version=1.12.3
erlang_version=22.3
Then we’ll want to create a phoenix_static_buildpack.config
and we’ll specify the node_version
to use.
phoenix_static_buildpack.config
node_version=12.16.3
Since Gigalixir uses git we need to create a new Git repo for our app. Then let’s add our project and commit the changes.
$ git init
$ git add .
$ git commit -m "updates for Gigalixir deploy"
Now let’s create a Gigalixir application with the name eager-reasonable-wolfspider
.
$ gigalixir create
Created app: eager-reasonable-wolfspider.
Set git remote: gigalixir.
eager-reasonable-wolfspider
And confirm that it was created by running gigalixir apps
.
$ gigalixir apps
[
{
"cloud": "gcp",
"region": "v2018-us-central1",
"replicas": 0,
"size": 0.5,
"stack": "gigalixir-20",
"unique_name": "eager-reasonable-wolfspider",
"version": 2
}
]
Our app will need a database so let’s create one. Because this is a demo application we’ll use the free tier, which isn’t suitable for a production app, but will work for our example.
$ gigalixir pg:create --free
...
Let’s confirm that the DATABASE_URL
and POOL_SIZE
environment variables were set, which we can do with gigalixir config
.
$ gigalixir config
{
"DATABASE_URL": "ecto://...",
"POOL_SIZE": "2"
}
Great, with that we can deploy to Gigalixir.
$ git push gigalixir master
...
It looks like everything worked. We can see from the logs that our app should now be accessible at “eager-reasonable-wolfspider.gigalixirapp.com”. Because your app will have a different name, the URL printed here will be different. Let’s open that URL - <our Gigalixir app name>.gigalixirapp.com
- in the browser. And great - we see our app is deployed to Gigalixir!
This is great. Now let’s see how we can deploy changes to our application. Let’s update our app to include a blog. We’ll go back to the command line. And we’ll run mix phx.gen.html
with a Blog
context, a Post
schema and plural posts
for the table name. And let’s give our posts a title
and body
.
$ mix phx.gen.html Blog Post posts title body
* creating lib/teacher_web/controllers/post_controller.ex
* creating lib/teacher_web/templates/post/edit.html.heex
* creating lib/teacher_web/templates/post/form.html.heex
* creating lib/teacher_web/templates/post/index.html.heex
* creating lib/teacher_web/templates/post/new.html.heex
* creating lib/teacher_web/templates/post/show.html.heex
* creating lib/teacher_web/views/post_view.ex
* creating test/teacher_web/controllers/post_controller_test.exs
* creating lib/teacher/blog/post.ex
* creating priv/repo/migrations/{timestamp}_create_posts.exs
* creating lib/teacher/blog.ex
* injecting lib/teacher/blog.ex
* creating test/teacher/blog_test.exs
* injecting test/teacher/blog_test.exs
* creating test/support/fixtures/blog_fixtures.ex
* injecting test/support/fixtures/blog_fixtures.ex
Add the resource to your browser scope in lib/teacher_web/router.ex:
resources "/posts", PostController
Remember to update your repository by running migrations:
$ mix ecto.migrate
Then let’s open our router.ex
and add the “/posts”
resource.
lib/teacher_web/router.ex
...
scope "/", TeacherWeb do
pipe_through :browser
resources "/posts", PostController
get "/", PageController, :index
end
...
Then let’s go back to the command line and migrate the database.
$ mix ecto.migrate
...
And we’ll start our server to confirm everything is working locally.
$ mix phx.server
...
Great everything looks good we can access the /posts
page and create a blog post. Now let’s commit our changes.
$ git add .
$ git commit -m "adds blog"
And then to deploy our changes to Gigalixir we’ll use the same command.
$ git push gigalixir master
...
It looks like everything deployed successfully so let’s open the /posts
page in production. and when we do we get an error. This is because we migrated our database in development, but haven’t done so in production. Let’s fix that. We’ll go back to the command line and to run our database migrations on Gigalixir we’ll use the gigalixir ps:migrate
command.
$ gigalixir ps:migrate
...
It looks like our migrations ran. So let’s go back to the browser and if we reload the page - perfect - our app is working. We can create blog posts in our application in production.