All Projects → eellson → phoenix-webpack-docker-elastic

eellson / phoenix-webpack-docker-elastic

Licence: other
Simple templates for Phoenix/Webpack/Docker/Elastic Beanstalk setup

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to phoenix-webpack-docker-elastic

Absinthe plug
Plug support for Absinthe, the GraphQL toolkit for Elixir
Stars: ✭ 209 (+533.33%)
Mutual labels:  phoenix
phoenix assets webpack
Asset Pipeline with Webpack on Phoenix
Stars: ✭ 52 (+57.58%)
Mutual labels:  phoenix
ticker-react
React Client for displaying Stock Quotes (IEX Trading)
Stars: ✭ 34 (+3.03%)
Mutual labels:  phoenix
Heroku Buildpack Phoenix Static
A Heroku buildpack for building Phoenix's static assets
Stars: ✭ 225 (+581.82%)
Mutual labels:  phoenix
Conduit
RealWorld example backend implementing the CQRS/ES pattern in Elixir and Phoenix
Stars: ✭ 253 (+666.67%)
Mutual labels:  phoenix
keeper
Flexible and Simple authentication solution for Phoenix
Stars: ✭ 27 (-18.18%)
Mutual labels:  phoenix
Formex
A better form library for Phoenix
Stars: ✭ 206 (+524.24%)
Mutual labels:  phoenix
Sphinx
Authorization library for Phoenix web framework
Stars: ✭ 19 (-42.42%)
Mutual labels:  phoenix
glasnost
Glasnost is a GraphQL app server for Golos/Steem
Stars: ✭ 23 (-30.3%)
Mutual labels:  phoenix
howto
How to do things on the Internet
Stars: ✭ 78 (+136.36%)
Mutual labels:  phoenix
Pow assent
Multi-provider authentication for your Pow enabled app
Stars: ✭ 236 (+615.15%)
Mutual labels:  phoenix
Exchat
(Not maintaining) A Slack-like app by Elixir, Phoenix & React(redux)
Stars: ✭ 252 (+663.64%)
Mutual labels:  phoenix
phoenix
Apache Phoenix / Hbase Spring Boot Microservices
Stars: ✭ 23 (-30.3%)
Mutual labels:  phoenix
Ex Shop
Digital goods shop & blog created using Elixir (Phoenix framework)
Stars: ✭ 214 (+548.48%)
Mutual labels:  phoenix
ambry
Self-hosted audiobook streaming server
Stars: ✭ 38 (+15.15%)
Mutual labels:  phoenix
Codebattle
Codebattle game
Stars: ✭ 209 (+533.33%)
Mutual labels:  phoenix
pokerex client
Elm client for PokerEx project
Stars: ✭ 39 (+18.18%)
Mutual labels:  phoenix
indifferent
Elixir Indifferent access on maps/lists/tuples with custom key transforms.
Stars: ✭ 20 (-39.39%)
Mutual labels:  phoenix
phoenix-hibernate-dialect
An Apache Phoenix Hibernate dialect
Stars: ✭ 20 (-39.39%)
Mutual labels:  phoenix
livebook
Automate code & data workflows with interactive Elixir notebooks
Stars: ✭ 3,402 (+10209.09%)
Mutual labels:  phoenix

Phoenix/Webpack/Docker/Elastic Beanstalk starter pack

This project aims to create a simple and repeatable solution for getting up and running with dev and production Phoenix environments.

This approach swaps out brunch for webpack (with sass and ES2015 support), makes use of Docker to allow devs to get their environment up and running easily, and is ready for deployment on Elastic Beanstalk.

Note: I wouldn't necessarily recommend this approach for all apps, as Docker blocks certain Elixir features from the outset. I've posted an outline of those, along with a method of deploying without Docker, in this post: Elixir deployments on AWS.

Getting started

First look at the Gotchas section for common issues.

Now clone this repo:

$ git clone https://github.com/eellson/phoenix_starter.git

Using in development

Updating existing project

Copy files into project directory:

$ cd phoenix-webpack-docker-elastic
$ cp -a .ebextensions/ path_to_project/
$ cp .dockerignore \
     Docker* \
     docker-compose.yml \
     webpack.config.js path_to_project/

Ensure you have all the dependencies and devDependencies from our package.json in yours, and remove any brunch dependencies. If you're using the default package.json (you've not added/removed any libs) you can just drop ours in, and the diff should look something like this:

 {
   "repository": {},
+  "scripts": {
+    "start": "webpack --watch-stdin --progress --color",
+    "compile": "NODE_ENV=production webpack -p"
   },
   "dependencies": {
-    "brunch": "^1.8.5",
-    "babel-brunch": "^5.1.1",
-    "clean-css-brunch": ">= 1.0 < 1.8",
-    "css-brunch": ">= 1.0 < 1.8",
-    "javascript-brunch": ">= 1.0 < 1.8",
-    "uglify-js-brunch": ">= 1.0 < 1.8"
+    "phoenix": "file:deps/phoenix",
+    "phoenix_html": "file:deps/phoenix_html"
+  },
+  "devDependencies": {
+    "babel-core": "^6.13.2",
+    "babel-loader": "^6.2.4",
+    "babel-preset-es2015": "^6.13.2",
+    "bootstrap-sass": "^3.3.7",
+    "copy-webpack-plugin": "^3.0.1",
+    "css-loader": "^0.23.1",
+    "extract-text-webpack-plugin": "^1.0.1",
+    "file-loader": "^0.9.0",
+    "node-sass": "^3.8.0",
+    "sass-loader": "^4.0.0",
+    "style-loader": "^0.13.1",
+    "url-loader": "^0.5.7",
+    "webpack": "^1.13.1"
 }

Update database configuration to point to postgres host in docker-compose.yml. You'll want to make this change in any environments you want to run using docker-compose:

config :name_of_project, PhoenixStarter.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "phoenix_starter_dev",
-  hostname: "localhost",
+  hostname: "postgres",
  pool_size: 10

We assume you want webpack, not brunch, so need to update the watchers instruction in config/dev.exs for this. Similarly, if you've got a brunch-config.yml floating around, you can likely get rid:

config :name_of_project, PhoenixStarter.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
-  watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
-                    cd: Path.expand("../", __DIR__)]]
+  watchers: [npm: ["start", cd: Path.expand("../", __DIR__)]]

We also assume you'll want to use sass, compiled to css by webpack, so update your original plain css:

$ mv web/static/css/app.{css,scss}

Building docker environment

Build Docker environment:

$ docker-compose build

Setup database:

$ docker-compose run web bash
> mix do ecto.create, ecto.migrate # run this in docker shell

Running

Run app:

$ docker-compose up

You can run tests in web container with:

$ docker-compose run web mix test

Setting up production

This setup should be good to go for an elastic beanstalk deployment, with a couple of tweaks. We assume you've got the aws and eb clis configured.

Updating existing project

We use git for our eb deployments, but don't keep our production secrets in source control, instead they live on the box. We inject these into the Docker container at build time, so they can be present in your compiled production config. Anything you expect to read from here should use System.get_env/1.

We also need to tweak the production config slightly. Once done you should have something like:

config :name_of_project, NameOfProject.Endpoint,
  http: [port: {:system, "PORT"}, compress: true],
  url: [scheme: "http", host: System.get_env("HOST"), port: {:system, "PORT"}],
  secret_key_base: System.get_env("SECRET_KEY_BASE"),
  code_reloader: false,
  cache_static_manifest: "priv/static/manifest.json",
  server: true

config :name_of_project, NameOfProject.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: System.get_env("RDS_USERNAME"),
  password: System.get_env("RDS_PASSWORD"),
  database: System.get_env("RDS_DATABASE"),
  hostname: System.get_env("RDS_HOSTNAME"),
  port: System.get_env("RDS_PORT") || 5432,
  pool_size: 20,
  ssl: true

Creating production database

Next, create an RDS instance. It's best to keep this outside of the elastic beanstalk environment and manage separately. There are lots of options for this, but here's a sample:

$ aws rds create-db-instance \
	  --db-instance-identifier yourrdsinstanceidentifier \
	  --db-instance-class db.t2.micro \
	  --engine postgres \
	  --db-name your_db_name \
	  --allocated-storage 5 \
	  --master-username yourdbusername \
	  --master-user-password dbpass

This will take some time to spin up, we can use the cli to get a picture of the status here. This simply returns when complete:

$ aws rds wait db-instance-available \
	  --db-instance-identifier yourrdsinstanceidentifier

We can now get the hostname for our db with:

$ aws rds describe-db-instances \
	  --db-instance-identifier yourrdsinstanceidentifier | grep Address

Creating production app environment

This gives us all the info we need to create our eb environment. We can specify most of the config options at this stage:

$ eb create environmentname \
     --envvars MIX_ENV=prod,SECRET_KEY_BASE=secret,PORT=4000,HOST=cname.elasticbeanstalk.com,RDS_USERNAME=yourdbusername,RDS_PASSWORD=dbpass,RDS_HOSTNAME=rdshostname,RDS_DATABASE=your_db_name,RDS_PORT=5432

Finally, we need to allow our eb environment access to the rds instance. There is a good run through of the steps to do this in Amazon's documentation, here.

Gotchas

My app won't deploy because my config is incorrect, but I can't update my config because my app is in an invalid state! What can I do?

Sadly it's easy to get into this state when creating the production environment. The simplest way to resolve this is to deploy a basic Dockerfile you know works, (such as the example here from amazon), set your config to the desired values, then redeploy with the correct Dockerfile.

Webpack isn't compiling assets on change/live-reload isn't working.

There is an issue (webpack/webpack-dev-server#143) with detecting file system changes when using the virtualbox driver. Using an alternative driver, or a solution like Docker for Mac should resolve this.

Webpack fails in development with "command not found"

Occasionally I have issues around this, seemingly caused by mounting /app/node_modules as a data volume, and it therefore not picking up changes. Deleting this volume from docker-compose.yml, running docker-compose up, adding the volume back and running docker-compose up again seems to resolve.

Webpack fails in production with "command not found"

Check your NODE_ENV. We need to install devDependencies in order to run webpack etc on the server, so we should not set NODE_ENV=production (note we set this explicitly when compiling assets for production).

Acknowledgements

  • This approach was heavily inspired by James Robert Somers' post here on Giant Robots Smashing into Other Giant Robots.
  • Strategy for writing ENV into Dockerfile on eb from Vladimir Zhukov's insights here.
  • Webpack config heavily influenced by Matthew Lehner and Andrew Stewart's approaches.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].