Ask HN: How to setup own server hosting a service with API (and no front end)?
Hello HN, I'd like to use my own server to host a new service, accessible through an API, for an application (Win/Android/iOS) that I wrote and that already has users. No web frontend is necessary. Just the service that my app calls through an API.
So far I have relied on Google Cloud (App Engine, Cloud functions, etc..) to run these kinds of things but for the new service I find that Google Cloud is too limited. It also requires Mac computers with M1, running Monterey.
My question is: how do I get started setting up my own server(s)? I found numerous tutorials for setting up web servers but I don't need a website / frontend. Just the service with an API. I would also like to have some amount of scalability and protection against DDoS and similar attacks. Is this possible?
17 comments
[ 2.7 ms ] story [ 52.0 ms ] thread> It also requires Mac computers with M1, running Monterey.
Does the operation requiring macOS needs to be synchronous & instant or can it be asynchronous and respond within a few seconds/minutes?
I'd highly suggest decoupling the Mac-related part of the API into an asynchronous task, that way the actual API servers can be inexpensive Linux servers.
There would be an instant response as some kind of receipt confirmation, but the actual result would be delivered later (within some minutes).
The Mac machines can poll the DB for new items, process them, then submit the finished item of work back to the DB.
The client can poll (using the previously-obtained reference) for the status, or the completion of a job can notify the client (push notifications, websocket, etc) to avoid polling.
On the macOS side, you would need an application (in whatever language you prefer), that pulls events on Pub/Sub topic, processes the image/video, and then uploads the result to the cloud (either on API, or maybe directly to Cloud Storage or the database.)
This will ensure that your M1 machines are never directly exposed to the users, and allow you to scale out to multiple machines if needed.
On the macOS side, you would need an application (in whatever language you prefer), that pulls events on Pub/Sub topic,
I assume there's an easy way for my server to talk to Google Cloud's pub/sub?
The core of a worker is while (true) { download_job_request(); do_job(); send_result(); }. [4] Having the worker connect outwards to get the job, and submit the result, has benefits: (1) not having your worker "listen for incoming traffic" dramatically improves your security situation (2) you don't need to build a separate system to track which workers are accepting jobs right now.
I don't know your use case, or what physical and network security is truly needed. A Mac Mini or two in your house, ideally on a separate network [5], may be enough. Or you could rent from some cloud providers (Note: you do not want your Mac accepting connections from the Internet! You want a hardened remote-access method your cloud provider manages). Renting a cubic foot in a data center, and putting Mac Minis in it, is an in-between for cost/security, but will require the most expertise.
Workers running on cloud compute, or serverless, typically connect to the job queue using security permissions provisioned in that cloud. Just like your webapp talks to its database. If your workers are on-prem or in a different cloud, you'll need to provision access tokens/keys in your main cloud, and somehow make them available to your Mac software, which will use them to initialize the GCP/AWS/Azure SDK. Doing this "properly" is a big job! If you're going to YOLO and copy-paste them into a config file, I suggest (0) don't keep them in version control! (1) unique token per worker host (2) strictly limit tokens' permissions to what is needed (3) expire tokens after 120 days, meaning any worries about tokens issued in January, become moot by June.
You'd need a Mac-native solution to deploy and run software. If you have 3 "worker nodes", you can probably manage by hand. Past that, I've read Hashicorp's Nomad can manage deploying and running software on Macs like Kubernetes can on Linux.
You will eventually encounter situations like: (1) Workers lock up (2) Particular jobs take much longer than others (3) I just fixed an issue but there are 7 hours of jobs backed up in the queue... Until these cause unacceptable customer pain, I suggest you have one reliable and documented process to (1) Stop all workers (2) Empty the queue (3) Restart all workers. Practice this, to eliminate one source of stress during an outage. Also, make sure your UI behaves sensibly if the result for a particular job never appears.
If you get to the point of 24/7 monitoring, the things to page on are: (1) upper/lower thresholds for rate at which items enter the queue (2) same for items exiting the queue (3) upper threshold for queue size (4) upper threshold for per-job end-to-end time. All but the last should be trivial to monitor in a cloud queue product.
Definitely do some back-of-the-envelope math on the data size of the request and response. These can affect latency and cloud network egress cost. If that makes hybrid GCP/off-GCP impractical, I'd still recommend a worker-based solution that avoids exposing the Macs to user HTTP requests.
[1] https://docs.microsoft.com/en-us/azure/architecture/guide/ar... [2] https://aws.amazon.com/blogs/compute/running-cost-effective-... [3] yuppie_scum ↗ AWS has M1 instances too. watermelon0 ↗ Docker on Mac works fine on M1, but it's running on a Linux VM, and cannot access macOS APIs. malf ↗ What is the api? Storage heavy? Compute heavy? Why M1? rsp1984 ↗ Compute heavy. It would be using integrated AI accelerators that the M1 offers and which Monterey offers a convenient API to. The data would be image / video for the most part. The results would have to be stored for some time until user downloads them or some timeout is up (whichever is first). ameliaquining ↗ Which APIs do you want to use? I'd be really surprised if there wasn't a way to do whatever-it-is in the cloud on Linux, with comparable speed and ease-of-development to macOS, at dramatically less cost and operational overhead. The M1 might be the only consumer device that has the relevant kind of hardware, but you don't particularly want a consumer device; you want a server. Macs aren't designed to be used as servers and come with a lot of onerous restrictions that make them difficult and expensive to use that way (designed to prevent cannibalization of Apple's consumer business). Media processing isn't an uncommon use case for cloud services, so it'd be surprising if accelerator hardware for that use case were available only in consumer devices—unless it's a use case that doesn't really benefit from specialized accelerator hardware, which would suggest that you don't need such hardware either. rsp1984 ↗ I definitely need to use Monterey, as it offers simple APIs for certain tasks that would be possible, but very time consuming, to recreate on other OS. The M1 is optional, theoretically, but in practice makes things go much faster due to its accelerator cores, which the Monterey APIs are taking advantage of. ameliaquining ↗ I am having a really hard time thinking of cloud-relevant macOS APIs that don't have comparably-easy-to-use Linux equivalents, other than for building and testing macOS and iOS apps. Which ones do you want to use? Core ML? andrewf ↗ I agree with everything you've said about it being most practical to run services on Linux. If OP's business grows I think they'd be wise to pivot away from macOS to avoid future pain. ameliaquining ↗ I am not convinced that getting this set up on macOS in a way that can handle real user traffic with sufficient reliability (especially given an apparent lack of relevant experience) will take less time than porting it to Linux and then productionizing that. But I suppose anything's possible. onlywicked ↗ The simplest option is start the service and then tunnel it using Cloudflare Tunnel [0] with your own domain. speedgoose ↗ You can rent a M1 at Hetzner or Scaleway. Even AWS if you want to help Jeff Bezos to pay his bills.
How does Docker(and compatibles) handle M1? I’d recommend getting your app containerized as early as possible, that should improve the portability, operability and reliability stories.
But also, if OP sees a business opportunity today, and they've already solved it on top of macOS, I think they should strike while the iron is hot, with the code that exists. Most businesses die because they can't get enough users and keep them. IMO it makes sense to take on tech debt.
With this you won't have to expose port to public internet, and fiddle with your firewall and router.
Then you can use Cloudflare DDoS protection and other offerings.
[0] https://developers.cloudflare.com/cloudflare-one/connections...