Mga Wika sa Programming
Functional programming language para sa pagbuo ng mga scalable at maintainable na aplikasyon
Lightweight processes and actor model enable millions of concurrent operations with low latency
Supervision trees and 'let it crash' philosophy create self-healing systems that recover from failures
Highly productive web framework with real-time features, LiveView, and performance rivaling compiled languages
Immutable data, pattern matching, and functional composition for maintainable, bug-resistant code
Built-in support for distributed systems with native clustering and inter-node communication
Update running production systems without downtime or dropping connections
# Add Erlang Solutions repository
wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb
sudo dpkg -i erlang-solutions_2.0_all.deb
sudo apt update
# Install Erlang (OTP 26)
sudo apt install esl-erlang -y
# Verify installation
erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'2. Install Elixir:# Install Elixir via apt
sudo apt install elixir -y
# Verify installation
elixir --version
# Should show: Elixir 1.14+ and Erlang/OTP 26
# Install Hex package manager
mix local.hex --force
# Install Phoenix archive (for Phoenix projects)
mix archive.install hex phx_new --force3. Install PostgreSQL (for database-backed apps):# Install PostgreSQL
sudo apt install postgresql postgresql-contrib -y
# Start PostgreSQL
sudo systemctl start postgresql
sudo systemctl enable postgresql
# Create database user
sudo -u postgres createuser --superuser $USER
sudo -u postgres psql -c "ALTER USER $USER WITH PASSWORD 'yourpassword';"4. Install Node.js (for Phoenix asset compilation):# Install Node.js 18
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install nodejs -y
# Verify installation
node --version
npm --version5. Create Your First Phoenix Application:# Create new Phoenix app
mix phx.new myapp --database postgres
# Navigate to project
cd myapp
# Configure database (edit config/dev.exs if needed)
mix ecto.create
# Install dependencies
mix deps.get
# Start Phoenix server
mix phx.server6. Access Your Application:Visit: http://localhost:40007. Set Up for Production (Systemd Service):# Build release
export MIX_ENV=prod
export SECRET_KEY_BASE=$(mix phx.gen.secret)
export DATABASE_URL=ecto://USER:PASS@localhost/myapp_prod
mix deps.get --only prod
mix compile
mix assets.deploy
mix release
# Create systemd service
sudo nano /etc/systemd/system/myapp.serviceAdd this configuration:[Unit]
Description=My Phoenix App
After=network.target
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/home/deploy/myapp
Environment="PORT=4000"
Environment="MIX_ENV=prod"
Environment="SECRET_KEY_BASE=your_secret_key"
Environment="DATABASE_URL=ecto://user:pass@localhost/myapp_prod"
ExecStart=/home/deploy/myapp/_build/prod/rel/myapp/bin/myapp start
Restart=on-failure
RestartSec=5
SyslogIdentifier=myapp
[Install]
WantedBy=multi-user.target8. Start Production Service:sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
# Check status
sudo systemctl status myapp
# View logs
sudo journalctl -u myapp -f9. Set Up Nginx Reverse Proxy:sudo nano /etc/nginx/sites-available/myapp
# Add this configuration:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Enable site
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx10. Set Up SSL with Let's Encrypt:sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :myapp,
version: "0.1.0",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
def application do
[
mod: {MyApp.Application, []},
extra_applications: [:logger, :runtime_tools]
]
end
defp deps do
[
{:phoenix, "~> 1.7"},
{:phoenix_live_view, "~> 0.20"},
{:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.10"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 3.3"},
{:phoenix_live_reload, "~> 1.4", only: :dev},
{:jason, "~> 1.4"},
{:plug_cowboy, "~> 2.6"}
]
end
end2. Runtime Configuration (config/runtime.exs):import Config
if config_env() == :prod do
database_url = System.get_env("DATABASE_URL") ||
raise "DATABASE_URL not available"
config :myapp, MyApp.Repo,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
socket_options: [:inet6]
secret_key_base = System.get_env("SECRET_KEY_BASE") ||
raise "SECRET_KEY_BASE not available"
host = System.get_env("PHX_HOST") || "example.com"
port = String.to_integer(System.get_env("PORT") || "4000")
config :myapp, MyAppWeb.Endpoint,
url: [host: host, port: 443, scheme: "https"],
http: [ip: {0, 0, 0, 0, 0, 0, 0, 0}, port: port],
secret_key_base: secret_key_base,
server: true
end3. Phoenix Endpoint Configuration (lib/myapp_web/endpoint.ex):defmodule MyAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :myapp
# WebSocket configuration
socket "/live", Phoenix.LiveView.Socket,
websocket: [connect_info: [session: @session_options]]
# Session configuration
plug Plug.Session,
store: :cookie,
key: "_myapp_key",
signing_salt: "random_salt"
plug MyAppWeb.Router
end4. Database Configuration (Ecto):# config/dev.exs
config :myapp, MyApp.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "myapp_dev",
stacktrace: true,
show_sensitive_data_on_connection_error: true,
pool_size: 105. Router Configuration:defmodule MyAppWeb.Router do
use MyAppWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {MyAppWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", MyAppWeb do
pipe_through :browser
live "/", HomeLive
live "/posts", PostLive.Index
live "/posts/:id", PostLive.Show
end
scope "/api", MyAppWeb do
pipe_through :api
resources "/users", UserController
resources "/posts", PostController
end
end6. LiveView Example:defmodule MyAppWeb.CounterLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
{:ok, assign(socket, :count, 0)}
end
def handle_event("inc", _params, socket) do
{:noreply, update(socket, :count, &(&1 + 1))}
end
def handle_event("dec", _params, socket) do
{:noreply, update(socket, :count, &(&1 - 1))}
end
def render(assigns) do
# Template with counter and buttons
end
end7. GenServer for State Management:defmodule MyApp.Counter do
use GenServer
# Client API
def start_link(initial_value) do
GenServer.start_link(__MODULE__, initial_value, name: __MODULE__)
end
def increment do
GenServer.call(__MODULE__, :increment)
end
def get_value do
GenServer.call(__MODULE__, :get_value)
end
# Server callbacks
def init(initial_value) do
{:ok, initial_value}
end
def handle_call(:increment, _from, state) do
{:reply, state + 1, state + 1}
end
def handle_call(:get_value, _from, state) do
{:reply, state, state}
end
end8. Supervision Tree:defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
MyApp.Repo,
MyAppWeb.Endpoint,
{Phoenix.PubSub, name: MyApp.PubSub},
MyApp.Counter # Add your GenServer here
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end9. Testing Configuration:# test/myapp_web/live/counter_live_test.exs
defmodule MyAppWeb.CounterLiveTest do
use MyAppWeb.ConnCase
import Phoenix.LiveViewTest
test "increments counter", %{conn: conn} do
{:ok, view, _html} = live(conn, "/counter")
assert view |> element("h1") |> render() =~ "Counter: 0"
view |> element("button", "+") |> render_click()
assert view |> element("h1") |> render() =~ "Counter: 1"
end
end10. Performance & Production Best Practices:Magsimula sa loob ng ilang minuto sa aming simpleng proseso ng pag-deploy VPS
I-deploy sa tungkol sa2minuto • Buong root access • Suporta sa pamamagitan ng tiket at email