KristerV

KristerV

How To deploy to DigitalOcean app platform with managed database

took me days to figure this out (with the help of you guys in Slack) so logging this down for future me. make sure you read the whole thing first and then deploy. you may want to change the order that you do this.

1. Get a Dockerfile

I had one from fly launch already.

1.1 Change the CMD

i changed my CMD to be

CMD ["/bin/bash", "-c", "/app/bin/migrate && /app/bin/server"]

you can also define your migrate/server command in the DO UI settings, but since I want multiple servers this was easier.

2. Deploy a managed database

do this before the app, it just makes it easier. note that if you start with the app it will offer you to attach a development database that you can “upgrade later”, but at least for me it created a set of problems because DO’s state doesn’t update very fast. better start with what you want.

2.1 Create user and database

use the UI for this.

2.2 Change ownership

you can get the Connection String from Overview. then in bash use psql "CONNECTION_STRING" (with quotes) to get into the database server and then ALTER DATABASE your_db OWNER TO your_user; to change the owner.

3. Deploy app

connecting a git repo is easy enough, but getting the database connected is not so easy so read ahead. configuration (next steps) can be done at this stage or after you’ve already deployed.

3.1 Attach database

DO has this concept of attaching the database. It will create a DATABASE_URL env var for you (that you can change/remove), but more importantly it’ll make bindable env vars available like ${your_db.CA_CERT}.

3.2 Set env vars

Find the env vars for your app (and it’s not under App).

Here’s what you need:

DATABASE_URL=${your_db.DATABASE_URL}
DATABASE_HOSTNAME=${your_db.HOSTNAME}
DATABASE_CA_CERT=${your_db.CA_CERT}
SECRET_KEY_BASE=[mix phx.gen]
PHX_HOST=[your_domain]

3.3 Configuration in elixir

this took me the most amount of time. I’ll paste, then explain. the base is stock phoenix.

 config :boocs, Boocs.Repo,
    ssl: true,
    ssl_opts: [
      verify: :verify_peer,
      cacerts: [
        System.get_env("DATABASE_CA_CERT")
        |> then(fn pem ->
          [{_type, der, _info}] = :public_key.pem_decode(pem)
          der
        end)
      ],
      server_name_indication: System.get_env("DATABASE_HOSTNAME") |> to_charlist(),
      customize_hostname_check: [
        match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
      ]
    ],
    url: database_url,
    pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
    migration_timestamps: [type: :utc_datetime_usec],
    migration_lock: nil,
    queue_target: 5000

  # socket_options: maybe_ipv6

SSL is required and it took me a long time which exact commands were required for it to work properly.

queue_target and the preceding 3 values were an interesting one. my initial migrations kept failing with something about connection pool timing out. even with ~200 connections allowed on the database side it crashed with this vague error. upgrading the DB to a $1000 server worked, but it made no sense. ultimately queue_target is what fixed it and I guess it had to do with the app server being too fast with it’s commands and the DB not answering fast enough.

DO doesn’t support IPV6. as far as I can tell. even though the ipv6 setting from phoenix is a “maybe” then removing this line still fixed an error I was stuck on for hours. it’s probably got something to do with the fact that fly did use ipv6 and the Dockerfile is form there.

Done

I’m not a devops guy and i do wish i could have stuck with fly, but at least it’s done now and ultimately DO is running a great service so happy to give it a go.

happy to answer any questions.

Where Next?

Popular in Discussions Top

kostonstyle
Hi all How can I compare haskell with elixir, included tools, webservices, ect. Thanks
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31307 143
New
sergio
There’s a new TIOBE index report that came out that shows Elixir is still not in the top 50 used languages. It also goes on to call Elix...
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19365 150
New
rower687
Hi all, I’ve been reading a lot about the “let it crash” term and how supervising processes and the whole messaging passing make an elixi...
New
New
Qqwy
Looking at the stacks that existing large companies have used, WhatsApp internally uses Mnesia to store the messages, while Discord uses ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement