Hi there, I will preface this by saying that I’m brand new to server stuff. I have used Linux for a very long time as a personal desktop computer, but not as a server exposed to the internet. I’ve previously only hosted Minecraft servers for my friends and also once had a VPS for a Discord bot, but otherwise never touched servers.
I’ve bought a VPS and domain name (let’s call it domain.com
) and have spun up a Nextcloud instance with it, currently at cloud.domain.com
. It’s all working smoothly and I’m happy with it.
I wanted to use this VPS to host multiple services. Currently wanting to self-host the following:
- Mail server
- Mastodon instance
- Matrix server
- Static website (on
domain.com
) - Forgejo instance
- Possibly other miscellaneous things I might want to put on it, but that’s what I’m planning for now
Now this is where the noob question comes in. I want to use this same VPS to host these services, probably as Docker containers, under subdomains like mail.domain.com
, mastodon.domain.com
, matrix.domain.com
, etc, with the root domain being used to host my static website. Is it possible to do this all on one VPS? What about all on one IP address just using different ports? e.g. could I have mastodon.domain.com
pointing to the same IP address as cloud.domain.com
but just a different port? How do I set up the DNS records to do this?
Currently I have an A record at domain.com
pointing to my VPS’s IP address (so I can ssh into it with ssh 0v0@domain.com
) and a CNAME record at cloud.domain.com
pointing to domain.com
. This was kind of a complete guess as to how to set this up as this is my first time managing a domain name and I didn’t know anything about DNS records before doing this. It seems to work with my current setup of just using the VPS for Nextcloud but obviously I want to do more with this VPS, either that or I’d like to reduce the specs of this VPS to save money as I picked an option that I imagined would be capable of hosting all these things. Is it possible to set up DNS records such that when you connect to subdomain.domain.com
it connects you to a specific port? Or is that not something DNS records can do, but I can set up server-side on my VPS?
My VPS provider also lets me buy additional IPv4 addresses for the VPS, if I can’t have them on the same IP address with different ports should I buy more IP addresses instead? How do I go about using different IP addresses for the same server?
Or do I need to host these services on completely different VPSes and point towards the different IP addresses with A records?
I’ve also heard of reverse proxies and that they might be able to achieve this, is this something I should look into or am I barking up the wrong tree here?
I know this question betrays a complete lack of knowledge as to how networking works, so please bear with me. Before someone says “well if you don’t know this, you shouldn’t be hosting all these services”, I have been finding the experience so far (i.e. just having set up my server with Nextcloud) to be fun and educational. I learn best by doing (I have ADHD and struggle with just reading books without doing any exercises alongside it) and I’d like to try host all these services just for the sake of the experience. I’m not hosting anything critical, it is purely for personal projects and I plan to have my friends on my Mastodon and Matrix servers. If this were for something serious I agree I’d get it managed by a professional sysadmin or at least someone who knows what they’re doing, but this is just for fun.
I don’t need my hand completely held, like I don’t need a step by step, but if I could at least be pointed towards concepts/things to research to achieve what I want, I would appreciate that. Literally if I could just be told search terms to look up that would be great, or if you have any more specific pointers than that with specific articles etc even better, or just explain on a high level how I would achieve this setup. Thanks in advance for any help!
TLDR: Is it possible to host these different services on one VPS with one IP address on different ports? If so, how do I set up the DNS records accordingly with my subdomains? If not, how should I achieve hosting these different services on different subdomains, preferably on the same VPS if at all possible?
Edit: Thank you for all the responses, sorry I couldn’t give everyone an individual response, but I’m grateful for all the help. I’ll look into reverse proxies :) Appreciate it!
For the web based services the best way would be to put a webserver in front of them to forward traffic to the Docker containers based on the domain. Nginx is popular for this. Personally I use Apache because I know it better.
So Nginx would listen on ports 443 and 80 and all the Docker ports should only be available internally. You can use Let’s Encrypt to get free SSL certificates for all your domains.
I dont really have the time to ezplain how (on break), but you can do everything you’re askijg without too much trouble.
It is possible, what you’re looking for is a reverse proxy: it’s an HTTP server that will listen to the standard ports for HTTP and HTTPS that will redirect traffic to the chosen service based on the domain name or URL.
In your case, every subdomain would point to your VPS’s IP and traffic that’s for
mastodon.example.tld
will be seemlesly proxied to your Mastodon container.Do some research on Caddy or Nginx, and I strongly recommend you learn Docker Compose and Docker networking, it will help you make it easier to maintain everything.
PS: CNAME pointing to A record is the way to go. You can do it one better by having a CNAME entry for
*.example.tld
, so that you don’t have to create a CNAME entry for every new service you deploy, but you better make sure that your reverse proxy won’t proxy requests to an unexpected container when requesting a bogus subdomain.Thank you! That’s very helpful.
As an aside/follow up question, I set up Nextcloud with their all in one container. I see they’ve got separate instructions for setting it up behind a reverse proxy. Is there a need to start from scratch and follow the reverse proxy instructions or can I somehow transfer my Nextcloud instance to be behind a reverse proxy?
I’m not familiar with Nextcloud, but from reading the How to use this? section of the README I believe you can run it behind a reverse proxy:
--publish 80:80
This means that port 80 of the container should get published on the host using port 80. It is used for getting valid certificates for the AIO interface if you want to use port 8443. It is not needed if you run AIO behind a web server or reverse proxy and can get removed in that case as you can simply use port 8080 for the AIO interface then.(Emphasis mine, in “Explanation of the command”)
My understanding is you only have to forward traffic from the reverse proxy to the port 8080. It uses a self-signed certificate though, so you might check if the reverse proxy you are using checks certificates signatures for upstream servers.
You can have multiple A records point to the same IP address, yes. Whatever website you’re managing your DNS with should allow you to create multiple subdomains as A/AAAA records. You can also (if you wish) use a wildcard to ensure that all subdomains go to your VPS’s server.
If you want to run multiple HTTP/HTTPS services on the same IP address (as it looks like you want to do), you’ll need to use a reverse proxy like Nginx. It can pattern match on domain names and ensure that traffic for one domain goes to an appropriate port/socket (mastodon.example.com being sent to the mastodon service). It’s not possible for DNS to specify port redirection.
Also, you’ve not mentioned it here, but look into https://letsencrypt.org/ for HTTPS certificates.
Some surface-level info while I’m waiting for my kids to finish the evening ritual: No need for an extra IP or VPS. You can host them all on the same IP and machine, provided there aren’tany conflicting port assignments.
In the DNS server, you can enter the various subdomains as CNAME pointing to the A record. The server-software is configured with which hostname it should operate as (For example, HTTP/1.1 has a Host-specification in the initial request, so that one server can host multiple domains on the same IP)
It should be noted that mail servers are indicated by an MX-record. And mailservers should also have a TXT record (SPF record) as part of spam prevention - some SMTP servers query this to ensure that your e-mail actually comes from you and not from someone spoofing the domain.
I used to have a zone file that did roughly what you’re trying to do, bit sadly I don’t have it anymore. But as you have DNS up and running, I’m sure you’ll be able to figure out the rest through checking some examples.
I half-baked an example zone file for you. I haven’t tested it, though. It assumes the domain of blargh.com being hosted from an IP of 123.123.123.123:
$TTL 86400 @ IN SOA ns1.blargh.com. admin.blargh.com. ( 2024102102 ; Serial (incremented) 3600 ; Refresh 1800 ; Retry 1209600 ; Expire 86400 ; Minimum TTL ) ; Name servers @ IN NS ns1.blargh.com. @ IN NS ns2.blargh.com. ; A Records @ IN A 123.123.123.123 ns1 IN A 123.123.123.123 ns2 IN A 123.123.123.123 ; CNAME Records mail IN CNAME blargh.com. mastodon IN CNAME blargh.com. matrix IN CNAME blargh.com. ; MX Records @ IN MX 10 mail.blargh.com. ; TXT/SPF Record @ IN TXT "v=spf1 mx ~all"
Oh, and two tips:
- Do not enable SMTP-relay on your SMTP server. This opens you up to abuse, and you (probably) don’t need it.
- Your DNS server should only talk to strangers about queries about your domain. Otherwise you might be part of a DNS amplification attack.
Hello my ADHD amigo! I see you have been taken care of quite well by the other comments. You guys are all awesome.
But yeah it’s just a reverse proxy that you need and most common is nginx or apache to implement it.
You can do this by configuring an HTTP server (e.g. Apache) to listen on port 80 and/or 443 (HTTP and HTTPS standard ports, respectively) and select which site to serve based on the name of the site requested. Apache documentation for this feature is here: https://httpd.apache.org/docs/2.4/vhosts/name-based.html
Note the sample config snippet showing how to set up a simple static site serving both
www.example.com
andother.example.com
usingServerName
in aVirtualHost
to select between them.You can also have Apache match a pattern in the URL and reverse proxy to another HTTP server – that can just be another program on the same computer listening on a different port, or could be on another computer entirely. See the simple reverse proxy config example on this page for a starting point: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html (Note also that you probably don’t need anything further down that page – e.g. the load balancer and failover stuff is not likely to be useful to you for a small personal project.)
Other popular HTTP servers can do this too; I just happen to have done it with Apache before.
Yes. As long as you have enough system resources, you can run whatever. If you want to refer to each service by an A record in DNS, just put a reverse proxy out in front. Otherwise, you can just refer to it’s forwarded port from the container if you wish.
Nginx proxy manager can do all of the routing for you if you are using docker. In a graphical interface without touching config. It’s on top of nginx so you get all its benefits!
I switched to a container running nginx proxy manager and haven’t looked back yet. I learned a whole lot setting up my proxy and TLS manually but now it’s really nice to be able to let the tool do its thing.