From ea4d665d3c34ff00756d84a49b71dd1627996bef Mon Sep 17 00:00:00 2001 From: nelsonic Date: Sun, 2 Jan 2022 23:45:07 +0000 Subject: [PATCH] add Dockerfile, .dockerignore, release.ex & fly.toml for deploy to fly.io #172 --- .dockerignore | 2 ++ Dockerfile | 76 +++++++++++++++++++++++++++++++++++++++++++++ fly.toml | 37 ++++++++++++++++++++++ lib/auth/release.ex | 28 +++++++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 fly.toml create mode 100644 lib/auth/release.ex diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..c9175f8c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +assets/node_modules/ +deps/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..ec89de20 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,76 @@ +### +### Fist Stage - Building the Release +### +FROM hexpm/elixir:1.12.1-erlang-24.0.1-alpine-3.13.3 AS build + +# install build dependencies +RUN apk add --no-cache build-base npm + +# prepare build dir +WORKDIR /app + +# extend hex timeout +ENV HEX_HTTP_TIMEOUT=20 + +# install hex + rebar +RUN mix local.hex --force && \ + mix local.rebar --force + +# set build ENV as prod +ENV MIX_ENV=prod +ENV SECRET_KEY_BASE=nokey + +# Copy over the mix.exs and mix.lock files to load the dependencies. If those +# files don't change, then we don't keep re-fetching and rebuilding the deps. +COPY mix.exs mix.lock ./ +COPY config config + +RUN mix deps.get --only prod && \ + mix deps.compile + +# install npm dependencies +# COPY assets/package.json assets/package-lock.json ./assets/ +# RUN npm --prefix ./assets ci --progress=false --no-audit --loglevel=error + +COPY priv priv +COPY assets assets + +# NOTE: If using TailwindCSS, it uses a special "purge" step and that requires +# the code in `lib` to see what is being used. Uncomment that here before +# running the npm deploy script if that's the case. +# COPY lib lib + +# build assets +# RUN npm run --prefix ./assets deploy +RUN mix assets.deploy +RUN mix phx.digest + +# copy source here if not using TailwindCSS +COPY lib lib + +# compile and build release +COPY rel rel +RUN mix do compile, release + +### +### Second Stage - Setup the Runtime Environment +### + +# prepare release docker image +FROM alpine:3.13.3 AS app +RUN apk add --no-cache libstdc++ openssl ncurses-libs + +WORKDIR /app + +RUN chown nobody:nobody /app + +USER nobody:nobody + +COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/hits ./ + +ENV HOME=/app +ENV MIX_ENV=prod +ENV SECRET_KEY_BASE=nokey +ENV PORT=4000 + +CMD ["bin/hits", "start"] \ No newline at end of file diff --git a/fly.toml b/fly.toml new file mode 100644 index 00000000..5982f3c8 --- /dev/null +++ b/fly.toml @@ -0,0 +1,37 @@ +# fly.toml file generated + +app = "authprod" + +kill_signal = "SIGTERM" +kill_timeout = 5 + +[env] + +[deploy] + release_command = "/app/bin/authprod eval Auth.Release.migrate" + +[[services]] + # http_checks = [] + internal_port = 4000 + # processes = ["app"] + protocol = "tcp" + # script_checks = [] + + [services.concurrency] + hard_limit = 25 + soft_limit = 20 + # type = "connections" + + [[services.ports]] + handlers = ["http"] + port = 80 + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 + + [[services.tcp_checks]] + grace_period = "30s" + interval = "15s" + restart_limit = 6 + timeout = "2s" diff --git a/lib/auth/release.ex b/lib/auth/release.ex new file mode 100644 index 00000000..b932f012 --- /dev/null +++ b/lib/auth/release.ex @@ -0,0 +1,28 @@ +defmodule Auth.Release do + @moduledoc """ + Used for executing DB release tasks when run in production without Mix + installed. + """ + @app :authprod + + def migrate do + load_app() + + for repo <- repos() do + {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true)) + end + end + + def rollback(repo, version) do + load_app() + {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version)) + end + + defp repos do + Application.fetch_env!(@app, :ecto_repos) + end + + defp load_app do + Application.load(@app) + end +end