Merge branch 'docker' into 'master'

Restore Docker development

See merge request framasoft/mobilizon!977
This commit is contained in:
Thomas Citharel 2021-08-04 09:26:18 +00:00
commit b45d407cc1
11 changed files with 102 additions and 42 deletions

25
.env.template Normal file
View file

@ -0,0 +1,25 @@
# Database settings
POSTGRES_USER=mobilizon
POSTGRES_PASSWORD=changethis
POSTGRES_DB=mobilizon
POSTGRES_PORT=5432
# Instance configuration
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN=false
MOBILIZON_INSTANCE_NAME=My Mobilizon Instance
MOBILIZON_INSTANCE_HOST=mobilizon.lan
MOBILIZON_INSTANCE_PORT=4000
MOBILIZON_INSTANCE_SECRET_KEY_BASE=changethis
MOBILIZON_INSTANCE_SECRET_KEY=changethis
MOBILIZON_INSTANCE_EMAIL=noreply@mobilizon.lan
MOBILIZON_REPLY_EMAIL=contact@mobilizon.lan
# Email settings
MOBILIZON_SMTP_SERVER=localhost
MOBILIZON_SMTP_PORT=25
MOBILIZON_SMTP_HOSTNAME=localhost
MOBILIZON_SMTP_USERNAME=noreply@mobilizon.lan
MOBILIZON_SMTP_PASSWORD=password
MOBILIZON_SMTP_SSL=false

1
.gitignore vendored
View file

@ -43,3 +43,4 @@ release/
docker/production/.env docker/production/.env
test-junit-report.xml test-junit-report.xml
js/junit.xml js/junit.xml
.env

View file

@ -201,7 +201,7 @@ pages:
- mkdir -p /kaniko/.docker - mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$CI_REGISTRY_AUTH\",\"email\":\"$CI_REGISTRY_EMAIL\"}}}" > /kaniko/.docker/config.json - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$CI_REGISTRY_AUTH\",\"email\":\"$CI_REGISTRY_EMAIL\"}}}" > /kaniko/.docker/config.json
script: script:
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/docker/production/Dockerfile --destination $DOCKER_IMAGE_NAME --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP - /kaniko/executor --cache=true --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/docker/production/Dockerfile --destination $DOCKER_IMAGE_NAME --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP
build-docker-master: build-docker-master:
<<: *docker <<: *docker

View file

@ -1,6 +1,6 @@
FROM bitwalker/alpine-elixir:latest FROM elixir:alpine
RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses git
RUN mix local.hex --force && mix local.rebar --force RUN mix local.hex --force && mix local.rebar --force

View file

@ -1,21 +1,15 @@
import Config import Config
# For development, we disable any cache and enable
# debugging and code reloading.
#
# The watchers configuration can be used to run external
# watchers to your application. For example, we use it
# with brunch.io to recompile .js and .css sources.
config :mobilizon, Mobilizon.Web.Endpoint, config :mobilizon, Mobilizon.Web.Endpoint,
http: [ http: [
ip: {127, 0, 0, 1}, port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "4000"))
port: 4000
], ],
url: [ url: [
host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.local"), host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.local"),
port: 80, port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "80")),
scheme: "http" scheme: "http"
], ],
secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis"),
debug_errors: true, debug_errors: true,
code_reloader: true, code_reloader: true,
check_origin: false, check_origin: false,
@ -91,6 +85,9 @@ config :mobilizon, :instance,
registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") == "true", registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") == "true",
groups: true groups: true
config :mobilizon, Mobilizon.Web.Auth.Guardian,
secret_key: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY", "changethis")
# config :mobilizon, :activitypub, sign_object_fetches: false # config :mobilizon, :activitypub, sign_object_fetches: false
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads" config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads"

View file

@ -2,7 +2,7 @@
import Config import Config
listen_ip = System.get_env("MOBILIZON_INSTANCE_LISTEN_IP", "::") listen_ip = System.get_env("MOBILIZON_INSTANCE_LISTEN_IP", "127.0.0.1")
listen_ip = listen_ip =
case listen_ip |> to_charlist() |> :inet.parse_address() do case listen_ip |> to_charlist() |> :inet.parse_address() do

View file

@ -1,13 +1,14 @@
version: "3" version: "3.2"
services: services:
postgres: postgres:
container_name: mobilizon_db container_name: mobilizon_db
restart: unless-stopped restart: unless-stopped
image: postgis/postgis:13-3.0 image: postgis/postgis
environment: environment:
POSTGRES_PASSWORD: postgres - POSTGRES_USER
POSTGRES_DB: mobilizon_dev - POSTGRES_PASSWORD
- POSTGRES_DB
- POSTGRES_PORT
volumes: volumes:
- pgdata:/var/lib/postgresql/data - pgdata:/var/lib/postgresql/data
api: api:
@ -17,29 +18,24 @@ services:
volumes: volumes:
- ".:/app" - ".:/app"
ports: ports:
- "4000:4000" - 4000:4000
depends_on: depends_on:
- postgres - postgres
environment: environment:
MIX_ENV: "dev" MIX_ENV: "dev"
DOCKER: "true" DOCKER: "true"
MOBILIZON_INSTANCE_NAME: My Mobilizon Instance MOBILIZON_INSTANCE_NAME: My Mobilizon Instance
MOBILIZON_INSTANCE_HOST: mobilizon.me MOBILIZON_INSTANCE_HOST: localhost
MOBILIZON_INSTANCE_HOST_PORT: 4000
MOBILIZON_INSTANCE_PORT: 4000
MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true" MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true"
MOBILIZON_DATABASE_PASSWORD: postgres MOBILIZON_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
MOBILIZON_DATABASE_USERNAME: postgres MOBILIZON_DATABASE_USERNAME: ${POSTGRES_USER}
MOBILIZON_DATABASE_DBNAME: mobilizon_dev MOBILIZON_DATABASE_DBNAME: ${POSTGRES_DB}
MOBILIZON_DATABASE_HOST: postgres MOBILIZON_DATABASE_HOST: postgres
command: > MOBILIZON_DATABASE_PORT: ${POSTGRES_PORT}
sh -c "cd js && command: sh -c "mix phx.server"
yarn install &&
cd ../ &&
mix deps.get &&
mix compile &&
mix ecto.create &&
mix ecto.migrate &&
mix phx.server"
volumes: volumes:
pgdata: pgdata:
.: .:

View file

@ -23,11 +23,17 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do
Tag.tag(:meta, property: "og:url", content: group.url), Tag.tag(:meta, property: "og:url", content: group.url),
Tag.tag(:meta, property: "og:description", content: group.summary), Tag.tag(:meta, property: "og:description", content: group.summary),
Tag.tag(:meta, property: "og:type", content: "profile"), Tag.tag(:meta, property: "og:type", content: "profile"),
Tag.tag(:meta, property: "profile:username", content: group.preferred_username), Tag.tag(:meta,
property: "profile:username",
content: Actor.preferred_username_and_domain(group)
),
Tag.tag(:meta, property: "twitter:card", content: "summary") Tag.tag(:meta, property: "twitter:card", content: "summary")
] ]
|> maybe_add_avatar(group) |> maybe_add_avatar(group)
|> add_group_schema(group) |> add_group_schema(group)
|> add_group_feeds(group)
|> add_canonical(group)
|> maybe_add_no_index(group)
end end
def build_tags(%Actor{} = _actor, _locale), do: [] def build_tags(%Actor{} = _actor, _locale), do: []
@ -42,27 +48,59 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do
end end
end end
@spec add_group_schema(list(Tag.t()), Actor.t()) :: list(Tag.t())
defp add_group_schema(tags, %Actor{} = group) do defp add_group_schema(tags, %Actor{} = group) do
tags ++ tags ++
[ [
~s{<script type="application/ld+json">#{json(group)}</script>} |> HTML.raw(), ~s{<script type="application/ld+json">#{json(group)}</script>} |> HTML.raw()
]
end
@spec add_group_feeds(list(Tag.t()), Actor.t()) :: list(Tag.t())
defp add_group_feeds(tags, %Actor{} = group) do
tags ++
[
Tag.tag(:link, Tag.tag(:link,
rel: "alternate", rel: "alternate",
type: "application/atom+xml", type: "application/atom+xml",
title: title:
gettext("%{name}'s feed", name: group.name || group.preferred_username) |> HTML.raw(), gettext("%{name}'s feed", name: group.name || group.preferred_username) |> HTML.raw(),
href: Routes.feed_url(Endpoint, :actor, group.preferred_username, :atom) href:
Routes.feed_url(Endpoint, :actor, Actor.preferred_username_and_domain(group), :atom)
), ),
Tag.tag(:link, Tag.tag(:link,
rel: "alternate", rel: "alternate",
type: "text/calendar", type: "text/calendar",
title: title:
gettext("%{name}'s feed", name: group.name || group.preferred_username) |> HTML.raw(), gettext("%{name}'s feed", name: group.name || group.preferred_username) |> HTML.raw(),
href: Routes.feed_url(Endpoint, :actor, group.preferred_username, :ics) href:
Routes.feed_url(
Endpoint,
:actor,
Actor.preferred_username_and_domain(group),
:ics
)
),
Tag.tag(:link,
rel: "alternate",
type: "application/activity+json",
href: group.url
) )
] ]
end end
@spec add_canonical(list(Tag.t()), Actor.t()) :: list(Tag.t())
defp add_canonical(tags, %Actor{url: group_url}) do
tags ++ [Tag.tag(:link, rel: "canonical", href: group_url)]
end
@spec maybe_add_no_index(list(Tag.t()), Actor.t()) :: list(Tag.t())
defp maybe_add_no_index(tags, %Actor{domain: nil}), do: tags
defp maybe_add_no_index(tags, %Actor{}) do
tags ++ [Tag.tag(:meta, name: "robots", content: "noindex")]
end
# Insert JSON-LD schema by hand because Tag.content_tag wants to escape it # Insert JSON-LD schema by hand because Tag.content_tag wants to escape it
defp json(%Actor{} = group) do defp json(%Actor{} = group) do
"group.json" "group.json"

View file

@ -69,7 +69,10 @@ defmodule Mobilizon.Web.Upload do
opts = get_opts(opts) opts = get_opts(opts)
with {:ok, upload} <- prepare_upload(upload, opts), with {:ok, upload} <- prepare_upload(upload, opts),
upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"}, %__MODULE__{} = upload <- %__MODULE__{
upload
| path: upload.path || "#{upload.id}/#{upload.name}"
},
{:ok, upload} <- Filter.filter(opts.filters, upload), {:ok, upload} <- Filter.filter(opts.filters, upload),
{:ok, url_spec} <- Uploader.put_file(opts.uploader, upload) do {:ok, url_spec} <- Uploader.put_file(opts.uploader, upload) do
{:ok, {:ok,

View file

@ -12,12 +12,13 @@ defmodule Mobilizon.Service.MetadataTest do
import Mobilizon.Factory import Mobilizon.Factory
describe "build_tags/2 for an actor" do describe "build_tags/2 for an actor" do
# TODO : Refactor me with DOM assertions, like the event test below
test "that is a group gives tags" do test "that is a group gives tags" do
%Actor{} = group = insert(:group, name: "My group") %Actor{} = group = insert(:group, name: "My group", domain: "remote.domain")
assert group |> Metadata.build_tags() |> Metadata.Utils.stringify_tags() == assert group |> Metadata.build_tags() |> Metadata.Utils.stringify_tags() ==
String.trim(""" String.trim("""
<meta content="#{group.name} (@#{group.preferred_username})" property="og:title"><meta content="#{group.url}" property="og:url"><meta content="The event organizer didn&#39;t add any description." property="og:description"><meta content="profile" property="og:type"><meta content="#{group.preferred_username}" property="profile:username"><meta content="summary" property="twitter:card"><meta content="#{group.avatar.url}" property="og:image"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Organization","address":null,"name":"#{group.name}","url":"#{group.url}"}</script><link href="#{Routes.feed_url(Endpoint, :actor, group.preferred_username, "atom")}" rel="alternate" title="#{group.name}'s feed" type="application/atom+xml"><link href="#{Routes.feed_url(Endpoint, :actor, group.preferred_username, "ics")}" rel="alternate" title="#{group.name}'s feed" type="text/calendar"> <meta content="#{group.name} (@#{group.preferred_username}@#{group.domain})" property="og:title"><meta content="#{group.url}" property="og:url"><meta content="The event organizer didn&#39;t add any description." property="og:description"><meta content="profile" property="og:type"><meta content="#{Actor.preferred_username_and_domain(group)}" property="profile:username"><meta content="summary" property="twitter:card"><meta content="#{group.avatar.url}" property="og:image"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Organization","address":null,"name":"#{group.name}","url":"#{group.url}"}</script><link href="#{Routes.feed_url(Endpoint, :actor, Actor.preferred_username_and_domain(group), "atom")}" rel="alternate" title="#{group.name}'s feed" type="application/atom+xml"><link href="#{Routes.feed_url(Endpoint, :actor, Actor.preferred_username_and_domain(group), "ics")}" rel="alternate" title="#{group.name}'s feed" type="text/calendar"><link href=\"#{group.url}\" rel=\"alternate\" type=\"application/activity+json\"><link href=\"#{group.url}\" rel=\"canonical\"><meta content=\"noindex\" name=\"robots\">
""") """)
assert group assert group
@ -25,7 +26,7 @@ defmodule Mobilizon.Service.MetadataTest do
|> Metadata.build_tags() |> Metadata.build_tags()
|> Metadata.Utils.stringify_tags() == |> Metadata.Utils.stringify_tags() ==
String.trim(""" String.trim("""
<meta content="#{group.name} (@#{group.preferred_username})" property="og:title"><meta content="#{group.url}" property="og:url"><meta content="The event organizer didn&#39;t add any description." property="og:description"><meta content="profile" property="og:type"><meta content="#{group.preferred_username}" property="profile:username"><meta content="summary" property="twitter:card"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Organization","address":null,"name":"#{group.name}","url":"#{group.url}"}</script><link href="#{Routes.feed_url(Endpoint, :actor, group.preferred_username, "atom")}" rel="alternate" title="#{group.name}'s feed" type="application/atom+xml"><link href="#{Routes.feed_url(Endpoint, :actor, group.preferred_username, "ics")}" rel="alternate" title="#{group.name}'s feed" type="text/calendar"> <meta content="#{group.name} (@#{group.preferred_username}@#{group.domain})" property="og:title"><meta content="#{group.url}" property="og:url"><meta content="The event organizer didn&#39;t add any description." property="og:description"><meta content="profile" property="og:type"><meta content="#{Actor.preferred_username_and_domain(group)}" property="profile:username"><meta content="summary" property="twitter:card"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Organization","address":null,"name":"#{group.name}","url":"#{group.url}"}</script><link href="#{Routes.feed_url(Endpoint, :actor, Actor.preferred_username_and_domain(group), "atom")}" rel="alternate" title="#{group.name}'s feed" type="application/atom+xml"><link href="#{Routes.feed_url(Endpoint, :actor, Actor.preferred_username_and_domain(group), "ics")}" rel="alternate" title="#{group.name}'s feed" type="text/calendar"><link href=\"#{group.url}\" rel=\"alternate\" type=\"application/activity+json\"><link href=\"#{group.url}\" rel=\"canonical\"><meta content=\"noindex\" name=\"robots\">
""") """)
end end

View file

@ -273,8 +273,7 @@ defmodule Mobilizon.Factory do
%{ %{
content_type: "image/jpeg", content_type: "image/jpeg",
name: "image.jpg", name: "image.jpg",
url: url, url: url
size: 13_227
} = data } = data
%Mobilizon.Medias.File{ %Mobilizon.Medias.File{