Very basic question about serving multiple websites

OK - I am sorry if this is obvious to others…
But, if so, should be easy and quick to provide an answer :wink:

My setup of Sanic is on debian server. Currently serving “hello world”. My plan is (while learning sanic) to move 3 or 4 old websites (been inactive for some time) across from Flask and modernise them a little, while re-hosting them and reactivating them.
These websites are completely unrelated to each other.

I have sanic running - and is setup to restart each reboot - just by setting in crontab. like this:

@reboot screen -S sanic_server1 -dm bash -c 'source /root/start_sanic'

And the sh is:

#!/bin/bash
cd /root/sanic
source /root/sanic/env/bin/activate
sanic first.app --dev 

So the sanic console is running in a disconnect Screen session.

I was imagining that I would do it like this: for the second (and third, 4th, etc) website(s). I will just add another crontab entry , another server instance in its own Screen session, all from the same virtualenv… Like this :

#!/bin/bash
cd /root/sanic
source /root/sanic/env/bin/activate
sanic second.app --dev 

And so on for the third and 4th … etc. Is that how it is usually done ? or usually do most people run Sanic once only, and have really big server.py that includes functionality for each one of these website-backends, all in the same python file ?

I am not trying to go “non-standard”. Just am unaware what is the usual way people do it.

All constructive comments welcome

I do not thin there is a standard. The question really is what works for your deployment needs. From what I can gather, you are running Sanic on a bare metal machine (not in containers), and intend to have multiple instances running (presumably all on different ports).

You can of course roll your own solution, or use something like supervisor. So, as to that answer I will leave it to you. But, to answer the question about within Sanic: yes, you can run multiple applications side-by-side.

app1 = Sanic("One")
app2 = Sanic("Two")

if __name__ == "__main__":
    app1.prepare(host="0.0.0.0", port=8001)
    app2.prepare(host="0.0.0.0", port=8002)
    Sanic.serve()

This means that they will literally run side-by-side and will share the same event loop.

We unfortunately do not yet have a nice clean API to run them in their own processes, but it is possible (and a feature that will be added sometime before the next LTS). Today, you can do it like this:

from sanic import Request, Sanic, json

app1 = Sanic("TestApp")
app2 = Sanic("TestApp2")


def run(app: Sanic, port: int, single_process: bool = False):
    app.run(port=port, single_process=single_process)


@app1.get("/")
async def handler1(request: Request):
    return json({"foo": 1})


@app2.get("/")
async def handler2(request: Request):
    return json({"foo": 2})


@app1.main_process_ready
async def startup(app: Sanic):
    app2.router.reset()
    app.manager.manage("Secondary", run, {"app": app2, "port": 8002, "single_process": True})


if __name__ == "__main__":
    run(app1, 8001)
1 Like

ok, I got it … another perfect answer :pray:t2:

So, in summary if I have understood correctly, I have 2 options… (1) how I proposed originally and (2) how you showed that 2 apps can run within one running Sanic.

And there’s not really any preference - either way will work.

Thanks again for your reply :pray:t2:

I guess the question I would answer if it were my own projects are:

  1. how often will changes be deployed?
  2. how resource intensive will each app be? heavy or low traffic?
  3. what is your preferred deployment/management strategy?