Merge branch 'docker' into 'master'
Restore Docker development See merge request framasoft/mobilizon!977
This commit is contained in:
commit
b45d407cc1
25
.env.template
Normal file
25
.env.template
Normal 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
1
.gitignore
vendored
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
.:
|
.:
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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'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'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'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'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
|
||||||
|
|
||||||
|
|
|
@ -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{
|
||||||
|
|
Loading…
Reference in a new issue