noahsettersten commited on
Commit
bfaed46
1 Parent(s): 29f33cd

feat: Deploy app to Fly

Browse files

This includes:
- The results of `fly launch` (initial .dockerignore, Dockerfile,
fly.toml, release.ex, and rel folder)
- Addition of `curl` to the Dockerfile
- Changes to the fly.toml to disable DB migrations on release, add a
volume, configure the Bumblebee and XLA cache directories, and add a
`ELIXIR_ERL_OPTIONS` env that I found on Fly's blog linked below.

See https://fly.io/phoenix-files/real-world-machine-learning-on-fly-gpu/

.dockerignore ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file excludes paths from the Docker build context.
2
+ #
3
+ # By default, Docker's build context includes all files (and folders) in the
4
+ # current directory. Even if a file isn't copied into the container it is still sent to
5
+ # the Docker daemon.
6
+ #
7
+ # There are multiple reasons to exclude files from the build context:
8
+ #
9
+ # 1. Prevent nested folders from being copied into the container (ex: exclude
10
+ # /assets/node_modules when copying /assets)
11
+ # 2. Reduce the size of the build context and improve build time (ex. /build, /deps, /doc)
12
+ # 3. Avoid sending files containing sensitive information
13
+ #
14
+ # More information on using .dockerignore is available here:
15
+ # https://docs.docker.com/engine/reference/builder/#dockerignore-file
16
+
17
+ .dockerignore
18
+
19
+ # Ignore git, but keep git HEAD and refs to access current commit hash if needed:
20
+ #
21
+ # $ cat .git/HEAD | awk '{print ".git/"$2}' | xargs cat
22
+ # d0b8727759e1e0e7aa3d41707d12376e373d5ecc
23
+ .git
24
+ !.git/HEAD
25
+ !.git/refs
26
+
27
+ # Common development/test artifacts
28
+ /cover/
29
+ /doc/
30
+ /test/
31
+ /tmp/
32
+ .elixir_ls
33
+
34
+ # Mix artifacts
35
+ /_build/
36
+ /deps/
37
+ *.ez
38
+
39
+ # Generated on crash by the VM
40
+ erl_crash.dump
41
+
42
+ # Static artifacts - These should be fetched and built inside the Docker image
43
+ /assets/node_modules/
44
+ /priv/static/assets/
45
+ /priv/static/cache_manifest.json
Dockerfile ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian
2
+ # instead of Alpine to avoid DNS resolution issues in production.
3
+ #
4
+ # https://hub.docker.com/r/hexpm/elixir/tags?page=1&name=ubuntu
5
+ # https://hub.docker.com/_/ubuntu?tab=tags
6
+ #
7
+ # This file is based on these images:
8
+ #
9
+ # - https://hub.docker.com/r/hexpm/elixir/tags - for the build image
10
+ # - https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye-20231009-slim - for the release image
11
+ # - https://pkgs.org/ - resource for finding needed packages
12
+ # - Ex: hexpm/elixir:1.16.0-erlang-26.2.1-debian-bullseye-20231009-slim
13
+ #
14
+ ARG ELIXIR_VERSION=1.16.0
15
+ ARG OTP_VERSION=26.2.1
16
+ ARG DEBIAN_VERSION=bullseye-20231009-slim
17
+
18
+ ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
19
+ ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
20
+
21
+ FROM ${BUILDER_IMAGE} as builder
22
+
23
+ # install build dependencies
24
+ RUN apt-get update -y && apt-get install -y build-essential git curl \
25
+ && apt-get clean && rm -f /var/lib/apt/lists/*_*
26
+
27
+ # prepare build dir
28
+ WORKDIR /app
29
+
30
+ # install hex + rebar
31
+ RUN mix local.hex --force && \
32
+ mix local.rebar --force
33
+
34
+ # set build ENV
35
+ ENV MIX_ENV="prod"
36
+
37
+ # install mix dependencies
38
+ COPY mix.exs mix.lock ./
39
+ RUN mix deps.get --only $MIX_ENV
40
+ RUN mkdir config
41
+
42
+ # copy compile-time config files before we compile dependencies
43
+ # to ensure any relevant config change will trigger the dependencies
44
+ # to be re-compiled.
45
+ COPY config/config.exs config/${MIX_ENV}.exs config/
46
+ RUN mix deps.compile
47
+
48
+ COPY priv priv
49
+
50
+ COPY lib lib
51
+
52
+ COPY assets assets
53
+
54
+ # compile assets
55
+ RUN mix assets.deploy
56
+
57
+ # Compile the release
58
+ RUN mix compile
59
+
60
+ # Changes to config/runtime.exs don't require recompiling the code
61
+ COPY config/runtime.exs config/
62
+
63
+ COPY rel rel
64
+ RUN mix release
65
+
66
+ # start a new build stage so that the final image will only contain
67
+ # the compiled release and other runtime necessities
68
+ FROM ${RUNNER_IMAGE}
69
+
70
+ RUN apt-get update -y && \
71
+ apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates \
72
+ && apt-get clean && rm -f /var/lib/apt/lists/*_*
73
+
74
+ # Set the locale
75
+ RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
76
+
77
+ ENV LANG en_US.UTF-8
78
+ ENV LANGUAGE en_US:en
79
+ ENV LC_ALL en_US.UTF-8
80
+
81
+ WORKDIR "/app"
82
+ RUN chown nobody /app
83
+
84
+ # set runner ENV
85
+ ENV MIX_ENV="prod"
86
+
87
+ # Only copy the final release from the build stage
88
+ COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/medical_transcription ./
89
+
90
+ USER nobody
91
+
92
+ # If using an environment that doesn't automatically reap zombie processes, it is
93
+ # advised to add an init process such as tini via `apt-get install`
94
+ # above and adding an entrypoint. See https://github.com/krallin/tini for details
95
+ # ENTRYPOINT ["/tini", "--"]
96
+
97
+ CMD ["/app/bin/server"]
fly.toml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # fly.toml app configuration file generated for medical-transcription-cpu on 2024-01-22T15:15:29-06:00
2
+ #
3
+ # See https://fly.io/docs/reference/configuration/ for information about how to use this file.
4
+ #
5
+
6
+ app = "medical-transcription-cpu"
7
+ primary_region = "ord"
8
+ kill_signal = "SIGTERM"
9
+ # vm.size = "a100-40gb"
10
+
11
+ [build]
12
+
13
+ # [deploy]
14
+ # release_command = "/app/bin/migrate"
15
+
16
+ [[mounts]]
17
+ source = "data"
18
+ destination = "/data"
19
+ initial_size = "40gb"
20
+
21
+ [env]
22
+ ELIXIR_ERL_OPTIONS = "-proto_dist inet6_tcp +sssdio 128"
23
+ BUMBLEBEE_CACHE_DIR="/data/cache/bumblebee"
24
+ XLA_CACHE_DIR="/data/cache/xla"
25
+ # XLA_TARGET="cuda120"
26
+ PHX_HOST = "medical-transcription-cpu.fly.dev"
27
+ PORT = "8080"
28
+
29
+ [http_service]
30
+ internal_port = 8080
31
+ force_https = true
32
+ auto_stop_machines = false
33
+ auto_start_machines = false
34
+ min_machines_running = 0
35
+ processes = ["app"]
36
+ [http_service.concurrency]
37
+ type = "connections"
38
+ hard_limit = 1000
39
+ soft_limit = 1000
40
+
41
+ [[vm]]
42
+ cpu_kind = "shared"
43
+ cpus = 2
44
+ memory_mb = 4096
lib/medical_transcription/release.ex ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule MedicalTranscription.Release do
2
+ @moduledoc """
3
+ Used for executing DB release tasks when run in production without Mix
4
+ installed.
5
+ """
6
+ @app :medical_transcription
7
+
8
+ def migrate do
9
+ load_app()
10
+
11
+ for repo <- repos() do
12
+ {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
13
+ end
14
+ end
15
+
16
+ def rollback(repo, version) do
17
+ load_app()
18
+ {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
19
+ end
20
+
21
+ defp repos do
22
+ Application.fetch_env!(@app, :ecto_repos)
23
+ end
24
+
25
+ defp load_app do
26
+ Application.load(@app)
27
+ end
28
+ end
rel/env.sh.eex ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+
3
+ # configure node for distributed erlang with IPV6 support
4
+ export ERL_AFLAGS="-proto_dist inet6_tcp"
5
+ export ECTO_IPV6="true"
6
+ export DNS_CLUSTER_QUERY="${FLY_APP_NAME}.internal"
7
+ export RELEASE_DISTRIBUTION="name"
8
+ export RELEASE_NODE="${FLY_APP_NAME}-${FLY_IMAGE_REF##*-}@${FLY_PRIVATE_IP}"
rel/overlays/bin/migrate ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ #!/bin/sh
2
+ cd -P -- "$(dirname -- "$0")"
3
+ exec ./medical_transcription eval MedicalTranscription.Release.migrate
rel/overlays/bin/migrate.bat ADDED
@@ -0,0 +1 @@
 
 
1
+ call "%~dp0\medical_transcription" eval MedicalTranscription.Release.migrate
rel/overlays/bin/server ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ #!/bin/sh
2
+ cd -P -- "$(dirname -- "$0")"
3
+ PHX_SERVER=true exec ./medical_transcription start
rel/overlays/bin/server.bat ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ set PHX_SERVER=true
2
+ call "%~dp0\medical_transcription" start