diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5f606694d..9db4572af3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ jobs: env: MIX_ENV: test + PHX_CI: true strategy: matrix: diff --git a/installer/lib/mix/tasks/phx.new.ex b/installer/lib/mix/tasks/phx.new.ex index 24773ce64d..a1839f07af 100644 --- a/installer/lib/mix/tasks/phx.new.ex +++ b/installer/lib/mix/tasks/phx.new.ex @@ -140,7 +140,8 @@ defmodule Mix.Tasks.Phx.New do install: :boolean, prefix: :string, mailer: :boolean, - adapter: :string + adapter: :string, + inside_docker_env: :boolean ] @reserved_app_names ~w(server table) diff --git a/installer/lib/phx_new/generator.ex b/installer/lib/phx_new/generator.ex index 72fa54d65c..eb118749e4 100644 --- a/installer/lib/phx_new/generator.ex +++ b/installer/lib/phx_new/generator.ex @@ -181,6 +181,17 @@ defmodule Phx.New.Generator do phoenix_path = phoenix_path(project, dev, false) phoenix_path_umbrella_root = phoenix_path(project, dev, true) + # detect if we're inside a docker env, but if we're in github actions, + # we want to treat it like regular env for end-user testing purposes + inside_docker_env? = + Keyword.get_lazy(opts, :inside_docker_env, fn -> + if System.get_env("PHX_CI") do + false + else + File.exists?("/.dockerenv") + end + end) + # We lowercase the database name because according to the # SQL spec, they are case insensitive unless quoted, which # means creating a database like FoO is the same as foo in @@ -239,7 +250,8 @@ defmodule Phx.New.Generator do web_adapter_docs: web_adapter_docs, generators: nil_if_empty(project.generators ++ adapter_generators(adapter_config)), namespaced?: namespaced?(project), - dev: dev + dev: dev, + inside_docker_env?: inside_docker_env? ] %{project | binding: binding} diff --git a/installer/templates/phx_single/config/dev.exs b/installer/templates/phx_single/config/dev.exs index 3df396383e..09c07a396e 100644 --- a/installer/templates/phx_single/config/dev.exs +++ b/installer/templates/phx_single/config/dev.exs @@ -6,10 +6,13 @@ import Config # The watchers configuration can be used to run external # watchers to your application. For example, we can use it # to bundle .js and .css sources. -config :<%= @app_name %>, <%= @endpoint_module %>, - # Binding to loopback ipv4 address prevents access from other machines. +config :<%= @app_name %>, <%= @endpoint_module %>,<%= if @inside_docker_env? do %> + # Bind to 0.0.0.0 to expose the server to the docker host machine. + # This makes make the service accessible from any network interface. + # Change to `ip: {127, 0, 0, 1}` to allow access only from the server machine. + http: [ip: {0, 0, 0, 0}, port: 4000],<% else %># Binding to loopback ipv4 address prevents access from other machines. # Change to `ip: {0, 0, 0, 0}` to allow access from other machines. - http: [ip: {127, 0, 0, 1}, port: 4000], + http: [ip: {127, 0, 0, 1}, port: 4000],<% end %> check_origin: false, code_reloader: true, debug_errors: true, diff --git a/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs b/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs index d73204be7e..d54beabbaa 100644 --- a/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs +++ b/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs @@ -6,10 +6,13 @@ import Config # The watchers configuration can be used to run external # watchers to your application. For example, we can use it # to bundle .js and .css sources. -config :<%= @web_app_name %>, <%= @endpoint_module %>, - # Binding to loopback ipv4 address prevents access from other machines. +config :<%= @web_app_name %>, <%= @endpoint_module %>,<%= if @inside_docker_env? do %> + # Bind to 0.0.0.0 to expose the server to the docker host machine. + # This makes make the service accessible from any network interface. + # Change to `ip: {127, 0, 0, 1}` to allow access only from the server machine. + http: [ip: {0, 0, 0, 0}, port: 4000],<% else %># Binding to loopback ipv4 address prevents access from other machines. # Change to `ip: {0, 0, 0, 0}` to allow access from other machines. - http: [ip: {127, 0, 0, 1}, port: 4000], + http: [ip: {127, 0, 0, 1}, port: 4000],<% end %> check_origin: false, code_reloader: true, debug_errors: true, diff --git a/installer/test/phx_new_test.exs b/installer/test/phx_new_test.exs index 9690c7b66b..baaeeb328b 100644 --- a/installer/test/phx_new_test.exs +++ b/installer/test/phx_new_test.exs @@ -149,6 +149,7 @@ defmodule Mix.Tasks.Phx.NewTest do assert_file("phx_blog/config/dev.exs", fn file -> assert file =~ "esbuild: {Esbuild," assert file =~ "lib/phx_blog_web/(controllers|live|components)/.*(ex|heex)" + assert file =~ "http: [ip: {127, 0, 0, 1}, port: 4000]" end) # tailwind @@ -819,4 +820,13 @@ defmodule Mix.Tasks.Phx.NewTest do Mix.Tasks.Phx.New.run(["table"]) end end + + test "new from inside docker machine (simulated)" do + in_tmp("new without defaults", fn -> + Mix.Tasks.Phx.New.run([@app_name, "--inside-docker-env"]) + assert_file("phx_blog/config/dev.exs", fn file -> + assert file =~ "http: [ip: {0, 0, 0, 0}, port: 4000]" + end) + end) + end end