bitwalker / distillery

Simplify deployments in Elixir with OTP releases!
MIT License
2.97k stars 399 forks source link

Two releases on same host are conflicting #254

Closed faithandbrave closed 7 years ago

faithandbrave commented 7 years ago

Steps to reproduce

There are 2 servers:

  1. application server
  2. admin site server (for management application server)

Both servers uses Distillery.

When release application server by admin site server (execute deploy shell script), application server's sys_config and vm_args path be admin site path.

$ app_server/_build/prod/rel/app_server/bin/app_server describe
erts:        8.1
path:        /app_server/_build/prod/rel/app_server/releases/0.0.1-8820a10
sys.config:  /admin_site/_build/dev/rel/admin_site/var/sys.config
vm.args:     /admin_site/_build/dev/rel/admin_site/var/vm.args
name:        admin_site@127.0.0.1
cookie:      pvp{@]Nu4w;:p$@JkYr<r%XyjY~9?Bb9=q0t|y%+EDi0X!=B(U.D<uQ!V}D_3UkX
erl_opts:    none provided
run_erl_env: none provided

When start the application server, shutdown admin site.

Verbose Logs

==> Loading configuration..
==> Assembling release..
==> Building release app_server:0.0.1-531aeeb using environment prod
==> Discovered applications:
  logger_file_backend-0.0.9
    from: _build/prod/lib/logger_file_backend
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  uuid-1.1.5
    from: _build/prod/lib/uuid
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  eredis-1.0.8
    from: _build/prod/lib/eredis
    applications:
      :kernel
      :stdlib
    includes: none

  exredis-0.2.5
    from: _build/prod/lib/exredis
    applications:
      :kernel
      :stdlib
      :elixir
      :eredis
    includes: none

  redis_poolex-0.0.6
    from: _build/prod/lib/redis_poolex
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
    includes: none

  ex_json_schema-0.2.2
    from: _build/prod/lib/ex_json_schema
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  connection-1.0.4
    from: _build/prod/lib/connection
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  db_connection-1.0.0-rc.5
    from: _build/prod/lib/db_connection
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
      :connection
    includes: none

  mariaex-0.7.8
    from: _build/prod/lib/mariaex
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
      :crypto
      :decimal
      :db_connection
    includes: none

  poolboy-1.5.1
    from: _build/prod/lib/poolboy
    applications:
      :kernel
      :stdlib
    includes: none

  decimal-1.2.0
    from: _build/prod/lib/decimal
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  ecto-2.0.5
    from: _build/prod/lib/ecto
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
      :decimal
      :poolboy
    includes: none

  phoenix_ecto-3.0.1
    from: _build/prod/lib/phoenix_ecto
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
      :ecto
      :plug
    includes: none

  gettext-0.11.0
    from: _build/prod/lib/gettext
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
    includes: none

  cowlib-1.0.2
    from: _build/prod/lib/cowlib
    applications:
      :kernel
      :stdlib
      :crypto
    includes: none

  ranch-1.2.1
    from: _build/prod/lib/ranch
    applications:
      :kernel
      :stdlib
    includes: none

  cowboy-1.0.4
    from: _build/prod/lib/cowboy
    applications:
      :kernel
      :stdlib
      :ranch
      :cowlib
      :crypto
    includes: none

  phoenix_html-2.7.0
    from: _build/prod/lib/phoenix_html
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
      :plug
    includes: none

  phoenix_pubsub-1.0.1
    from: _build/prod/lib/phoenix_pubsub
    applications:
      :kernel
      :stdlib
      :elixir
      :logger
      :crypto
    includes: none

  eex-1.3.3
    from: /usr/local/Cellar/elixir/1.3.3/bin/../lib/eex
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  poison-2.2.0
    from: _build/prod/lib/poison
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  mime-1.0.1
    from: _build/prod/lib/mime
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  logger-1.3.3
    from: /usr/local/Cellar/elixir/1.3.3/bin/../lib/logger
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  crypto-3.7.1
    from: /usr/local/Cellar/erlang/19.1/lib/erlang/lib/crypto-3.7.1
    applications:
      :kernel
      :stdlib
    includes: none

  plug-1.2.1
    from: _build/prod/lib/plug
    applications:
      :kernel
      :stdlib
      :elixir
      :crypto
      :logger
      :mime
    includes: none

  phoenix-1.2.1
    from: _build/prod/lib/phoenix
    applications:
      :kernel
      :stdlib
      :elixir
      :plug
      :poison
      :logger
      :eex
    includes: none

  compiler-7.0.2
    from: /usr/local/Cellar/erlang/19.1/lib/erlang/lib/compiler-7.0.2
    applications:
      :kernel
      :stdlib
    includes: none

  elixir-1.3.3
    from: /usr/local/Cellar/elixir/1.3.3/bin/../lib/elixir
    applications:
      :kernel
      :stdlib
      :compiler
    includes: none

  stdlib-3.1
    from: /usr/local/Cellar/erlang/19.1/lib/erlang/lib/stdlib-3.1
    applications:
      :kernel
    includes: none

  kernel-5.1
    from: /usr/local/Cellar/erlang/19.1/lib/erlang/lib/kernel-5.1
    applications: none
    includes: none

  app_server-0.0.1-531aeeb
    from: _build/prod/lib/app_server
    applications:
      :kernel
      :stdlib
      :elixir
      :phoenix
      :phoenix_pubsub
      :phoenix_html
      :cowboy
      :logger
      :gettext
      :phoenix_ecto
      :mariaex
      :ex_json_schema
      :redis_poolex
      :exredis
      :uuid
      :logger_file_backend
    includes: none

  iex-1.3.3
    from: /usr/local/Cellar/elixir/1.3.3/bin/../lib/iex
    applications:
      :kernel
      :stdlib
      :elixir
    includes: none

  sasl-3.0.1
    from: /usr/local/Cellar/erlang/19.1/lib/erlang/lib/sasl-3.0.1
    applications:
      :kernel
      :stdlib
    includes: none

==> Generated overlay vars:
    release_name=:app_server
    release_version="0.0.1-531aeeb"
    is_upgrade=false
    upgrade_from=:latest
    dev_mode=false
    include_erts=true
    include_src=false
    include_system_libs=true
    erl_opts=""
    run_erl_env=""
    erts_vsn="8.1"
    output_dir="_build/prod/rel/app_server"
==> Copying applications to _build/prod/rel/app_server
==> Generating nodetool
==> Generating start_erl.data
==> Generating vm.args
==> Generating sys.config from config/config.exs
==> Including ERTS 8.1 from /usr/local/Cellar/erlang/19.1/lib/erlang/erts-8.1
==> Generating boot script
==> Generating RELEASES
==> Generating start_clean.boot
==> Applying overlays
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/pre_configure.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/pre_start.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/post_start.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/pre_stop.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/post_stop.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/pre_upgrade.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/hooks/post_upgrade.d
==> Applying mkdir overlay
    dst: releases/0.0.1-531aeeb/commands
==> Applying copy overlay
    src: priv
    dst: priv
==> Packaging release..
==> Archiving app_server-0.0.1-531aeeb
==> Writing tarball to _build/prod/rel/app_server/releases/0.0.1-531aeeb/app_server.tar.gz
==> Updating tarball
==> Tarball updated!
==> Release successfully built!

Description of issue

admin site rel/config.exs:

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: :dev

# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/configuration.html

# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile

environment :dev do
  set dev_mode: true
  set include_erts: false
  set cookie: :"pvp{@]Nu4w;:p$@JkYr<r%XyjY~9?Bb9=q0t|y%+EDi0X!=B(U.D<uQ!V}D_3UkX"
end

environment :prod do
  set include_erts: true
  set include_src: false
  set cookie: :"pvp{@]Nu4w;:p$@JkYr<r%XyjY~9?Bb9=q0t|y%+EDi0X!=B(U.D<uQ!V}D_3UkX"
end

# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default

release :admin_site do
  set version: current_version(:admin_site)
end

app server rel/config.exs:

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: :dev

# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/configuration.html

# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile

environment :dev do
  set dev_mode: true
  set include_erts: false
  set cookie: :"fF7YQ;ZC2RO)4YVc5W7r5N$ve5CJZH$_:nq.^Mr}xm$0`,WDMgY22QPGOBAHd4(M"
end

environment :prod do
  set include_erts: true
  set include_src: false
  set cookie: :"fF7YQ;ZC2RO)4YVc5W7r5N$ve5CJZH$_:nq.^Mr}xm$0`,WDMgY22QPGOBAHd4(M"
end

# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default

release :app_server do
  set version: current_version(:app_server)
  set overlays: [
    {:copy, "priv", "priv"}
  ]
end
bitwalker commented 7 years ago

Have you set RELEASE_CONFIG_DIR, RELEASE_MUTABLE_DIR, VM_ARGS_PATH or SYS_CONFIG_PATH in the environment of the host you are deploying to? If these are set globally, it will not be possible to run two releases on the same host, those env vars must be set in the context of the release itself only.

faithandbrave commented 7 years ago

No changed.

bitwalker commented 7 years ago

@faithandbrave I don't understand, are you saying you unset these globally and there was no change to the issue; or are you saying you didn't change them in the first place? Can you describe in more detail how you are deploying and running the releases?

faithandbrave commented 7 years ago

I don't set environment variables. I'll provide sample project.

faithandbrave commented 7 years ago

I created sample project. Please see:

https://github.com/faithandbrave/distillery_issue254_sample

The project is faithandbrave/elixir-phoenix-chunked-response-example based.

bitwalker commented 7 years ago

@faithandbrave It looks like your first problem is that you are running the app from the same directory the release is built in - you should not be doing that, you need to deploy the tarball (releases/<version>/<app>.tar.gz) to some directory, and run your app from there. Distillery can't guarantee things will work as expected when running from the release build directory because things can change underneath the app. It is actually explicitly called out in the documentation that you cannot perform hot upgrades in that directory.

Secondly, you aren't checking the exit code of the stop command you are issuing. If something is failing there, then the subsequent start command will naturally conflict with the release which is already running.

Lastly, stopping the daemon may not immediately be noticed by epmd, and thus when the next version is started the name may still appear to be registered. One approach would be to run epmd -kill && epmd -daemon after stop to ensure that it's flushed, but I would recommend instead sleeping for a second (e.g. sleep 1) before issuing the start command to avoid the race here.

If you resolve all of the above and you are still able to reproduce this problem, feel free to reopen this issue, and I'll look further, but for now there doesn't appear to be an actionable issue with Distillery here yet.

faithandbrave commented 7 years ago

@bitwalker Thanks a lot! I'll redesign my application.