How to Deploy an App
Deploying an app is done using a git push, the same way you would push code to github. For more information about how this works, see Life of a Deploy.
git push gigalixir
How to Clean your Build Cache
There is an extra flag you can pass to clean your cache before building in case you need it, but you need git 2.9.0 or higher for it to work.
For information on how to install the latest version of git on Ubuntu, see this stackoverflow question.
git -c http.extraheader="GIGALIXIR-CLEAN: true" push gigalixir
How to Set Up Zero-Downtime Deploys
Normally, there is nothing you need to do to have zero-downtime deploys.
The only caveat is that health checks are currently done by checking if tcp port 4000 is listening. If your app opens the port before it is ready, then it may start receiving traffic before it is ready to serve it. In most cases, with Phoenix, this isn’t a problem.
One downside of zero-downtime deploys is that they make deploys slower.
What happens during a deploy is
- Spawn a new instance
- Wait for health check on the new instance to pass
- Start sending traffic to the new instance
- Stop sending traffic to the old instance
- Wait 30 seconds for old instance is finish processing requests
- Terminate the old instance
- Repeat for every instance
Although you should see your new code running within a few seconds, the entire process takes over 30 seconds per instance so if you have a lot of instances running, this could take a long time.
Heroku opts for faster deploys and restarts instead of zero-downtime deploys.
How to Deploy a Branch
To deploy a local branch, my-branch
,
run
git push gigalixir my-branch:main
How to Set Up a Staging Environment
To set up a separate staging app and production app, you’ll need to create another gigalixir app. To do this, first rename your current gigalixir git remote to staging:
git remote rename gigalixir staging
Then create a new app for production:
gigalixir create
If you like, you can also rename the new app remote
:
git remote rename gigalixir production
From now on, you can run this to push to staging:
git push staging main
And this to push to production:
git push production main
You’ll probably also want to check all your environment variables and make sure they are set probably for production and staging.
Also, generally speaking, it’s best to use prod.exs
for both production and staging and let environment variables be the only thing that varies between the two environments. This way staging is as close a simulation of production as possible.
If you need to convert any configs into environment variables, use "${MYVAR}"
.
How to Set Up Continuous Integration (CI/CD)
Since deploys are just a normal git push
, Gigalixir should work with any CI/CD tool available.
For example, with Travis CI, add .travis.yml
to your codebase.
script:
- git remote add gigalixir https://$GIGALIXIR_EMAIL:$GIGALIXIR_API_KEY@git.gigalixir.com/$GIGALIXIR_APP_NAME.git
- mix test && git push -f gigalixir HEAD:refs/heads/main
language: elixir
elixir: 1.5.1
otp_release: 20.0
services:
- postgresql
before_script:
- PGPASSWORD=postgres psql -c 'create database gigalixir_getting_started_test;' -U postgres
Be sure to replace gigalixir_getting_started_test
with your test database name configured in your test.exs
file along with your db username and password.
In the Travis CI Settings, add a GIGALIXIR_EMAIL
environment variable, but be sure to URI encode it e.g. foo%40gigalixir.com
.
Add a GIGALIXIR_API_KEY
environment variable which you can find in your ~/.netrc
file e.g. b9fbde22-fb73-4acb-8f74-f0aa6321ebf7
.
Finally, add a GIGALIXIR_APP_NAME
environment variable with the name of your app e.g. real-hasty-fruitbat
Using GitLab CI or any other CI/CD service should be very similar.
Foran example GitLab CI yaml file, see this .gitlab-ci.yml file.
Using GitHub Actions is also similar. For example, see https://gist.github.com/jesseshieh/7b231370874445592a40bf5ed6961460
You might also take a look at this GitHub Action for Gigalixir: https://github.com/marketplace/actions/gigalixir-action
Using CircleCI is also similar. For an example, see this config.yml.
How to Set Up Review Apps (Feature branch apps)
Review Apps let you run a new instance for every branch and tear them down after the branch is deleted.
For GitLab CI/CD Review Apps, all you have to do is create a .gitlab-ci.yml
file that looks like this one.
Be sure to create CI/CD secrets for GIGALIXIR_EMAIL
, GIGALIXIR_PASSWORD
, and
GIGALIXIR_APP_NAME
.
For review apps run on something other than GitLab, the setup should be very similar.
How to Set the Gigalixir Git Remote
If you have a Gigalixir app already created and want to push a git repository to it, set the git remote by running:
gigalixir git:remote $APP_NAME
If you prefer to do it manually, run:
git remote add gigalixir https://git.gigalixir.com/$APP_NAME.git
How to Rollback an App
We only keep the releases for one year from when they were created - so rolling back will only work if was created less than one year ago.
To rollback one release, run the following command.
gigalixir releases:rollback
To rollback to a specific release, find the version
by listing all releases. You can see which SHA the release was built on and when it was built. This will also automatically restart your app with the new release.
gigalixir releases
You should see something like this
[
{
"created_at": "2017-04-12T17:43:28.000+00:00",
"version": "5",
"sha": "77f6c2952129ffecccc4e56ae6b27bba1e65a1e3",
"summary": "Set `DATABASE_URL` config var."
},
...
]
Then specify the version when rolling back.
gigalixir releases:rollback --version=5
The release list is immutable so when you rollback, we create a new release on top of the old releases, but the new release refers to the old slug.
Can I Deploy an App that is not at the Root of my Repository?
If you just want to push a subtree, try:
git subtree push --prefix my-sub-folder gigalixir
If you want to push the entire repo, but run the app from a subfolder, it becomes a bit trickier, but this pull request should help you -> https://github.com/jesseshieh/nonroot/pull/1/files
How to do Blue-Green or Canary Deploys?
You’ll need the CLI v1.0.19 or later.
Apps on Gigalixir can be assigned another app as its canary. An arbitrary weight can also be assigned to control the traffic between the two apps.
For example, if you have my-app
with a canary assigned to it called my-app-canary
with weight of 10, then my-app
will receive 90% of the traffic and my-app-canary
will receive 10% of the traffic.
If you want to do blue-green deploys, simply flip the traffic between 0 and 100 to control which app receives the traffic.
For example,
# create the "blue" app
gigalixir create --name my-app-blue
git remote rename gigalixir blue
# create the "green" app
gigalixir create --name my-app-green
git remote rename gigalixir green
# deploy the app to blue
git push blue main
# wait a few minutes and ensure the app is running
curl https://my-app-blue.gigalixirapp.com/
# deploy the app to green
git push green main
# wait a few minutes to ensure the app is running
curl https://my-app-green.gigalixirapp.com/
# watch the logs on both apps
gigalixir logs -a my-app-blue
gigalixir logs -a my-app-green
# set the canary, this should have no effect because the weight is 0
gigalixir canary:set -a my-app-blue -c my-app-green -w 0
# increase the weight to the canary
gigalixir canary:set -a my-app-blue -w 10
# ensure traffic is split as expected by watching the logs
# flip traffic completely to green
gigalixir canary:set -a my-app-blue -w 100
# ensure traffic is going totally to green by watching the logs
# to delete a canary, run
gigalixir canary:unset -a my-app-blue -c my-app-green
Notice that with canaries, only the domain for my-app-blue
gets redirected. Traffic to my-app-green.gigalixirapp.com
goes entirely to my-app-green
.
If you have custom domains defined on my-app-blue
, traffic to those will also be shaped by the canary, but custom domains on my-app-green
will still go entirely to my-app-green
.
How do I Deploy an Umbrella App?
Umbrella apps are deployed the same way, but the buildpacks need to know which internal app is your Phoenix app.
Therefore, set your phoenix_relative_path
in your phoenix_static_buildpack.config
file,
see the gigalixir-buildpack-phoenix-static configuration for more details.
When running migrations, we need to know which internal app contains
your migrations. Use the --migration_app_name
flag on gigalixir ps:migrate
.
If you have multiple Phoenix apps in the umbrella, you’ll need to use something like master_proxy to proxy requests to the two apps.
How to Deploy a Ruby App
gigalixir login
git clone https://github.com/heroku/ruby-getting-started.git
cd ruby-getting-started
APP=$(gigalixir create)
git push gigalixir
curl https://$APP.gigalixirapp.com/
Does Gigalixir have any web hooks?
We haven’t built-in any web hooks, but most of what you need can be accomplished with buildpacks at build time or modifying your Procfile.
To hit a web hook when building your app, you can use https://github.com/jesseshieh/buildpack-webhook.
For runtime prestart hooks, see Can I use a Custom Procfile? You can add any command you like.