An unofficial website for the EPFL community.
Clubhouse is written in Elixir is a relatively new programming language, running on the Erlang VM (used in several high-stake projects such as WhatsApp and RabbitMQ) with an elegant syntax similar to that of Ruby. In particular, it features a stellar web framework called Phoenix that was used to make Clubhouse as a single application, after various experiments with Svelte, Node.js, Deno, Go and Rust.
See the Elixir website for instructions on installing Elixir and Erlang on your machine. If you're feeling slightly adventurous, you can try installing Elixir using asdf as most distributions have an outdated Elixir version (helpful guide).
Project dependencies are managed by Hex, Elixir's package manager.
$ mix deps.get
During development, you will likely also want to set up a Postgres database, which is required for for most features of Clubhouse to work correctly. This database is also used for tests.
$ docker run --name postgres -p 5455:5432 -e POSTGRES_PASSWORD=postgres -d postgres
You can also set the DATABASE_HOST
environmental variable to localhost
when
running the development server, as the database is considered to run at
postgres
in a Docker Compose network by default.
The project can be built and run using Mix, Elixir's integrated build tool and task runner.
$ mix compile
This will compile all the Elixir code into the _build
directory as BEAM
modules. It is also possible to package the application as a self-contained
release
that can be run in any similar environment, even without Elixir or Erlang
installed. This project uses Docker and releases together to simplify
deployment.
The application will run differently, depending on the environment. The
development server can simply be started with no additional configuration (as
long as your database has the default hostname, or you have set the
DATABASE_HOST
environmental variable).
When running for the first time, you will also have to to setup the database schema using Ecto.
$ mix ecto.create
$ mix ecto.migrate
$ mix phx.server
The bridge and mailer will be emulated without any external network calls.
The following environmental variables are supported when running the application as a release (in production). During development, most variables use sane defaults found in dev.exs that an be changed for your environment.
Value | Description |
---|---|
MIX_ENV | This should be set to prod in production |
PHX_HOST | The domain at which the application is accessible at (without the protocol) |
PORT | The port to bind the server to (default: 4000) |
SECRET_KEY_BASE | Secret value used to derive signing keys (required) |
DATABASE_URL | The connection string for the production database (required) |
BRIDGE_HOST | The host at which the bridge is accessible on (required) |
BRIDGE_API_KEY | The shared secret used as a Bearer token (required) |
FORUM_URL | THe URL at which the forum is available (required) |
DISCOURSE_SECRET | The shared secret used for SSO token signing (required) |
MAILER_SENDER | The "from" address when sending mail (required) |
SMTP_HOST | The hostname of the SMTP server (default: postfix) |
SMTP_PORT | The port of the SMTP server (default: 587) |
APPEAL_ADDRESS | Email which users can submit an appeal (required) |
STATIC_URL | THe URL for statically hosted resources (external) (required) |
The config directory can also be used as a reference to all available application configuration.
This value is used to derive other private keys, such as those used to sign
session cookies. It should be unique and kept secret. A random value can be
generated using the mix phx.gen.secret
command.
$ mix phx.gen.secret
# XidElJ...
This value is used to connect to the database. It should be a full connection string, including the password.
# docker-compose.yml
app:
environment:
- "DATABASE_URL=ecto://clubhouse:${DATABASE_PASS}@postgres/clubhouse"
Tip: Docker Compose can substitute variables using an adjacent
.env
file.
The Dockerfile can be re-generated using mix phx.gen.release --docker
. This
ensures that the OTP, Elixir and OS versions are a suitable match.
$ docker build --tag clubhouse .
Create a .env
file to simplify runtime configuration:
SECRET_KEY_BASE=<RANDOM VALUE>
Run the Docker container with docker run
:
$ docker run --name clubhouse --env-file=.env -p 8080:4000 clubhouse
Transfer the image to a remote server:
$ docker save clubhouse | ssh some-host "docker load"
Use the image in a Docker Compose project:
app:
image: clubhouse
ports:
- "8080:4000"
environment:
- "DATABASE_URL=ecto://clubhouse:${DATABASE_PASS}@postgres/clubhouse"
- "SECRET_KEY_BASE=${SECRET_KEY_BASE}"
bridge:
image: clubhouse-bridge
postgres:
image: postgres
environment:
- "POSTGRES_PASSWORD=${DATABASE_PASS}"
The entire project can be spun up and torn down on a private network with a single command:
$ docker compose up -d # -d is for --detach, runs in background
$ docker compose down
The docker image can also be used to run the database migrations, or to get an IEx shell into the running application (even in production!).
$ docker compose run --rm app bin/migrate
$ docker compose exec app bin/clubhouse remote
Make sure that the database is running for the migration with
docker compose up -d postgres
. Any environmental variables, such as
DATABASE_URL
specified in docker-compose.yml
will automatically be applied
with docker compose run
.
- 0.1
- Initial release
This project is licensed under the MIT License - see the LICENSE file for details
Built on the amazing work of the Elixir community.