Skip to content

Commit

Permalink
Merge branch 'master' into proper-dependent-preloads
Browse files Browse the repository at this point in the history
  • Loading branch information
JannikStreek authored Nov 10, 2024
2 parents f56c3e6 + 9e957d9 commit 6997b69
Show file tree
Hide file tree
Showing 20 changed files with 249 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .buildpacks
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
https://github.com/nwittstruck/heroku-buildpack-elixir#scalingo
https://github.com/gjaldon/heroku-buildpack-phoenix-static
https://github.com/gigalixir/gigalixir-buildpack-phoenix-static
https://github.com/chrismcg/heroku-buildpack-elixir-mix-release
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
elixir 1.13.1-otp-23
erlang 23.1.5
elixir 1.15.8-otp-26
erlang 26.2.5
49 changes: 23 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,9 @@ Brainstorm ...

## Getting Started

mindwendel can be run just about anywhere. So checkout our [Installation Guides](./docs/installing_mindwendel.md) for detailed instructions for various deployments.
mindwendel can be run just about anywhere. So checkout our [Installation Guides](./docs/installing_mindwendel.md) for detailed instructions for various deployments. The easiest way to deploy and run mindwendel is using our own `docker-compose-prod.yml` file. For instructions, see [Setup for Production](#setup-for-production).
If you want to contribute, jump ahead to [Development](#development)!

Here's the TLDR:

- Run mindwendel via Docker and reference your postgres database

```bash
docker run -d --name mindwendel \
-p 127.0.0.1:80:4000 \
-e DATABASE_HOST="..." \
-e DATABASE_PORT="5432" \
-e DATABASE_SSL="false" \
-e DATABASE_NAME="mindwendel_prod" \
-e DATABASE_USER="mindwendel_db_user" \
-e DATABASE_USER_PASSWORD="mindwendel_db_user_password" \
-e SECRET_KEY_BASE="generate_your_own_secret_key_base_and_save_it" \
-e URL_HOST="your_domain_to_mindwendel" \
ghcr.io/mindwendel/mindwendel
```

NOTE: mindwendel requires a postgres database. You can use [our docker-compose file](./docs/installing_mindwendel.md#running-on-docker-compose) to also install the postgres.

## Contributing

To get started with a development installation of mindwendel, follow the instructions below.
Expand Down Expand Up @@ -144,7 +124,7 @@ mix gettext.extract --merge
docker compose exec app mix test
```

### Production
### Setup for Production

- Generate self-signed ssl sertificate for the postgres server on the host machine; the generated files are mounted into the docker container

Expand All @@ -157,7 +137,7 @@ mix gettext.extract --merge
test $(uname -s) = Linux && chown 70 ./ca/server.key
```

- Duplicate and rename `.env.default`
- Duplicate and rename `.env.prod.default`

```bash
cp .env.prod.default .env.prod
Expand All @@ -178,6 +158,7 @@ mix gettext.extract --merge
- The url has to match the env var `URL_HOST`; so http://localhost will not work when your `URL_HOST=0.0.0.0`
- The mindwendel production configuration is setup to enforce ssl, see Mindwendel.Endpoint configuration in `config/prod.exs`
- The mindwendel production configuration supports deployment behind a reverse porxy (load balancer) by parsing the proper protocol from the x-forwarded-\* header of incoming requests, see `config/prod.exs`
- If you are having troubles during setup, please raise an issue.

### Build release and production docker image

Expand All @@ -199,16 +180,25 @@ We are using Elixir's built-in formatter.
mix format
```

## Environment Variables
## Feature flags

### Privacy and automatic data removal
Mindwendel includes a job runner that deletes old brainstormings after a defined number of days. This can be controlled with the setting `MW_FEATURE_BRAINSTORMING_REMOVAL_AFTER_DAYS`, which can be set to for instance to `30`.

### File Storage
File storage is available through an s3 compatible object storage backend. An encryption key needs to be generated before, e.g.:
File storage is available through an s3 compatible object storage backend. An encryption key (`VAULT_ENCRYPTION_KEY_BASE64`) needs to be generated before, e.g.:

```
iex
32 |> :crypto.strong_rand_bytes() |> Base.encode64()
```

or

```
openssl rand -base64 32
```

Then, object storage and the vault key need to be set:

```
Expand All @@ -226,9 +216,12 @@ There is an example given inside the `docker-compose.yml` with a docker compose

To deactivate file storage, use `MW_FEATURE_IDEA_FILE_UPLOAD` (defaults to `true`) and set it to `false`.

### Brainstorming teasers
If you want to display some teasers and help for your brainstorming, use `MW_FEATURE_BRAINSTORMING_TEASER` and set it to `true`.

### Localization

Currently, there are two language files available, german ("de") and english ("en"). To set the default_locale, you can set `MW_DEFAULT_LOCALE`. The default is english.
Currently, there are two language files available, german (`de`) and english (`en`). To set the default_locale, you can set `MW_DEFAULT_LOCALE`. The default is english.

## Testimonials

Expand All @@ -250,3 +243,7 @@ Logos and text provided with courtesy of kits.
- https://github.com/gerardo-navarro
- https://github.com/nwittstruck
- Lightbulb stock image by LED Supermarket at Pexels: https://www.pexels.com/de-de/foto/die-gluhbirne-577514/

## Image Licenses
- Lightbulb, Pexels / CC0: https://www.pexels.com/license/, https://www.pexels.com/terms-of-service/
- GitHub Logo: https://github.com/logos
2 changes: 1 addition & 1 deletion assets/scss/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ a .bi {
}

.bg-mindwendel {
background-image: url("/images/mindwendel.jpg");
background-image: url("/images/mindwendel.png");
background-repeat: no-repeat;
background-size: cover;
}
Expand Down
36 changes: 29 additions & 7 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Config
require Logger

if config_env() == :prod do
# configure logging:
config :logger, :default_handler,
formatter: {
LoggerJSON.Formatters.Basic,
Expand Down Expand Up @@ -49,13 +48,28 @@ if config_env() != :test do
# disable on prod, because logger_json will take care of this. set to :debug for test and dev
ecto_log_level = if config_env() == :prod, do: false, else: :debug

ssl_config =
if System.get_env("DATABASE_SSL", "true") == "true",
do: [cacerts: :public_key.cacerts_get()],
else: nil
# default ssl_opts:
ssl_opts = [
verify: :verify_peer,
depth: 3,
versions: [:"tlsv1.3"],
server_name_indication: String.to_charlist(System.get_env("DATABASE_HOST")),
customize_hostname_check: [
match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
]
]

# either use system certificates or specify files:
ssl_opts =
if System.get_env("DATABASE_CERT_FILE") do
Logger.info("Loading DATABASE_CERT_FILE")
ssl_opts ++ [cacertfile: System.get_env("DATABASE_CERT_FILE")]
else
Logger.info("Loading System Certificates")
ssl_opts ++ [cacerts: :public_key.cacerts_get()]
end

config :mindwendel, Mindwendel.Repo,
start_apps_before_migration: [:logger_json],
database: System.get_env("DATABASE_NAME"),
hostname: System.get_env("DATABASE_HOST"),
password: System.get_env("DATABASE_USER_PASSWORD"),
Expand All @@ -65,7 +79,8 @@ if config_env() != :test do
url: System.get_env("DATABASE_URL"),
timeout: String.to_integer(System.get_env("DATABASE_TIMEOUT", "15000")),
log: ecto_log_level,
ssl: ssl_config
ssl: System.get_env("DATABASE_SSL", "true") == "true",
ssl_opts: ssl_opts

secret_key_base =
System.get_env("SECRET_KEY_BASE") ||
Expand Down Expand Up @@ -162,6 +177,12 @@ feature_file_upload =
String.trim(System.get_env("MW_FEATURE_IDEA_FILE_UPLOAD") || "")
)

feature_privacy_imprint_enabled =
Enum.member?(
["true"],
String.trim(System.get_env("MW_FEATURE_LEGAL_PRIVACY_LINKS") || "")
)

# enable/disable brainstorming teasers and configure delete brainstormings option:
config :mindwendel, :options,
feature_brainstorming_teasers:
Expand All @@ -171,6 +192,7 @@ config :mindwendel, :options,
),
feature_file_upload: feature_file_upload,
feature_brainstorming_removal_after_days: delete_brainstormings_after_days,
feature_privacy_imprint_enabled: feature_privacy_imprint_enabled,
# use a strict csp everywhere except in development. we need to relax the setting a bit for webpack
csp_relax: config_env() == :dev

Expand Down
110 changes: 68 additions & 42 deletions docs/installing_mindwendel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,16 @@

We have prepared different installation configurations for you. A postgres database server is the only external dependency needed by mindwendel in order to store all application data.

Below, we provide detailed instructions on how to install and run mindwendel in a variety of common configurations:
Below, we provide detailed instructions on how to install and run mindwendel:

- [Running on Docker-Compose](#running-on-docker-compose) (RECOMMENDED)
- [Running on Docker](#running-on-docker)
- [Running on Docker Compose](#running-on-docker-compose)
- [Running on Gigalixir](#running-on-gigalixir)

## Setup of .env secrets and variables

Please copy the .env.default file to .env and set the secrets!

https://hexdocs.pm/cloak/install.html

```
iex
iex> 32 |> :crypto.strong_rand_bytes() |> Base.encode64()
```

## Running on Docker-Compose
## Running on Docker Compose

When you use [docker compose](https://docs.docker.com/compose/), you will be using one or several `docker-compose.yml` files.

- Add the following snippets to one of your `docker-compose.yml` file
- Add the following snippets to one of your `docker-compose.yml` file or simply use our `docker-compose-prod.yml` file and add your own passwords and configs:

```yml
services:
Expand All @@ -45,7 +34,10 @@ When you use [docker compose](https://docs.docker.com/compose/), you will be usi
# Add the credentials for the database user that mindwendel should use to access the database
# NOTE: The database user should have read and write permissions
DATABASE_USER: "mindwendel_db_user"
DATABASE_USER_PASSWORD: "mindwendel_db_user_password"
DATABASE_USER_PASSWORD:

# Secure connection to database, especially in a remote db setup
DATABASE_SSL: false

# Add the url host that points to this mindwendel installation. This is used by mindwendel to generate urls with the right host throughout the app.
URL_HOST: "your_domain_to_mindwendel"
Expand All @@ -55,11 +47,43 @@ When you use [docker compose](https://docs.docker.com/compose/), you will be usi
DATABASE_SSL: "false"
MW_DEFAULT_LOCALE: en

# MW Features
MW_FEATURE_BRAINSTORMING_REMOVAL_AFTER_DAYS: 30
MW_FEATURE_BRAINSTORMING_TEASER: true
MW_FEATURE_IDEA_FILE_UPLOAD: true

# Variables for your s3 file storage
OBJECT_STORAGE_BUCKET: mindwendel
OBJECT_STORAGE_SCHEME: "https://"
OBJECT_STORAGE_HOST: minio
OBJECT_STORAGE_PORT: 9000
OBJECT_STORAGE_REGION: local
OBJECT_STORAGE_USER:
OBJECT_STORAGE_PASSWORD:
# To generate a vault encryption key, you can use either:
# openssl rand -base64 32
# OR
# iex
# iex> 32 |> :crypto.strong_rand_bytes() |> Base.encode64()
VAULT_ENCRYPTION_KEY_BASE64:

# Add a secret key base for mindwendel for encrypting the use session
# NOTE: There are multiple commands you can use to generate a secret key base. Pick one command you like, e.g.:
# `date +%s | sha256sum | base64 | head -c 64 ; echo`
# See https://www.howtogeek.com/howto/30184/10-ways-to-generate-a-random-password-from-the-command-line/
SECRET_KEY_BASE: "generate_your_own_secret_key_base_and_save_it"

# Add the url host that points to this mindwendel installation.
# This is used by mindwendel to generate urls with the right host throughout the app.
URL_HOST: localhost
# 80 for http
URL_PORT: 443
# http or https
URL_SCHEME: https

# This env var defines to what port the phoeinx (cowboy) server should listen to.
# Given that we are target port is 4000 (see below) it likely that the phoenix server should also listen to this port 4000.
MW_ENDPOINT_HTTP_PORT: 4000
ports:
- "80:4000"
depends_on:
Expand All @@ -69,24 +93,47 @@ When you use [docker compose](https://docs.docker.com/compose/), you will be usi
# Note: Please use other credentials when using this in production.
db:
image: postgres:latest
# Pass config parameters to the postgres server.
# Find more information below when you need to generate the ssl-relevant file your self
# command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_PASSWORD:
PGDATA: /var/lib/postgresql/data/pgdata
restart: always
ports:
- "5432:5432"
# This is important for a production setup in order ot presist the mindwendel database even the docker container is stopped and removed
volumes:
- pgdata:/var/lib/postgresql/data

# minio acts as a backend for file storage
minio:
image: minio/minio
container_name: minio
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minio_user
MINIO_ROOT_PASSWORD:
volumes:
- ~/minio/data:/data
command: server /data --console-address ":9001"

volumes:
# To setup an ssl-enabled postgres server locally, you need to generate a self-signed ssl certificate.
# See README.md for more information.
# Mount the ssl_cert_file and ssl_key_file into the docker container.
# - ./ca/server.crt:/var/lib/postgresql/server.crt
# - ./ca/server.key:/var/lib/postgresql/server.key
pgdata:
```
- To run mindwendel via Docker-Compose, just type
- To run mindwendel via Docker Compose, just type
```sh
docker compose up
docker compose up -d
```

- To create the production database (after having created the containers via up):
Expand Down Expand Up @@ -121,28 +168,7 @@ When you use [docker compose](https://docs.docker.com/compose/), you will be usi

Note: Adjust the env vars in `docker-compose.yml` according to your preferences.

## Running on Docker

If you are using Docker containers and prefer to manage your mindwendel installation that way then we’ve got you covered. This guide discusses how to use the mindwendel docker image to launch a container running mindwendel.

- Run mindwendel via [Docker](https://docs.docker.com/engine/reference/run/) (without postgres database)
```sh
docker run -d --name mindwendel \
-p 127.0.0.1:80:4000 \
-e DATABASE_HOST="..." \
-e DATABASE_PORT="5432" \
-e DATABASE_SSL="false" \
-e DATABASE_NAME="mindwendel_prod" \
-e DATABASE_USER="mindwendel_db_user" \
-e DATABASE_USER_PASSWORD="mindwendel_db_user_password" \
-e SECRET_KEY_BASE="generate_your_own_secret_key_base_and_save_it" \
-e URL_HOST="your_domain_to_mindwendel" \
ghcr.io/mindwendel/mindwendel
```

NOTE: mindwendel requires a postgres database. You can use our docker-compose file to also install the postgres, see [above](#running-on-docker-compose).

## Running on Gigalixir.com
## Running on Gigalixir

Gigalixir.com is a plattform as a service that fully supports Elixir and Phoenix.

Expand Down
4 changes: 2 additions & 2 deletions elixir_buildpack.config
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
elixir_version=1.13.1
erlang_version=24.2
elixir_version=1.15.8
erlang_version=26.2.5
release=false
Loading

0 comments on commit 6997b69

Please sign in to comment.