defmodule Mix.Tasks.Blog.Server do @shortdoc "Run the blog preview and Micropub editing servers" @moduledoc """ Starts two Bandit servers from a single supervisor: * **Preview server** on port 4000 — serves the built `_site/` directory for local browser preview. * **API server** on port 4010 — Micropub + XML-RPC endpoint for MarsEdit. mix blog.server [--api-port 4010] [--preview-port 4000] Ports default to 4000 (preview) and 4010 (API) but can be set in config: config :static_blog, :preview_port, 4000 config :static_blog, :api_port, 4010 Command-line flags override config values. Before running, set a bearer token in the environment. The environment variable name defaults to `BLOG_TOKEN` but can be overridden via `config :static_blog, :auth_token_env_var, "MY_TOKEN"`. Press `Ctrl+C` twice to stop. """ use Mix.Task alias StaticBlog.Web.Server @impl Mix.Task def run(argv) do {options, _, _} = OptionParser.parse(argv, switches: [api_port: :integer, preview_port: :integer]) default_api_port = Application.get_env(:static_blog, :api_port, 4010) default_preview_port = Application.get_env(:static_blog, :preview_port, 4000) api_port = Keyword.get(options, :api_port, default_api_port) preview_port = Keyword.get(options, :preview_port, default_preview_port) token_var = Application.get_env(:static_blog, :auth_token_env_var, "BLOG_TOKEN") unless System.get_env(token_var) do Mix.raise(""" #{token_var} is not set. Generate a long random string and export it before running the server: export #{token_var}=$(openssl rand -hex 32) mix blog.server """) end Mix.Task.run("app.start") Application.ensure_all_started(:bandit) micropub_url = "http://localhost:#{api_port}/micropub" Application.put_env(:static_blog, :micropub_url, micropub_url) Mix.shell().info([:cyan, "→ Rebuilding _site/ with local micropub URL…"]) {:ok, _} = StaticBlog.Generator.build("_site", StaticBlog.RuntimePosts.all()) children = Server.child_specs(api_port, preview_port) {:ok, _pid} = Supervisor.start_link(children, strategy: :one_for_one) Mix.shell().info([ :green, "✓ Preview ", :reset, "http://localhost:#{preview_port}/" ]) Mix.shell().info([ :green, "✓ Micropub ", :reset, micropub_url ]) Mix.shell().info("Press Ctrl+C twice to stop.") Process.sleep(:infinity) end end