Current section
Files
Jump to
Current section
Files
examples/full_host.exs
use HostKit.DSL, providers: [HostKit.Providers.Caddy]
project :prod do
host :app do
hostname("app.example.com")
user("root")
sudo(true)
# For password-only hosts use:
# ssh password: secret_env("HOSTKIT_SSH_PASSWORD"), silently_accept_hosts: true
ssh(
identity_file: Path.expand("~/.ssh/id_ed25519"),
silently_accept_hosts: true
)
end
provider :caddy, HostKit.Providers.Caddy do
set(:sites_dir, "/etc/caddy/sites")
end
service :bootstrap do
package(:ca_certificates)
package(:build_essential, as: "build-essential", update: true)
mise path: "/usr/local/bin/mise", system_data_dir: "/usr/local/share/mise" do
tool(:erlang, "29.0.2")
tool(:elixir, "1.20.1")
end
end
service :api do
account("api", system: true, home: "/var/lib/api")
directory("/var/lib/api", owner: "api", group: "api", mode: 0o750)
env_file "/etc/api/api.env", owner: "root", group: "api" do
set(:mix_env, :prod)
secret(:database_url, env: "DATABASE_URL")
end
daemon "api.service" do
description("API service")
service_user("api")
working_directory("/opt/api")
environment_file("/etc/api/api.env")
exec_start(["/opt/api/bin/server"])
restart(:on_failure)
# Container-like isolation without a Docker daemon.
sandbox(:strict_app,
resources: [memory_max: "512M"],
sandbox: [read_write_paths: ["/var/lib/api"]]
)
listen(:http, port: 4000, on: :loopback)
wanted_by(:multi_user)
end
caddy_site :api, "api.example.com" do
encode([:zstd, :gzip])
reverse_proxy(listener(:http))
end
end
end