diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index a7d2570..1cb1144 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,137 +1,115 @@ +# docker/docker-compose.yml services: + # ================== Кластер EventHub ================== eventhub-node1: build: context: .. dockerfile: docker/Dockerfile - container_name: eventhub-node1 - ports: - - "8080:8080" - - "8081:8081" - - "8445:8445" - - "8446:8446" + hostname: eventhub-node1.local environment: - - NODE_NAME=eventhub-node1@eventhub-node1 - - HTTP_PORT=8080 - - WS_PORT=8081 - - ADMIN_HTTP_PORT=8445 - - ADMIN_WS_PORT=8446 - - MNESIA_DIR=/app/data + - NODE_NAME=eventhub-node1@eventhub-node1.local - RELEASE_COOKIE=${RELEASE_COOKIE} - JWT_SECRET=${JWT_SECRET} - volumes: - - eventhub-node1-data:/app/data + - JOIN_NODES=eventhub-node1@eventhub-node1.local,eventhub-node2@eventhub-node2.local,eventhub-node3@eventhub-node3.local networks: - eventhub-net + volumes: + - eventhub-node1-data:/app/data + ports: + - "8080:8080" # REST API + - "8081:8081" # WebSocket + - "8445:8445" # Admin REST + - "8446:8446" # Admin WebSocket restart: unless-stopped eventhub-node2: build: context: .. dockerfile: docker/Dockerfile - container_name: eventhub-node2 + hostname: eventhub-node2.local + environment: + - NODE_NAME=eventhub-node2@eventhub-node2.local + - RELEASE_COOKIE=${RELEASE_COOKIE} + - JWT_SECRET=${JWT_SECRET} + - JOIN_NODES=eventhub-node1@eventhub-node1.local,eventhub-node2@eventhub-node2.local,eventhub-node3@eventhub-node3.local + networks: + - eventhub-net + volumes: + - eventhub-node2-data:/app/data ports: - "8082:8080" - "8083:8081" - - "8447:8445" - - "8448:8446" - environment: - - NODE_NAME=eventhub-node2@eventhub-node2 - - HTTP_PORT=8080 - - WS_PORT=8081 - - ADMIN_HTTP_PORT=8445 - - ADMIN_WS_PORT=8446 - - MNESIA_DIR=/app/data - - RELEASE_COOKIE=${RELEASE_COOKIE} - - JWT_SECRET=${JWT_SECRET} - - JOIN_NODES=eventhub-node1@eventhub-node1 - volumes: - - eventhub-node2-data:/app/data - networks: - - eventhub-net - depends_on: - - eventhub-node1 + - "9445:8445" + - "9446:8446" restart: unless-stopped eventhub-node3: build: context: .. dockerfile: docker/Dockerfile - container_name: eventhub-node3 + hostname: eventhub-node3.local + environment: + - NODE_NAME=eventhub-node3@eventhub-node3.local + - RELEASE_COOKIE=${RELEASE_COOKIE} + - JWT_SECRET=${JWT_SECRET} + - JOIN_NODES=eventhub-node1@eventhub-node1.local,eventhub-node2@eventhub-node2.local,eventhub-node3@eventhub-node3.local + networks: + - eventhub-net + volumes: + - eventhub-node3-data:/app/data ports: - "8084:8080" - "8085:8081" - - "8449:8445" - - "8450:8446" - environment: - - NODE_NAME=eventhub-node3@eventhub-node3 - - HTTP_PORT=8080 - - WS_PORT=8081 - - ADMIN_HTTP_PORT=8445 - - ADMIN_WS_PORT=8446 - - MNESIA_DIR=/app/data - - RELEASE_COOKIE=${RELEASE_COOKIE} - - JWT_SECRET=${JWT_SECRET} - - JOIN_NODES=eventhub-node1@eventhub-node1 - volumes: - - eventhub-node3-data:/app/data - networks: - - eventhub-net - depends_on: - - eventhub-node1 - restart: unless-stopped - - observer_web: - build: - context: .. - dockerfile: docker/ObserverWeb.Dockerfile - container_name: observer_web - ports: - - "4000:4000" - environment: - - RELEASE_COOKIE=${RELEASE_COOKIE} - networks: - - eventhub-net + - "11445:8445" + - "11446:8446" restart: unless-stopped + # ================== Мониторинг ================== prometheus: image: prom/prometheus:latest - container_name: prometheus volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' - - '--storage.tsdb.path=/prometheus' - ports: - - "9090:9090" networks: - eventhub-net + ports: + - "9090:9090" restart: unless-stopped grafana: image: grafana/grafana:latest - container_name: grafana - depends_on: - - prometheus - ports: - - "3000:3000" environment: - - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} volumes: - - grafana-data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning + - grafana-data:/var/lib/grafana networks: - eventhub-net + ports: + - "3000:3000" restart: unless-stopped + # ================== Инструмент отладки ================== + observer_web: + build: + context: .. + dockerfile: docker/ObserverWeb.Dockerfile + environment: + - RELEASE_COOKIE=${RELEASE_COOKIE} + networks: + - eventhub-net + ports: + - "4000:4000" + restart: unless-stopped + +# ================== Сети и тома ================== +networks: + eventhub-net: + driver: bridge + volumes: eventhub-node1-data: eventhub-node2-data: eventhub-node3-data: prometheus-data: - grafana-data: - -networks: - eventhub-net: - driver: bridge \ No newline at end of file + grafana-data: \ No newline at end of file diff --git a/src/admin_app.erl b/src/admin_app.erl deleted file mode 100644 index f3c27e7..0000000 --- a/src/admin_app.erl +++ /dev/null @@ -1,49 +0,0 @@ --module(admin_app). --behaviour(application). - --export([start/2, stop/1]). - -start(_StartType, _StartArgs) -> - application:ensure_all_started(cowboy), - start_admin_http(), - {ok, self()}. - -stop(_State) -> - ok. - -start_admin_http() -> - Port = application:get_env(eventhub, admin_http_port, 8445), - - Dispatch = cowboy_router:compile([ - {'_', [ - {"/admin/health", admin_handler_health, []}, - {"/admin/stats", admin_handler_stats, []}, - {"/admin/users", admin_handler_users, []}, - {"/admin/users/:id", admin_handler_user_by_id, []}, - {"/admin/calendars", admin_handler_calendars, []}, - {"/admin/calendars/:id", admin_handler_calendar_by_id, []}, - {"/admin/events", admin_handler_events, []}, - {"/admin/events/:id", admin_handler_event_by_id, []}, - {"/admin/reports", handler_reports, []}, - {"/admin/reports/:id", handler_report_by_id, []}, - {"/admin/tickets", handler_tickets, []}, - {"/admin/tickets/:id", handler_ticket_by_id, []}, - {"/admin/tickets/stats", handler_ticket_stats, []}, - {"/admin/subscriptions", handler_admin_subscriptions, []}, - {"/admin/banned-words", handler_banned_words, []} - ]} - ]), - - Middlewares = [ - cowboy_router, - cowboy_handler - ], - - Env = #{dispatch => Dispatch}, - - cowboy:start_clear(admin_http, [{port, Port}], #{ - env => Env, - middlewares => Middlewares - }), - - io:format("Admin HTTP server started on port ~p~n", [Port]). \ No newline at end of file diff --git a/src/config/vm.args b/src/config/vm.args index c23151d..afea6c5 100644 --- a/src/config/vm.args +++ b/src/config/vm.args @@ -1,3 +1,3 @@ --sname ${NODE_NAME} +-name ${NODE_NAME} -setcookie ${RELEASE_COOKIE} -kernel inet_dist_use_interface {0,0,0,0} \ No newline at end of file diff --git a/src/eventhub_app.erl b/src/eventhub_app.erl index 1df5c9e..be3c64c 100644 --- a/src/eventhub_app.erl +++ b/src/eventhub_app.erl @@ -12,6 +12,7 @@ start(_StartType, _StartArgs) -> {ok, Pid} -> ok = infra_mnesia:init_tables(), ok = infra_mnesia:wait_for_tables(), + connect_nodes(), start_http(), start_admin_http(), % Запускаем сборщик метрик Prometheus @@ -126,4 +127,18 @@ start_admin_http() -> env => #{dispatch => AdminWsDispatch} }), - io:format("WebSocket started on ports 8081 (user) and 8446 (admin)~n"). \ No newline at end of file + io:format("WebSocket started on ports 8081 (user) and 8446 (admin)~n"). + +connect_nodes() -> + case os:getenv("JOIN_NODES") of + false -> ok; + NodesStr -> + Nodes = [list_to_atom(string:trim(N)) || N <- string:tokens(NodesStr, ",")], + lists:foreach(fun(Node) -> + case net_kernel:connect_node(Node) of + true -> io:format("Connected to ~s~n", [Node]); + false -> io:format("ERROR: Failed to connect to ~s~n", [Node]); + ignored -> ok + end + end, Nodes) + end. \ No newline at end of file