<div dir="ltr"><div>Hi Simon,<br><br></div>As others have said, it's better not to touch the application code for multi-tenancy.<br><div><div><div class="gmail_extra"><br><div class="gmail_quote">2018-05-14 0:02 GMT+06:00 Simon Van Casteren <span dir="ltr"><<a href="mailto:simon.van.casteren@gmail.com" target="_blank">simon.van.casteren@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thanks everybody for the help. I was running my exe in standalone mode, so I didn't realise when you're running in fastCGI mode that Nginx will start processes for you. As I said, I don't have any frame of reference so I ask silly questions :).<div><br></div><div>As I see it now, I'll probably have an API endpoint "new_tenant" that will run the following:</div><div><br></div><div>* Run a shell script to set up a new DB and load default data.</div><div>* Write the necessary config for a new fastCGI server with the new connection string into my nginx config and reload nginx, as I've read this should not impact the other servers. I'll probably add some notification to myself whenever I do this so I don't silently start thousands of servers when something goes wrong.</div><div><br></div><div>It would be nice if I could have urweb do this. Is there a way to run shell scripts for urweb? And what about interacting stuff with file system? Both I have not seen happen in urweb, since it's mostly not necessary. Am I better off using the FFI for these things? I saw the BazQux reader uses the FFI to call into Haskell, that seems very nice even though it's probably overkill for this use case.</div><span class="HOEnZb"><font color="#888888"><div><br></div></font></span></div></blockquote><div><br></div><div>It's best to utilize an off-the-shelf CI & CD tools for this. I'd advise you to containerize your app (dockerize); next, automate the build & test & containerize parts (use say GitLab-CI or Travis-CI, or the like). And finally use some ready-made continous deployment tools to handle the configuration parts. Then adding a new tenant would be some script that will simply spin up a new container based off an existing image.<br><br></div><div>By the way, just last week I posted a PR to Ur/Web repo where I do functional tests for an Ur/Web app using Selenium. You might want to take a look.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="HOEnZb"><font color="#888888"><div></div><div>Simon</div></font></span></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">2018-05-13 16:13 GMT+02:00 Rob Manhatton <span dir="ltr"><<a href="mailto:rob.manhatton@gmail.com" target="_blank">rob.manhatton@gmail.com</a>></span>:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div text="#000000" bgcolor="#FFFFFF">After a light google, it seems that terraform's linode support isn't super mature yet, so if you're comfortable doing all the apps on the same VM and database end point then hold off on terraform a few more months (although you will really like having nearly 100% of your systems backed by code when you have bandwidth to look into it).<br><br><div class="gmail_quote"><div><div class="m_-479327099228007248h5">On May 13, 2018 9:03:28 AM CDT, Adam Chlipala <<a href="mailto:adamc@csail.mit.edu" target="_blank">adamc@csail.mit.edu</a>> wrote:</div></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="m_-479327099228007248h5">

  
    
  
  
    <div class="m_-479327099228007248m_2908577934982250575moz-cite-prefix">I'm not sure which aspect of deployment
      you're worried about.  With Apache, you can configure as many
      FastCGI applications as you'd like, and they will all be started
      automatically on each reboot.  It only takes a few lines of
      configuration per application.  Similarly, creating a new database
      is a few lines of shell script, using the .sql file that the
      Ur/Web compiler produces for an application.  All of the details
      are independent of application specifics.<br>
      <br>
      I am not aware of any existing tools for doing these simple steps
      automatically, but it should be easy to roll an all-inclusive
      shell script.<br>
      <br>
      On 05/13/2018 09:48 AM, Simon Van Casteren wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">I considered it briefly as I was doing some
        research on the topic. It's the first time I'll be running and
        deploying a SaaS app myself (I've so far always been on the
        programming side only) so it felt more natural to me to keep
        everything inside a single application. Running the application
        right now consists of me ssh'ing into a Linode and running the
        exe by hand. If I want to split this into one application per
        database (which does guarantee data security better, that's
        really nice) then deployment seems to become much more
        complicated. 
        <div><br>
        </div>
        <div>But let's say I do go that route. Is using one of the new
          deployment tools a good idea for a just-started scenario? I
          appreciate how ur/web uses very basic and simple tools, eg:
          Using curl in the Worldffi project to do HTTP requests, not
          having editor tooling but having the compiler use standard
          error formatting so emacs picks it up automatically. This is
          in strong contrast to the javascript community where I
          normally reside, which likes to re-implement things a lot. So
          I'd like to know what advice the community has on the right
          tools for setting up a new application and database
          automatically (probably via the C FFI?) and then running and
          updating them together. I would like to note that adding and
          running new clients without any manual work is strongly
          preferred.</div>
        <div><br>
        </div>
        <div>Because I don't have any idea of how I would handle this
          adding and deploying of clients, I can't weigh the two
          alternatives: Complicating the app with tenantIds, or
          complicating the deployment with seperate apps. </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">2018-05-13 15:31 GMT+02:00 Adam
          Chlipala <span dir="ltr"><<a href="mailto:adamc@csail.mit.edu" target="_blank">adamc@csail.mit.edu</a>></span>:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF">
              <div class="m_-479327099228007248m_2908577934982250575m_1427308567734777397moz-cite-prefix">Can you
                explain why you don't want to run separate applications
                with separate databases?
                <div>
                  <div class="m_-479327099228007248m_2908577934982250575h5"><br>
                    <br>
                    On 05/13/2018 05:50 AM, Simon Van Casteren wrote:<br>
                  </div>
                </div>
              </div>
              <div>
                <div class="m_-479327099228007248m_2908577934982250575h5">
                  <blockquote type="cite">
                    <div dir="auto">Hi,
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">I'm in the process of making a new
                        application for music schools, using ur/web for
                        front and backend. I'm at the point where I have
                        two customers and am starting to implement
                        support for multiple clients/tenants in one DB
                        (postgres). I've been planning to implement
                        multitenancy from the start, but haven't had the
                        time yet.</div>
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">Has anyone implemented a form of
                        multitenancy in ur/web before? </div>
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">I see two areas that need
                        consideration. </div>
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">1. Deciding which user belongs to
                        which tenant. Ideally I'd have a seperate url
                        for each tenant that I can give out to my
                        clients (=the schools), do some dns magic to
                        send them all to the same exe, extract the
                        tenantname from the url and save the tenantId in
                        a cookie. Also ideally, the user's url would not
                        change, ie. All urls should go to <a href="http://myschool.coolschools.be" target="_blank">myschool.coolschools.be</a>
                        during a session, not getting redirected at all.
                        This is all in an ideal situation of course.</div>
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">2. Database access: I'll have
                        tenantId columns in all tables + foreign keys
                        and indexes on these columns. I'm a bit afraid
                        I'll forget adding tenantId = cookie.tenantid
                        somewhere, so I was thinking I could make a
                        function that takes a sql_exp and a tenantId and
                        adds these clauses to all tables involved. Not
                        100% sure that will work but I think it's
                        possible, I haven't had to dive into the
                        internals of sql_exp yet. Secondly, I wonder if
                        I can somehow declare my endpoints to be
                        tenantdepandent (all but the most general will
                        be) maybe via newtyping the transaction datatype
                        and then allowing the execute only sql queries
                        that have the above function applied. Just
                        dreaming out loud here.</div>
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">I'd be very interested in any
                        ideas or examples! </div>
                      <div dir="auto"><br>
                      </div>
                      <div dir="auto">Simon </div>
                    </div>
                  </blockquote>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  

<p style="margin-top:2.5em;margin-bottom:1em;border-bottom:1px solid #000"></p></div></div><span><pre class="m_-479327099228007248m_2908577934982250575k9mail"><hr><br>Ur mailing list<br><a href="mailto:Ur@impredicative.com" target="_blank">Ur@impredicative.com</a><br><a href="http://www.impredicative.com/cgi-bin/mailman/listinfo/ur" target="_blank">http://www.impredicative.com/c<wbr>gi-bin/mailman/listinfo/ur</a><br></pre></span></blockquote></div><br><span>
-- <br>
Sent from my Android device with K-9 Mail. Please excuse my brevity.</span></div><br></div></div>______________________________<wbr>_________________<span class=""><br>
Ur mailing list<br>
<a href="mailto:Ur@impredicative.com" target="_blank">Ur@impredicative.com</a><br>
<a href="http://www.impredicative.com/cgi-bin/mailman/listinfo/ur" rel="noreferrer" target="_blank">http://www.impredicative.com/c<wbr>gi-bin/mailman/listinfo/ur</a><br>
<br></span></blockquote></div><br></div>
<br>______________________________<wbr>_________________<br>
Ur mailing list<br>
<a href="mailto:Ur@impredicative.com">Ur@impredicative.com</a><br>
<a href="http://www.impredicative.com/cgi-bin/mailman/listinfo/ur" rel="noreferrer" target="_blank">http://www.impredicative.com/<wbr>cgi-bin/mailman/listinfo/ur</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Cheers,<br>Artyom Shalkhakov<br></div>
</div></div></div></div>