Compare commits

...

5 Commits

Author SHA1 Message Date
8c3e7b3ee8 Merge tag '0.7.1' into develop
Working BeetRound server with configuration for prod environment.
2026-02-21 11:56:44 +01:00
2186a7509c Merge branch 'release/0.7.1' 2026-02-21 11:55:49 +01:00
41e32e3ff1 Configured for release on prod environment. 2026-02-21 11:55:23 +01:00
0b364f19c2 Added uberspace deployment info to README.md 2026-02-21 11:35:42 +01:00
4f38eb36f1 Disabled login and logout for users. 2026-02-21 11:27:46 +01:00
8 changed files with 143 additions and 90 deletions

122
README.md
View File

@ -2,17 +2,123 @@
To start your Phoenix server:
* Run `mix setup` to install and setup dependencies
* Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server`
- Run `mix setup` to install and setup dependencies
- Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server`
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html).
## Learn more
# Deployment on new uberspace asteroid
* Official website: https://www.phoenixframework.org/
* Guides: https://hexdocs.pm/phoenix/overview.html
* Docs: https://hexdocs.pm/phoenix
* Forum: https://elixirforum.com/c/phoenix-forum
* Source: https://github.com/phoenixframework/phoenix
## Initial deployment
### Add subdomain
uberspace web domain add beetround.example.com
### Init database
Follow guide to initialize postgresql database:
https://lab.uberspace.de/guide_postgresql/
#### Configure database
createuser beetround_admin -P
createdb --encoding=UTF8 --owner=beetround_admin --template=template0 beetround_server
## Configure Elixir/Phoenix
uberspace tools version use erlang 27
## Build & run BeetRound
cd ~/
mkdir develop
git clone https://git.working-copy.org/bent/BeetRoundServer.git
cd develop
export MIX_ENV=prod
mix deps.get
mix phx.gen.secret
export SECRET_KEY_BASE=<SECRET_KEY>
export DATABASE_URL=ecto://beetround_admin:<DB_PASSWORD>@localhost/beetround_server
mix assets.deploy #throws "'mix tailwind beet_round_server --minify' exited with 1" error
Workaround: copy assets from develop machine
mix compile
PHX_HOST=beetround.example.com PORT=4005 mix ecto.migrate
### Create webbackend
uberspace web backend set beetround.example.com --http --port 4005
#### Test backend
PHX_HOST=beetround.example.com PORT=4005 mix phx.server
#### Create mix release
mix release
### Create service
nvim ~/etc/services.d/beetround_server.ini
```
[program:beetround_server]
command=%(ENV_HOME)s/develop/BeetRoundServer/_build/prod/rel/beet_round_server/bin/beet_round_server
directory=%(ENV_HOME)s/develop/BeetRoundServer
autostart=true
autorestart=true
startsecs=60
environment =
MAIL_RELAY="<UBERSPACE_ASTEROID>.uberspace.de",
MAIL_ADDRESS="<MAIL_ADDRESS>",
MAIL_PW="<MAIL_PASSWORD>",
PHX_HOST="beetround.example.com",
MIX_ENV=prod,
PORT=4005,
DATABASE_URL="ecto://beetround_admin:<DB_PASSWORD>@localhost/beetround_server",
SECRET_KEY_BASE=<SECRET_KEY>
```
supervisorctl reread
supervisorctl update
supervisorctl status
## Updates (TODO old content. needs to be adjusted/checked)
Steps on develop environment:
- create new release version (with git flow)
- push main branch to repo
Steps on server:
- cd develop/SplitPot/
- pull main branch
- mix deps.get --only prod
- MIX_ENV=prod mix assets.deploy
- export BUILD_DATE="DD.MM.YYYY"
- MIX_ENV=prod mix release
- supervisorctl stop splitpot_server
- DB migrations
- export DATABASE_URL=...
- export SECRET_BASE_KEY=...
- MIX_ENV=prod mix ecto.migrate
- supervisorctl start splitpot_server

View File

@ -39,14 +39,15 @@ config :beet_round_server,
# Configures the endpoint
config :beet_round_server, BeetRoundServerWeb.Endpoint,
url: [host: "localhost"],
url: [host: "https://beetround.example.com"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: BeetRoundServerWeb.ErrorHTML, json: BeetRoundServerWeb.ErrorJSON],
layout: false
],
pubsub_server: BeetRoundServer.PubSub,
live_view: [signing_salt: "4HDgM4VC"]
live_view: [signing_salt: "4HDgM4VC"],
server: true
# Configures the mailer
#

View File

@ -6,7 +6,9 @@ import Config
# which you should run after static files are built and
# before starting your production server.
config :beet_round_server, BeetRoundServerWeb.Endpoint,
cache_static_manifest: "priv/static/cache_manifest.json"
cache_static_manifest: "priv/static/cache_manifest.json",
url: [host: "https://beetround.example.com"],
check_origin: ["https://beetround.example.com"]
# Configures Swoosh API Client
config :swoosh, api_client: Swoosh.ApiClient.Req

View File

@ -116,4 +116,20 @@ if config_env() == :prod do
# config :swoosh, :api_client, Swoosh.ApiClient.Req
#
# See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details.
mail_relay = System.get_env("MAIL_RELAY") || "example.com"
mail_address = System.get_env("MAIL_ADDRESS") || "info@example.com"
mail_pw = System.get_env("MAIL_PW") || ""
config :beet_round_server, BeetRoundServer.Mailer,
adapter: Swoosh.Adapters.SMTP,
relay: mail_relay,
username: mail_address,
password: mail_pw,
ssl: false,
ssl_opts: [verify: :verify_none],
tls_options: [verify: :verify_none],
tls: :always,
auth: :always,
port: 587,
retries: 2
end

View File

@ -32,11 +32,6 @@
</head>
<body>
<ul class="menu menu-horizontal w-full relative z-10 flex items-center gap-4 px-4 sm:px-6 lg:px-8 justify-end">
<%= if @current_scope do %>
<li>
<.link href={~p"/users/log-out"} method="delete">Log out</.link>
</li>
<% end %>
<Layouts.theme_toggle />
</ul>
{@inner_content}

View File

@ -12,81 +12,10 @@ defmodule BeetRoundServerWeb.UserLive.Login do
<.header>
<p>Log in</p>
<:subtitle>
<%= if @current_scope do %>
You need to reauthenticate to perform sensitive actions on your account.
<% else %>
Don't have an account? <.link
navigate={~p"/users/register"}
class="font-semibold text-brand hover:underline"
phx-no-format
>Sign up</.link> for an account now.
<% end %>
Bitte nutze deinen persönlichen Link der dir per Mail zugesendet wurde um dich anzumelden.
</:subtitle>
</.header>
</div>
<div :if={local_mail_adapter?()} class="alert alert-info">
<.icon name="hero-information-circle" class="size-6 shrink-0" />
<div>
<p>You are running the local mail adapter.</p>
<p>
To see sent emails, visit <.link href="/dev/mailbox" class="underline">the mailbox page</.link>.
</p>
</div>
</div>
<.form
:let={f}
for={@form}
id="login_form_magic"
action={~p"/users/log-in"}
phx-submit="submit_magic"
>
<.input
readonly={!!@current_scope}
field={f[:email]}
type="email"
label="Email"
autocomplete="email"
required
phx-mounted={JS.focus()}
/>
<.button class="btn btn-primary w-full">
Log in with email <span aria-hidden="true">→</span>
</.button>
</.form>
<div class="divider">or</div>
<.form
:let={f}
for={@form}
id="login_form_password"
action={~p"/users/log-in"}
phx-submit="submit_password"
phx-trigger-action={@trigger_submit}
>
<.input
readonly={!!@current_scope}
field={f[:email]}
type="email"
label="Email"
autocomplete="email"
required
/>
<.input
field={@form[:password]}
type="password"
label="Password"
autocomplete="current-password"
/>
<.button class="btn btn-primary w-full" name={@form[:remember_me].name} value="true">
Log in and stay logged in <span aria-hidden="true">→</span>
</.button>
<.button class="btn btn-primary btn-soft w-full mt-2">
Log in only this time
</.button>
</.form>
</div>
</Layouts.app>
"""
@ -126,6 +55,7 @@ defmodule BeetRoundServerWeb.UserLive.Login do
end
defp local_mail_adapter? do
Application.get_env(:beet_round_server, BeetRoundServer.Mailer)[:adapter] == Swoosh.Adapters.Local
Application.get_env(:beet_round_server, BeetRoundServer.Mailer)[:adapter] ==
Swoosh.Adapters.Local
end
end

View File

@ -4,7 +4,7 @@ defmodule BeetRoundServer.MixProject do
def project do
[
app: :beet_round_server,
version: "0.1.0",
version: "0.7.1",
elixir: "~> 1.15",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
@ -61,6 +61,7 @@ defmodule BeetRoundServer.MixProject do
depth: 1},
{:swoosh, "~> 1.16"},
{:phoenix_swoosh, "~> 1.2.1"},
{:gen_smtp, "~> 1.1"},
{:req, "~> 0.5"},
{:telemetry_metrics, "~> 1.0"},
{:telemetry_poller, "~> 1.0"},

View File

@ -14,6 +14,7 @@
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
"finch": {:hex, :finch, "0.21.0", "b1c3b2d48af02d0c66d2a9ebfb5622be5c5ecd62937cf79a88a7f98d48a8290c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "87dc6e169794cb2570f75841a19da99cfde834249568f2a5b121b809588a4377"},
"fine": {:hex, :fine, "0.1.4", "b19a89c1476c7c57afb5f9314aed5960b5bc95d5277de4cb5ee8e1d1616ce379", [:mix], [], "hexpm", "be3324cc454a42d80951cf6023b9954e9ff27c6daa255483b3e8d608670303f5"},
"gen_smtp": {:hex, :gen_smtp, "1.3.0", "62c3d91f0dcf6ce9db71bcb6881d7ad0d1d834c7f38c13fa8e952f4104a8442e", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "0b73fbf069864ecbce02fe653b16d3f35fd889d0fdd4e14527675565c39d84e6"},
"gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"},
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "0435d4ca364a608cc75e2f8683d374e55abbae26", [tag: "v2.2.0", sparse: "optimized", depth: 1]},
"hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"},
@ -37,6 +38,7 @@
"plug": {:hex, :plug, "1.19.1", "09bac17ae7a001a68ae393658aa23c7e38782be5c5c00c80be82901262c394c0", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "560a0017a8f6d5d30146916862aaf9300b7280063651dd7e532b8be168511e62"},
"plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
"postgrex": {:hex, :postgrex, "0.22.0", "fb027b58b6eab1f6de5396a2abcdaaeb168f9ed4eccbb594e6ac393b02078cbd", [:mix], [{:db_connection, "~> 2.9", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a68c4261e299597909e03e6f8ff5a13876f5caadaddd0d23af0d0a61afcc5d84"},
"ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"},
"req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"},
"swoosh": {:hex, :swoosh, "1.22.0", "0d65a95f89aedb5011af13295742294e309b4b4aaca556858d81e3b372b58abc", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c01ced23d8786d1ee1a03e4c16574290b2ccd6267beb8c81d081c4a34574ef6e"},
"tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"},