Last time we created a Docker image and ran a container based on it. Now we'll deploy our Elixir Release Docker image in DigitalOcean.
There are several approaches to this:
- Let DigitalOcean access directly your GitHub or GitLab repository
- Put the image in Docker public registry where DigitalOcean can fetch it
- Put the image in DigitalOcean own Container Registry
In this article we'll use the first approach
Create a repository
I'll show how to do it in GitHub but should be similarly easy in GitLab
GitHub
Create a new repository
push the code:
git remote add origin git@github.com:miguelcoba/saturn.git
git branch -M main
git push -u origin main
Prepare to deploy to DigitalOcean
DigitalOcean requires some changes to our code in order to correctly connect to the DB from our Docker application.
So far we have been establishing a plain, unencrypted connections between the application and the database. This won't work for DigitalOcean as they strictly enforce SSL when connecting to the database.
In our case, that means that we need to enable SSL on the application side every time we open a connection to the database.
First thing is to configure the Repo to use ssl. Open runtime.ex
and uncomment the ssl: true
line on the Repo
section:
config :saturn, Saturn.Repo,
ssl: true,
# socket_options: [:inet6],
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
This will enable SSL for all the connections in the pool that the repository uses to connect to the database.
We need to change the Saturn.Release
module that we use to run the migrations, because that also opens a connection to the database and we need it to start the ssl
application at the beginning.
Change the load_app
function in the Saturn.Release
module to be like this:
defp load_app do
Application.ensure_all_started(:ssl)
Application.load(@app)
end
This will ensure the ssl application is started before trying to connect to the database to run the migrations.
We need to commit this changes to the repository. DigitalOcean works by deploying a specific branch from our repository and building the Docker image with what it finds in that branch. If you plan to use Docker as your production environment then is fine to commit this to the main branch and setup DigitalOcean to use the main branch for deployment.
For this example, I will use a different branch to commit these changes and configure DigitalOcean to use that branch. I'll use a branch named digital-ocean-deployment
git checkout -b digital-ocean-deployment
git add .
git commit -m "Setup for deploying to DigitalOcean"
git push -u origin digital-ocean-deployment
Creating an App in DigitalOcean
Let's do the deployment to DigitalOcean.
Go to your DigitalOcean dashboard and create a new App:
Select GitHub on the "Choose Source" screen:
The first time you do this, GitHub will require you to authorize DigitalOcean to access your repositories. Follow the instructions and give access to the repository you just created
You'll get back to the "Choose source" and you'll see the list of authorized repositories there
Select your repository and you'll see that the main
branch is selected automatically
If you're using main
that's fine. For this article, I'll change it to the digital-ocean-deployment
branch:
Click Next to move to the "Configure your app" page:
We need to configure the environment variables that DigitalOcean will provide to our Docker container in runtime. We can omit the PORT
environment variable as DigitalOcean automatically provides it. We have to create the POOL_SIZE
, DATABASE_URL
, and SECRET_KEY_BASE
. Let's start with the last one.
Click on the Edit link in the "Environment Variables" section. Then, in a terminal execute this command:
mix phx.gen.secret
Add a variable named SECRET_KEY_BASE and put the value you got from the command in it. Check the "Encrypt" option.
Now create a POOL_SIZE
with value 2 and a DATABASE_URL with value ${db.DATABASE_URL}
. These two don't need to be encrypted.
We need to create a database. Click on the "Add a Database" button:
Accept the default values for the database and now you're ready to create the App in DigitalOcean.
One thing to note: the DATABASE_URL environment variable is referring to this database we just created. It will be replaced with the correct value to connect to this database when the application starts.
Click next to proceed to the "Name your web service" page:
Accept the defaults and click Next. You're now in the "Finalize and launch" page:
Click the "Launch Basic App" and you'll see your app being created.
DigitalOcean will now:
- Access your repository
- Clone it,
- Detect the
Dockerfile
in it - Build a Docker image from it
- Push it to their own Container Registry
- Provision the database
- Set up environment variables
- Provision a server to run the Docker container
- Run the application
You can check the progress by inspecting the logs:
At the end you'll have your app deployed:
Run the migrations
You can access the elixir container console and run the migrations. Go to the "Console" tab and there evaluate the following command:
bin/saturn eval "Saturn.Release.migrate"
You'll see something like this:
Finally, visit the application by clicking the "Live App" button:
You'll see your app running in DigitalOcean's infrastructure:
We are done!
Source code
The source code for the saturn project is open source under the MIT license. Use the digital-ocean-deployment
branch.
About
I'm Miguel Cobá. I write about Elixir, Elm, Software Development, and eBook writing.
- Follow me on Twitter
- Subscribe to my newsletter
- Read all my articles on my blog
- Get my books:
Top comments (0)