peppy

peppy

Greetings,

I am just learning Elixir and Phoenix. I finished the elixir-lang.org tutorial and a bit of Phoenix. While I’m still not very confident in the language yet, I am extremely impressed so far.

Basically, I have a social media site (we’ll say example.com). It is developed using PHP/MySQL and I built a Node.js chat app a few years back just to learn about sockets and build some simple chat features, like one page with a big 1990s style chat room where everyone on the site can chat on one page, live private messaging for users to chat among people only on their friends list, and live web cam chat. I was successful in getting all of that set up, and haven’t touched it in years. From the beginning, I was never comfortable with Node.js and how one crash anywhere in the app causes the whole thing to crash completely, and how it simply didn’t have as much capability in case our site one day became popular with tons of users. I always hated “callback hell” as well… After reading about chat apps, I always knew that someday I would eventually learn Phoenix/Elixir to replace Node.js.

Right now, I have Ubuntu 20.04. When I login to my shell using the “ubuntu” user (like a root user), I installed Phoenix and set up a project in the ubuntu username directory “/home/ubuntu/chatter/”, the app name is “chatter”. I’ve been making some good progress getting the simple chat example to work, Presence to work and that awesome LiveDashboard working. Really impressed on how all those things just “worked” right out of the box without any arcane configurations.

I am running this stuff on my generic IP address, like [xxx.xxx.xxx.xxx]:4000 and through the shell. So now I have some questions on starting up a real project on the website itself.

First question: If my website directory is in: “/home/example/example.com”, what is the common practice for where where you would install the new project for use in production? Do I install it in “/home/example/chatter”, or “/home/example/example.com/chatter”? I’m seeing that in a standard install, some files are server stuff, and other are “assets”, which is stuff that I think goes in the website directory for browsers to load the JavaScript files. Or do I install it under the user “example” or directory: “/home/example/chatter” and copy and paste the “asset” files into the “/home/example/example.com/assets”?

Next question, for UFW firewall rules for port “4000”, should I set the “Allow” flag for 0.0.0.0 for everyone on the internet to access, or is there a common security practice for this for setting it up on a public-facing website? Phoenix will run on the same server as my website.

Lastly, how do I run Phoenix and my “chatter” app non-stop and have it automatically restart in case the server crashes? I’m cheap right now, so my server does sometimes crash from running out of memory every once in awhile. so I’m going to need my app to fire back up automatically again after reboots, crashes and server restarts, especially I’m sleeping and can’t get to the shell until I wake up.

Thanks

Showing Posts 1 to 4

tj0

tj0

So it sounds like you have a VPS. I would suggest using mix release to package everything.

This will allow you to:

  • start in foreground with logs to stdout
  • package your assets
  • runtime configuration through environmental variables
  • bundling of erts,etc.
  • connect a remote shell

So just pick a directory and a user, just make sure it isn’t root. The release package will take care of the rest.

Docs:

Generally speaking, most people use a reverse proxy to forward the traffic to phoenix on port 4000. The only ports available to the public should be 80 and 443. Search for nginx reverse proxy or haproxy reverse proxy guides. An alternative is to expose phoenix directly on port 443 itself and use a library like SiteEncrypt — site_encrypt v0.7.0 to manage the ssl certificate from LetsEncrypt.

You can just run the release via a supervisor in the foreground. I’m pretty old-school and have the logs piped out to stdout via runit / daemontools, but you can use systemd as well.

Hope that helps.

axelson

axelson

Scenic Core Team

Welcome to the forum! :waving_hand:

For this portion I would recommend GitHub - hauleth/erlang-systemd: systemd utilities for Erlang applications · GitHub

peppy

peppy OP

Thanks for the response. Basically, I’m set up on Dreamhost’s Cloud Compute service. It’s not actually a VPS, but I have my server configured that way to separate each of my websites/users, as I have about 20 websites hosted on one server, so that if one gets hacked, I can contain the damage to just one user.

I did some research on reverse proxy (been a few years since I worked with Node), but I remembered that I have a setup like below on Apache. This was thrown together and eventually worked for my Node.js chat app:

<VirtualHost *:443>
  ServerName www.example.com
  ServerAlias example.com
  DocumentRoot /home/example/example.com

  #// socket.io 1.0+ starts all connections with an HTTP polling request
  RewriteCond %{QUERY_STRING} transport=polling       [NC]
  RewriteRule /(.*)           http://127.0.0.1:3000/$1 [P]

  #// When socket.io wants to initiate a WebSocket connection, it sends an
  #// "upgrade: websocket" request that should be transferred to ws://
  RewriteCond %{HTTP:Upgrade} websocket               [NC]
  RewriteRule /(.*)           ws://127.0.0.1:3000/$1  [P]

  ProxyRequests Off  # can't remember why this is set to "Off"
  ProxyPass /chatnode http://127.0.0.1:3000
  ProxyPassReverse /chatnode http://127.0.0.1:3000

</VirtualHost>

I remember this part being a real pain working with Node and I didn’t understand it too well, so I’m hoping it will be easier with Phoenix.

How would you set up this block of code to run Node and Phoenix at the same time? I’d like to have our Node-based chat continue to run for our users while I experiment and develop the new Phoenix app at the same time.

UPDATE:

I’ve been working for a few hours now, I added the following to my apache VirtualHost tag:

  ProxyRequests Off
  ProxyPass /ex http://127.0.0.1:4000
  ProxyPassReverse /ex http://127.0.0.1:4000

However, I’m having problems getting the default “Welcome to Phoenix!” page on example.com/ex/

I edited /config/config.exs with:

config :chatter, ChatterWeb.Endpoint,
  url: [host: "localhost", path: "/ex"],

I edited: /lib/endpoint.ex with:

plug Plug.Static,
    at: "/ex",
    from: :chatter,

The welcome page shows up on example.com/ex, but none of the css, images or any other files load up. If I click a link in the source code, for example: <link rel="stylesheet" href="/ex/css/app.css"/>, I’ll get an error like:

Phoenix.Router.NoRouteError at GET /css/app.css
no route found for GET /css/app.css (ChatterWeb.Router)
Available routes
          page_path  GET  /                       ChatterWeb.PageController :index
live_dashboard_path  GET  /dashboard              Phoenix.LiveView.Plug :home
live_dashboard_path  GET  /dashboard/:page        Phoenix.LiveView.Plug :page
live_dashboard_path  GET  /dashboard/:node/:page  Phoenix.LiveView.Plug :page

I tried changing /lib/chatter_web/router.ex with various combinations, like:

 scope "/ex", ChatterWeb do
    pipe_through :browser

    get "/", PageController, :index
  end

or:

  scope "/", ChatterWeb do
    pipe_through :browser

    get "/ex", PageController, :index
  end

but I’m kinda stuck now.

peppy

peppy OP

I’m still having problems here trying to get my website URL https://www.example.com/ex/ to display the default “Welcome To Phoenix” page. I made some slight changes and made some progress. First, I created a new project in my web user directory where I plan to use it indefinitely. In apache, I’ve edited the virtual host to:

<VirtualHost *:443>
  ServerName www.example.com
  ServerAlias example.com
  DocumentRoot /home/example/example.com

  <Location /ex/>
    ProxyPass http://127.0.0.1:4000/ex/
    ProxyPassReverse http://127.0.0.1:4000/ex/
  </Location>
</VirtualHost>

and left the router.ex the same:

 scope "/ex", ChatterWeb do
    pipe_through :browser

    get "/", PageController, :index
  end

So when I go to that URL (without the port 4000 part), the css, js and image files loaded up. However, in the logs, I still get this error:

[info] GET /ex/phoenix/live_reload/frame
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /ex/phoenix/live_reload/frame (ExchatWeb.Router)
    (exchat 0.1.0) lib/phoenix/router.ex:402: ExchatWeb.Router.call/2
    (exchat 0.1.0) lib/exchat_web/endpoint.ex:1: ExchatWeb.Endpoint.plug_builder_call/2
    (exchat 0.1.0) lib/plug/debugger.ex:136: ExchatWeb.Endpoint."call (overridable 3)"/2
    (exchat 0.1.0) lib/exchat_web/endpoint.ex:1: ExchatWeb.Endpoint.call/2
    (phoenix 1.5.10) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4
    (cowboy 2.9.0) /home/example/exchat/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
    (cowboy 2.9.0) /home/example/exchat/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
    (cowboy 2.9.0) /home/example/exchat/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
    (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

When I click on the “Live Dashboard” link (https://example.com/ex/dashboard), I get the same type of error:

##### Phoenix.Router.NoRouteError <small>at GET</small> <small>/ex/dashboard</small>

# no route found for GET /ex/dashboard (ExchatWeb.Router)

Just trying to get the default phoenix page working on a production website URL so I can begin practicing… Right now, I’m just randomly adding/subtracting “/ex” to various snippets in the endpoints/router files, probably breaking stuff in the process, and there is no good guide on the internet on just doing this basic thing of getting example.com:4000 to fully work on example.com/[some-directory]/

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews