Browse Source

add logic for building from distillery.

jackyalcine 6 months ago
parent
commit
e678db6787
Signed by: Jacky Alciné <yo@jacky.wtf> GPG Key ID: 537A4F904B15268D

+ 1
- 2
.lvimrc View File

@@ -8,8 +8,7 @@ if exists(':DirenvExport')
8 8
 endif
9 9
 
10 10
 let s:command_prefix = 'docker-compose run ' .
11
-      \ '-e CANONICAL_HOST="koype_vim_test" '.
12
-      \ '-e CANONICAL_SCHEME="http" '.
11
+      \ '-e CANONICAL_URL="http://koype_vim_test" '.
13 12
       \ '-e MIX_ENV="test" ' .
14 13
       \ '-e DOC=1 ' .
15 14
       \ '-e OBJECT_STORAGE_BUCKET="koype-test" '.

+ 2
- 2
Dockerfile View File

@@ -1,7 +1,7 @@
1
-FROM elixir:1.7.4-alpine
1
+FROM elixir:1.8.0-alpine
2 2
 LABEL maintainer Jacky Alcine <yo@jacky.wtf>
3 3
 
4
-ARG MIX_ENV
4
+ARG MIX_ENV=prod
5 5
 
6 6
 ENV MIX_ENV=${MIX_ENV:-prod} \
7 7
   TZ=Etc/UTC \

+ 0
- 82
Dockerfile.build View File

@@ -1,82 +0,0 @@
1
-# The version of Alpine to use for the final image
2
-# This should match the version of Alpine that the `elixir:1.7.2-alpine` image uses
3
-ARG ALPINE_VERSION=3.8
4
-
5
-FROM elixir:1.7.2-alpine AS builder
6
-
7
-# The following are build arguments used to change variable parts of the image.
8
-# The name of your application/release (required)
9
-ARG APP_NAME
10
-# The version of the application we are building (required)
11
-ARG APP_VSN
12
-# The environment to build with
13
-ARG MIX_ENV=prod
14
-# Set this to true if this release is not a Phoenix app
15
-ARG SKIP_PHOENIX=false
16
-# If you are using an umbrella project, you can change this
17
-# argument to the directory the Phoenix app is in so that the assets
18
-# can be built
19
-ARG PHOENIX_SUBDIR=.
20
-
21
-ENV SKIP_PHOENIX=${SKIP_PHOENIX} \
22
-  APP_NAME=${APP_NAME} \
23
-  APP_VSN=${APP_VSN} \
24
-  MIX_ENV=${MIX_ENV}
25
-
26
-# By convention, /opt is typically used for applications
27
-WORKDIR /opt/app
28
-
29
-# This step installs all the build tools we'll need
30
-RUN apk update && \
31
-      apk upgrade --no-cache && \
32
-      apk add --no-cache \
33
-      nodejs \
34
-      yarn \
35
-      git \
36
-      build-base && \
37
-      mix local.rebar --force && \
38
-      mix local.hex --force
39
-
40
-# This copies our app source code into the build container
41
-COPY . .
42
-
43
-RUN mix do deps.get, deps.compile, compile
44
-
45
-# This step builds assets for the Phoenix app (if there is one)
46
-# If you aren't building a Phoenix app, pass `--build-arg SKIP_PHOENIX=true`
47
-# This is mostly here for demonstration purposes
48
-RUN if [ ! "$SKIP_PHOENIX" = "true" ]; then \
49
-      cd ${PHOENIX_SUBDIR}/assets && \
50
-      yarn install && \
51
-      yarn deploy && \
52
-      cd .. && \
53
-      mix phx.digest; \
54
-      fi
55
-
56
-RUN \
57
-      mkdir -p /opt/built && \
58
-      mix release --verbose && \
59
-      cp _build/${MIX_ENV}/rel/${APP_NAME}/releases/${APP_VSN}/${APP_NAME}.tar.gz /opt/built && \
60
-      cd /opt/built && \
61
-      tar -xzf ${APP_NAME}.tar.gz && \
62
-      rm ${APP_NAME}.tar.gz
63
-
64
-# From this line onwards, we're in a new image, which will be the image used in production
65
-FROM alpine:${ALPINE_VERSION}
66
-
67
-# The name of your application/release (required)
68
-ARG APP_NAME
69
-
70
-RUN apk update && \
71
-      apk add --no-cache \
72
-      bash \
73
-      openssl-dev
74
-
75
-ENV REPLACE_OS_VARS=true \
76
-  APP_NAME=${APP_NAME}
77
-
78
-WORKDIR /opt/app
79
-
80
-COPY --from=builder /opt/built .
81
-
82
-CMD trap 'exit' INT; /opt/app/bin/${APP_NAME} foreground

+ 1
- 1
Dockerfile.dev View File

@@ -1,4 +1,4 @@
1
-FROM elixir:1.7.1-alpine
1
+FROM elixir:1.8.0-alpine
2 2
 LABEL maintainer Jacky Alcine <yo@jacky.wtf>
3 3
 
4 4
 ARG MIX_ENV

+ 9
- 10
config/config.exs View File

@@ -1,10 +1,7 @@
1 1
 use Mix.Config
2 2
 
3 3
 config :koype,
4
-  domain: %{
5
-    host: {:system, :string, "CANONICAL_HOST", "localhost"},
6
-    scheme: {:system, :string, "CANONICAL_SCHEME", "http"}
7
-  },
4
+  canonical_url: {:system, :string, "CANONICAL_URL", "http://localhost"},
8 5
   environment: {:system, :atom, "ENV", "dev"},
9 6
   ecto_repos: [Koype.Repo],
10 7
   session_signing_salt:
@@ -13,7 +10,9 @@ config :koype,
13 10
 
14 11
 config :koype, Koype.Web.Endpoint,
15 12
   http: [port: {:system, :integer, "PORT", 5000}],
16
-  secret_key_base: {:system, :string, "SECRET_KEY_BASE"},
13
+  secret_key_base:
14
+    {:system, :string, "SECRET_KEY_BASE",
15
+     32 |> :crypto.strong_rand_bytes() |> Base.encode64(case: :lower, padding: false)},
17 16
   render_errors: [
18 17
     view: Koype.Web.ErrorView,
19 18
     layout: {Koype.Web.LayoutView, "simple.html"},
@@ -39,15 +38,17 @@ config :koype, Koype.Repo,
39 38
   migration_timestamsp: [type: :utc_datetime],
40 39
   db_timeout: 30_000,
41 40
   pool_timeout: 60_000,
42
-  pool_size: 128,
43
-  log: true,
44
-  database: "priv/repo/db/#{Mix.env()}.db"
41
+  pool_size: 1,
42
+  log: false,
43
+  database: {:system, :string, "DATABASE_FILE_PATH", "priv/repo/db/#{Mix.env()}.db"}
45 44
 
46 45
 config :seedex,
47 46
   repo: Koype.Repo
48 47
 
49 48
 config :guardian, Guardian.DB, repo: Koype.Repo
50 49
 
50
+config :mnesia, dir: 'priv/mnesia/#{Mix.env()}/#{node()}'
51
+
51 52
 config :phoenix, :format_encoders, json: Jason
52 53
 
53 54
 config :phoenix,
@@ -88,8 +89,6 @@ config :koype, :phoenix_swagger,
88 89
 config :liquid, error_mode: :strict
89 90
 config :logger, :console, metadata: :all
90 91
 
91
-config :mnesia, dir: 'priv/mnesia/#{Mix.env()}/#{node()}'
92
-
93 92
 config :indieweb,
94 93
   webmention_url_adapter: Koype.Webmention.URIAdapter,
95 94
   auth_adapter: IndieWeb.Auth.Adapters.Default

+ 4
- 0
docker/scripts/build-release.sh View File

@@ -0,0 +1,4 @@
1
+#!/usr/bin/env sh
2
+
3
+echo " ---> [release] Building..."
4
+mix release --verbose --env=${MIX_ENV}

+ 6
- 1
docker/scripts/entrypoint.sh View File

@@ -1,4 +1,9 @@
1 1
 #!/bin/sh
2 2
 
3 3
 cd /opt/koype || exit 10
4
-mix phx.server
4
+
5
+if [ "prod" == $MIX_ENV ]; then
6
+  _build/prod/rel/koype/bin/koype
7
+else
8
+  mix phx.server
9
+fi

+ 15
- 0
docs/RELEASE.markdown View File

@@ -0,0 +1,15 @@
1
+# Releasing Koype
2
+
3
+Koype makes use of both [Distillery][] and [Docker][] to provide a containerized
4
+version of itself as well as a self-contained tarball with everything it'd need
5
+to run on one's machine.
6
+
7
+## Using from Docker
8
+
9
+Using Docker to run and deploy Koype works as follows:
10
+
11
+```shell
12
+$ docker run -e CANONICAL_URL="https://jacky.wtf" black.af/koype:0.0.12
13
+```
14
+
15
+That'll be enough to get the underyling system up and running.

+ 2
- 1
lib/application.ex View File

@@ -46,6 +46,7 @@ defmodule Koype.Application do
46 46
   def load_runtime_config() do
47 47
     [
48 48
       :arc,
49
+      :mnesia,
49 50
       :cowboy,
50 51
       :ex_aws,
51 52
       :ex_aws_s3,
@@ -54,7 +55,7 @@ defmodule Koype.Application do
54 55
       :indieweb,
55 56
       :koype,
56 57
       :phoenix,
57
-      :guardian
58
+      :guardian,
58 59
     ]
59 60
     |> Enum.each(&Confex.resolve_env!/1)
60 61
   end

+ 2
- 4
lib/koype.ex View File

@@ -23,10 +23,8 @@ defmodule Koype do
23 23
 
24 24
   @spec host() :: binary()
25 25
   def host() do
26
-    case Confex.fetch_env(:koype, :domain) do
27
-      {:ok, %{host: host, scheme: scheme}} ->
28
-        scheme <> "://" <> host
29
-
26
+    case Confex.fetch_env(:koype, :canonical_url) do
27
+      {:ok, url} -> url
30 28
       _ ->
31 29
         Koype.Web.Endpoint.url()
32 30
     end

+ 9
- 7
lib/metrics.ex View File

@@ -2,7 +2,7 @@ defmodule Koype.Metrics do
2 2
   use GenServer
3 3
   require Logger
4 4
 
5
-  @interval :timer.minutes(10)
5
+  @interval :timer.minutes(5)
6 6
 
7 7
   def start_link() do
8 8
     GenServer.start_link(__MODULE__, [], name: __MODULE__)
@@ -31,14 +31,16 @@ defmodule Koype.Metrics do
31 31
     state
32 32
   end
33 33
 
34
+  # TODO: Move collection into [mod.func/1] in a Task.async_stream
34 35
   def compute(pid, state) do
35
-    entry_count = Koype.Repo.Entry |> Koype.Repo.count() |> Integer.to_string()
36
-    webmention_count = Koype.Repo.Webmention |> Koype.Repo.count() |> Integer.to_string()
37
-    last_updated_at = Calendar.DateTime.now_utc() |> Calendar.DateTime.Format.rfc3339(3)
36
+    Logger.info("Computing information about Koype...")
37
+
38
+    [
39
+      Koype.Metrics.NodeInfo
40
+    ]
41
+    |> Task.async_stream(fn mod -> mod.collect() end, timeout: @interval, on_timeout: :kill_task)
42
+    |> Stream.run()
38 43
 
39
-    Koype.Setting.set("nodeinfo:localPosts", entry_count)
40
-    Koype.Setting.set("nodeinfo:localComments", webmention_count)
41
-    Koype.Setting.set("nodeinfo:lastUpdatedAt", last_updated_at)
42 44
     Logger.info("Statistical information about Koype computed.")
43 45
     schedule(pid, state)
44 46
   end

+ 12
- 0
lib/metrics/nodeinfo.ex View File

@@ -0,0 +1,12 @@
1
+defmodule Koype.Metrics.NodeInfo do
2
+  def collect() do
3
+    entry_count = Koype.Repo.Entry |> Koype.Repo.count() |> Integer.to_string()
4
+    webmention_count = Koype.Repo.Webmention |> Koype.Repo.count() |> Integer.to_string()
5
+    last_updated_at = Calendar.DateTime.now_utc() |> Calendar.DateTime.Format.rfc3339(3)
6
+
7
+    Koype.Setting.set("nodeinfo:localPosts", entry_count)
8
+    Koype.Setting.set("nodeinfo:localComments", webmention_count)
9
+    Koype.Setting.set("nodeinfo:lastUpdatedAt", last_updated_at)
10
+    :ok
11
+  end
12
+end

+ 0
- 13
lib/repo.ex View File

@@ -21,19 +21,6 @@ defmodule Koype.Repo do
21 21
   use Scrivener, page_size: 10
22 22
   import Ecto.Query, only: [from: 2, order_by: 2]
23 23
 
24
-  @doc """
25
-  Sets up the data repository.
26
-
27
-  For now, loads up the database system. It'll support side injection via
28
-  an environment variable.
29
-
30
-  TODO: Support switching database drivers (from SQLite to PostgreSQL) here.
31
-  """
32
-  @spec init(any(), keyword()) :: {:ok, keyword()}
33
-  def init(_, opts) do
34
-    {:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
35
-  end
36
-
37 24
   def find_in_column(query, column, value) do
38 25
     like_str = "%#{value}%"
39 26
     from(q in query, where: like(field(q, ^column), ^like_str))

+ 1
- 1
mix.exs View File

@@ -81,7 +81,7 @@ defmodule Koype.Mixfile do
81 81
       {:cabbage, "~> 0.3.0", only: :test},
82 82
       {:cachex, "~> 3.1"},
83 83
       {:calendar, "~> 0.17.4"},
84
-      {:confex, "~> 3.3", override: true},
84
+      {:confex, "~> 3.4.0", override: true},
85 85
       {:corsica, "~> 1.1.2"},
86 86
       {:credo, "~> 0.10.0", only: [:dev, :test]},
87 87
       {:dialyxir, "~> 1.0.0-rc.4", only: :dev, runtime: false},

+ 4
- 1
rel/config.exs View File

@@ -10,7 +10,9 @@ use Mix.Releases.Config,
10 10
 environment :dev do
11 11
   set(dev_mode: true)
12 12
   set(include_erts: false)
13
+  set(include_src: true)
13 14
   set(cookie: :"sZl?KdVIyFipT)V%Wc9G4p<Cq&N0}|gQH(T{gLkWrX&cSbw3PyIhG.&DrpXlAatf")
15
+  set(pre_start_hooks: "rel/hooks/pre_start")
14 16
   set(post_start_hooks: "rel/hooks/post_start")
15 17
 end
16 18
 
@@ -35,7 +37,8 @@ release :koype do
35 37
       :que,
36 38
       :arc,
37 39
       :logger,
38
-      :koype
40
+      :koype,
41
+      :mnesia
39 42
     ]
40 43
   )
41 44
 end

rel/hooks/post_configure/migrate → rel/hooks/pre_start/migrate View File


+ 3
- 23
rel/vm.args View File

@@ -2,28 +2,8 @@
2 2
 ## You can find a full list of flags and their behaviours at
3 3
 ## http://erlang.org/doc/man/erl.html
4 4
 
5
-## Name of the node
6
--name <%= release_name %>@127.0.0.1
7
-
8
-## Cookie for distributed erlang
9
--setcookie <%= release.profile.cookie %>
10
-
11
-## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive
12
-## (Disabled by default..use with caution!)
13
-+heart
14
-
15
-## Enable kernel poll and a few async threads
16
-+K true
17
-## For OTP21+, the +A flag is not used anymore,
18
-## +SDio replace it to use dirty schedulers
19
-+SDio 5
20
-
21
-## Increase number of concurrent ports/sockets
22 5
 -env ERL_MAX_PORTS 4096
23
-
24
-## Tweak GC to run more often
25 6
 -env ERL_FULLSWEEP_AFTER 10
26
-
27
-# Enable SMP automatically based on availability
28
-# On OTP21+, this is not needed anymore.
29
-# -smp auto
7
+-sname <%= release_name %>@${HOSTNAME}
8
+-setcookie <%= release.profile.cookie %>
9
+-smp auto

+ 1
- 1
web/plug/client/cors.ex View File

@@ -36,7 +36,7 @@ defmodule Koype.Web.Plug.Client.CORS do
36 36
 
37 37
   def valid_origin?(host) do
38 38
     port = Koype.Web.Endpoint.config(:http) |> Keyword.get(:port)
39
-    full_host = Koype.host() <> ":" <> port
39
+    full_host = "#{Koype.host()}:#{port}" |> URI.parse |> URI.to_string
40 40
 
41 41
     cond do
42 42
       host == full_host -> true

Loading…
Cancel
Save