This is pretty old as it refers to a 3-year old version of Phoenix. If I'll do monolithic web apps in Elixir again, I'll post my results here.
My skeleton to bootstrap a new Phoenix app.
This is my application skeleton that integrates useful things (see ROADMAP) when starting a new project with phoenix. Starting from 100% scratch every time went tediuos so here it goes. Most changes to this project are backported from live production projects. So yes, albeit a bit quirky here and there this code runs in production.
After cloning this project, I do run a search/replace on the code and file names replacing "Skeleton" with "WhateverMyAppIsCalled" and "skeleton" with "whatever_my_app_is_called".
Master branch currently supports Phoenix v1.1.2
"prod releasing"
- tuned
mix.ex
s andconfig/prod.exs
in a way that exrm can create a working release (thanks to hykw for reporting on this)
- document how to use NavigationTree.Agent in a practical manner. Backport NavigationTree renderers from other projects here to provide templates for use with Zurb/Foundation side navigation bars (It's easy!)
- move Plug.Authorization.Roles into an external dependency (plug_authorization_roles)
- make it configurable from NavigationTree
This assumes a Debian/Ubuntu environment. Max OSX should be similar, except that packages are installed with homebrew instead of apt-get.
- Install System dependencies (see section System dependencies)
- Install Elixir dependencies with
mix deps.get
- Install npm dependencies for ranch with
npm install
- You might want to run
brunch builld
to check if js/css compiling and concatenation works
- You might want to run
- create database with postgre script below
- run as postgres superuser:
sudo -u postgres psql postgres
This will create a databaseCREATE ROLE skeleton_dev_user LOGIN ENCRYPTED PASSWORD 'md5465fc2608ab7a4ebe4eaa198e63b85a7' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION; CREATE DATABASE skeleton_dev WITH OWNER = skeleton_dev_user ENCODING = 'UTF8' TABLESPACE = pg_default LC_COLLATE = 'de_DE.UTF-8' LC_CTYPE = 'de_DE.UTF-8' CONNECTION LIMIT = -1 TEMPLATE = template0 ;
skeleton_dev
that is accessible byskeleton_dev_user
using passwordskeleton_dev_pass
. You should tune this to your needs, of course. Hint: You may need to adjust de_DE.UTF-8 to en_US.UTF-8 for US-english Collation using this Gist: (https://gist.github.com/ffmike/877447) - run as postgres superuser:
- run
mix.compile
to see if everything builds fine - run
mix ecto.migrate Repo
to create required database tables - Start Phoenix endpoint with
mix phoenix.server
oriex -S mix phoenix.server
if you wish to have a console
Now you can visit 127.0.0.1:4000
from your browser.
This will create a database "skeleton_dev" owned by "skeleton_dev_user" with password "skeleton_dev_pass". Tune this to yout needs.
This only creates the database. To install all required tables (users, userroles, user_userrole_map), run mix ecto.migrate Repo
. This will also install a simple user with zsername "admin" with password "admin" and userroles ["admin"] that you can log in with to access /ADMIN/*.
I try to keep up with th latest releases of our dependencies, namely:
- Erlang/Elixir
- tested on Erlang/OTP 18.2 [erts-7.2] and Elixir 1.2.0
- On Debian/Ubuntu I use Linuxbrew to keep up-to-date, see: brew.sh/linuxbrew
- On a Mac you probably know Homebrew
brew update && brew install elixir
Should install both Elixir and Erlang.- On poduction servers I prefer debian packages obtained from Erlang Solutions
- PostgreSQL (tests run on 9.4)
- see config/dev.exs for host/user/port settings
sudo apt-get install postgresql postgresql-contrib postgresql-server-dev-all
works fine on Debian/Ubuntu
- memcached running on 127.0.0.1:11211
apt-get install memcached
works fine on Debina/Ubuntu- if you have memcached running on another host/port, adjust settings in
conf/dev.exs conf/prod.exs
- nodejs and npm
- on Debian/Ubuntu "deb.nodesource.com" works great, or just download nodejs from nodejs.org
- on a Mac, presumably you'll need to use homebrew
- tested on node v5.4.0 and npm 3.3.12
- used for brunch: ran all this with brunch 2.1.3
Hot code relaod is not covered here. See [https://exrm.readme.io/docs/upgradesdowngrades]
- run
bash etc/compile_release.sh
- copy
rel/skeleton/releases/<version>/skeleton.tar.gz
to your production machine - extract, then run
bin/skeleton --start
orbin/skeleton --console
(if you want and iex shell)
This assumes a linux production machine with systemd as init system and a bash shell. Something like Debian 8/Jessie or Ubuntu 15.04/vivid (tested on both distributions). Also, this assumes
- nxing 1.6+ being configured in /etc/nginx
- postgre 9.3+
- memcached instance listening on 127.0.0.1:11211
run apt-get install nginx memcached postgresql-9.4
on Debian/Ubtuntu have a config as above
=======
I am used to put these things into /var/www-apps/<project-name>
. Scripts and
configs in ./etc are tuned to this. As root/superuser do this:
mkdir /var/www-apps
cd /var/www-apps
git clone https://github.com/gutschilla/phoenix-skeleton.git
cd phoenix-skeleton
npm install
mix compile
mix ecto.migrate
bash etc/compile_release.sh
bash etc/install.sh
systemctl nginx reload
cd /var/www-apps/phoenix-skeleton
git pull
bash etc/compile-release.sh
systemctl restart phoenix_skeleton_backend.service
If this doesn't work (most often when you didn't increase your app's version),
run either mix release --implode
(be sure to set MIX_ENV=prod and PORT=4001)
or simply delete the whole ./rel folder.
CAUTION: After deleting the ./rel folder it's currently required to run
rel/skeleton/bin/skeleon console
as privileged user as this will create
neccessary directories which can't be done by an unprivileged user. TODO: Update
compile-release script to create.
phoenix-skeleton depends on misc_random which compiles with a warning:
lib/random.ex:11: warning: erlang:now/0: Deprecated BIF"
on Erlang 18. This
can safely be ignored as on Erlang 18 :erlang.now/0
will not e used in favour of
:erlang.monotonic_time/0
At a certain point, I'll require Erlang 18 to get rid of this and always use
:erlang.monotonic_time/0
.
Is more than welcome. I am still learning this whole Elixir and Erlang/OTP thing so be rude, be harsh but be helpful.