[Ur] Multitenancy
Artyom Shalkhakov
artyom.shalkhakov at gmail.com
Sun May 13 23:11:08 EDT 2018
Hi Simon,
As others have said, it's better not to touch the application code for
multi-tenancy.
2018-05-14 0:02 GMT+06:00 Simon Van Casteren <simon.van.casteren at gmail.com>:
> 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 :).
>
> As I see it now, I'll probably have an API endpoint "new_tenant" that will
> run the following:
>
> * Run a shell script to set up a new DB and load default data.
> * 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.
>
> 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.
>
>
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.
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.
> Simon
>
> 2018-05-13 16:13 GMT+02:00 Rob Manhatton <rob.manhatton at gmail.com>:
>
>> 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).
>>
>> On May 13, 2018 9:03:28 AM CDT, Adam Chlipala <adamc at csail.mit.edu>
>> wrote:
>>
>>> 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.
>>>
>>> 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.
>>>
>>> On 05/13/2018 09:48 AM, Simon Van Casteren wrote:
>>>
>>> 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.
>>>
>>> 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.
>>>
>>> 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.
>>>
>>> 2018-05-13 15:31 GMT+02:00 Adam Chlipala <adamc at csail.mit.edu>:
>>>
>>>> Can you explain why you don't want to run separate applications with
>>>> separate databases?
>>>>
>>>>
>>>> On 05/13/2018 05:50 AM, Simon Van Casteren wrote:
>>>>
>>>> Hi,
>>>>
>>>> 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.
>>>>
>>>> Has anyone implemented a form of multitenancy in ur/web before?
>>>>
>>>> I see two areas that need consideration.
>>>>
>>>> 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
>>>> myschool.coolschools.be during a session, not getting redirected at
>>>> all. This is all in an ideal situation of course.
>>>>
>>>> 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.
>>>>
>>>> I'd be very interested in any ideas or examples!
>>>>
>>>> Simon
>>>>
>>>>
>>> ------------------------------
>>>
>>> Ur mailing list
>>> Ur at impredicative.com
>>> http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
>>>
>>>
>> --
>> Sent from my Android device with K-9 Mail. Please excuse my brevity.
>>
>> _______________________________________________
>> Ur mailing list
>> Ur at impredicative.com
>> http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
>>
>>
>
> _______________________________________________
> Ur mailing list
> Ur at impredicative.com
> http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
>
>
--
Cheers,
Artyom Shalkhakov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.impredicative.com/pipermail/ur/attachments/20180514/a676bd2d/attachment-0001.html>
More information about the Ur
mailing list