debops / ansible-nginx

Install and manage nginx webserver
GNU General Public License v3.0
50 stars 42 forks source link

Pheonix Elixir Upstreams ? #157

Open niccolox opened 7 years ago

niccolox commented 7 years ago

trying to work out how to configure debops-nginx with an Elixir / Phoenix app as upstream?

http://www.phoenixframework.org/docs/serving-your-application-behind-a-proxy

Phoenix generally runs on port 4000 but I actually want to have a number of apps and domains running with the same nginx as proxy

apologies if I am missing something super obvious

drybjed commented 7 years ago

The explanation on their site is totally unreadable. Did you recreate the nginx configuration they are suggesting already? Can you paste it here so we can see what's needed?

niccolox commented 7 years ago

lol

how is this?

https://medium.com/@a4word/setting-up-phoenix-elixir-with-nginx-and-letsencrypt-ada9398a9b2c

niccolox commented 7 years ago

the obvious question is where do I put the nginx config into a debops-nginx role?

I am not even sure what variable I use?

niccolox commented 7 years ago

a couple of examples of Ansible Phoenix alternatives https://github.com/HashNuke/ansible-elixir-stack https://github.com/lnikkila/ansible-phoenix

drybjed commented 7 years ago

Since I assume that you are writing a role for phoenix (because you are, right?) then the relvant dependent variables for debops.nginx would be:

phoenix__fqdn: 'phoenix.{{ ansible_domain }}'

phoenix__nginx__dependent_upstreams:
  - name: 'phoenix_upstream'
    server: 'localhost:4000'

phoenix__nginx__dependent_servers:
  - filename: 'phoenix'
    name: '{{ phoenix__fqdn }}'
    type: 'proxy'
    proxy_pass: 'http://phoenix_upstream'
    proxy_options: |
      proxy_redirect off;

Stick these in the phoenix/defaults/main.yml file, and in the playbook that runs the role, add:

- name: Configure Phoenix
  hosts: phoenix-hosts
  become: True

  roles:

    - role: debops.apt_preferences
      tags: [ 'role::apt_preferences' ]
      apt_preferences__dependent_list:
        - '{{ nginx__apt_preferences__dependent_list }}'

    - role: debops.ferm
      tags: [ 'role::ferm' ]
      ferm__dependent_rules:
        - '{{ nginx__ferm__dependent_rules }}'

    - role: debops.nginx
      tags: [ 'role::nginx' ]
      nginx__dependent_upstreams:
        - '{{ phoenix__nginx__dependent_upstreams }}'
      nginx__dependent_servers:
        - '{{ phoenix__nginx__dependent_servers }}'

    - role: phoenix
      tags: [ 'role::phoenix' ]

That should do the trick. If you stick with using the TCP port for the application instead of the UNIX socket, I suggest using debops.etc_services role to register this port in the /etc/services file, it will look nicer in application output that use it.

niccolox commented 7 years ago

thanks, I'll try to bang out a debops-lite phoenix role during the week

drybjed commented 7 years ago

@niccolox Great. I've added the proxy_redirect off parameter, since Phoenix guide has it included.

niccolox commented 7 years ago

tx, doing first pass now

niccolox commented 7 years ago

thanks for this, have an OK first version running

how do I add two ACME certs for two upstreams on the same server?

do I add config to the role stubbed above or add inventory settings?

I have example.com and example.org both on the same server and within the same phoenix umbrella app

happy to share access to private repo if thats helpful

I haven't generalized this yet ... thanks

niccolox commented 7 years ago

ok, I think I am stuck in a catch 22 i.e. I need to run the elixir/phoenix cowboy server AND nginx running passthrough for ACME registration

and also the ACME challenge/response file needs to be in the cowboy server as this is where the files are being loaded from and not nginx which is acting as a passthrough

I am looking at the wordpress debops contrib role and see that has a task specific to acme and I may need to run something like this for elixir/phoenix/cowboy and nginx as proxy

niccolox commented 7 years ago

this is the inventory host

phoenix__fqdn: 'www.example.com'
www_example_org__fqdn: 'example.org'
phx_starter: MIX_ENV=prod mix phx.server
pki_host_realms:
  - name: 'example.com'
    acme: True
    acme_subject: [ 'o=example.com o', 'ou=IT department', 'cn=example.com cn' ]
    acme_domains: [ 'example.com' ]
    acme_ca: 'le-staging'
    acme_alt_names:
      - 'ip:{{ ansible_default_ipv4.address }}'
      - 'uri:https://example.com/'
      - 'email:info@example.com'
      - 'dns:example.com'
  - name: 'example.org'
    acme_subject: [ 'o=example.org o', 'ou=IT department', 'cn=example.org cn' ]
    acme_domains: [ 'example.org' ]
    acme: True
    acme_ca: 'le-staging'
    acme_alt_names:
      - 'ip:{{ ansible_default_ipv4.address }}'
      - 'uri:https://example.org/'
      - 'email:info@example.org'
      - 'dns:example.org'

this is the role main

phoenix__nginx__dependent_upstreams:
    - name: 'example_com_upstream'
      server: 'localhost:4000'
    - name: 'example_org_upstream'
      server: 'localhost:4001'

phoenix__nginx__dependent_servers:
    - filename: 'example_com_upstream'
      name: 'example.com'
      type: 'proxy'
      proxy_pass: 'http://example_com_upstream'
      # acme: True
      # nginx_acme_server: True
      # ssl: True
      proxy_options: |
        proxy_redirect off;
    - filename: 'example_org_upstream'
      name: 'example.org'
      type: 'proxy'
      proxy_pass: 'http://example_org_upstream'
      # acme: True
      # nginx_acme_server: True
      # ssl: True
      proxy_options: |
        proxy_redirect off;

needless to say, this doesn't work, LE Acme fails because it cant fine the acme challenge

Parsing account key...
Parsing CSR...
Registering account...
Registered!
Verifying example.com...
Traceback (most recent call last):
  File "/usr/local/lib/pki/acme-tiny", line 198, in <module>
    main(sys.argv[1:])
  File "/usr/local/lib/pki/acme-tiny", line 194, in main
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/usr/local/lib/pki/acme-tiny", line 123, in get_crt
    wellknown_path, wellknown_url))
ValueError: Wrote file to /srv/www/sites/acme/public/.well-known/acme-challenge/djkfddfsjfdsjkldsfkdfskdfkskjfdjdfs-kJ-heE, but couldn't download http://example.com/.well-known/acme-challenge/djkfddfsjfdsjkldsfkdfskdfkskjfdjdfs-kJ-heE

also, the FQDN root domain is not for working example.com it redirects to www.example.com

I feel like it may be some config clash with the default domain

spent the weekend on this, will come back to it during the week

drybjed commented 7 years ago

Is the DNS correctly configured? Remember that the zone propagation might take some time. Check from multiple locations if your websites can be correctly resolved.

niccolox commented 7 years ago

I fixed the dns, thanks for the tip

I am stuck on the acme challenge / response step

Need to custom config phoenix static files and integrate with the acme tiny script

Is there an inventory host variable I can use that sends the acme challenge file to a phoenix static folder?

On Apr 17, 2017 3:18 AM, "Maciej Delmanowski" notifications@github.com wrote:

Is the DNS correctly configured? Remember that the zone propagation might take some time. Check from multiple locations if your websites can be correctly resolved.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/debops/ansible-nginx/issues/157#issuecomment-294445686, or mute the thread https://github.com/notifications/unsubscribe-auth/AAbsppT0drBV8JXdg9ruu3YZhj21Y-zYks5rwzxogaJpZM4M4XME .