
A college chapter can use Coolify for application deployment and Mailcow for domain email while keeping code, accounts and access under the organization’s control. The tradeoff is ongoing responsibility for availability, email deliverability, membership changes and handover to the next team.
I set up this infrastructure as ACM MPSTME’s Webmaster and continue to operate it as Chairperson. Coolify hosts applications and bots; Mailcow handles mail for 7–9 college committees and provides an @mpstmeacm.com mailbox for every ACM member, approximately 250 people. Discord roles and account linking also support members-only spaces.
This is a case study of the setup we operate, including a readiness check for a Discord bot and the DNS work behind mail delivery. It is not a claim that self-hosting removes hosting costs or maintenance work.
How does Coolify deploy college applications and bots?
Coolify is an open-source, self-hosted platform-as-a-service. You give it a server, point it at a repository or a Dockerfile, and it builds the app, runs it in a container, and puts it behind a reverse proxy with HTTPS certificates it renews on its own. It’s the Vercel or Heroku experience on hardware you control.
I set up the chapter’s GitHub organization at the same time, with its GitHub Apps and CI/CD, so the code and the place it runs both belong to ACM rather than to whoever happened to write it. Coolify now runs the chapter website, the chapter’s Discord bot, and apps for other committees and clubs, including the college’s Railway Concession system.
One detail from this setup worth copying is the health check. A Discord bot has no web server, so by default there’s nothing for the platform to probe, and a bot that has lost its connection to Discord still looks “running”. So acm-cord, our bot, serves a tiny endpoint that reports whether it’s actually connected:
async def health(_request):
ready = bot.is_ready() and not bot.is_closed()
return web.json_response(
{"status": "ok" if ready else "starting", "ready": bot.is_ready()},
status=200 if ready else 503,
)
The Docker image’s HEALTHCHECK probes it every 30 seconds, so “running” in the dashboard means connected to Discord, not just that the process exists.
What does running Mailcow email involve?
Mailcow is an open-source mail server suite that runs in Docker: Postfix to send and receive, Dovecot for mailboxes, Rspamd for spam filtering, and a webmail client, managed from one admin panel.
Deploying Mailcow provides the mail services; it does not guarantee inbox placement. I configured SPF, DKIM and DMARC to authenticate messages and set the domain’s handling policy. These records are part of deliverability, alongside sender reputation and how the server is used. The following abbreviated records illustrate our setup rather than values to copy into another domain:
mpstmeacm.com. TXT "v=spf1 mx ~all"
dkim._domainkey TXT "v=DKIM1; k=rsa; p=MIIBIjANBg…" (2048-bit key)
_dmarc TXT "v=DMARC1; p=quarantine; rua=mailto:…; fo=1"
- SPF lists which servers may send mail for the domain. Ours says: only the domain’s own mail server, and treat anything else with suspicion.
- DKIM signs messages with a domain’s private key. Receivers use the public key in DNS to verify the signature and the integrity of the signed content; it does not establish the identity of the individual author.
- DMARC requires the visible From domain to align with a domain authenticated by SPF or DKIM. Our policy asks receivers to quarantine messages that fail that check and send reports. The reports help identify legitimate senders that need configuration as well as unauthorized use of the domain.
The DNS records are only the minimum, though. They make your mail eligible to be trusted; they don’t make it trusted. Reputation builds up from how the server behaves over time, and since seven to nine committees now send through the same server, it’s a shared reputation. One committee blasting a stale mailing list affects everyone else’s deliverability, so running the server also means paying attention to how it’s being used.
The records above are public. Anyone can look up a domain’s SPF, DKIM and DMARC records, and checking them for a domain you care about is a good habit. Nothing in this post goes beyond what DNS already publishes.
How do member mailboxes support a student chapter?
Because the mail server is ours, every ACM member gets their own @mpstmeacm.com address, hosted and managed on that same Mailcow.
Hosted email is priced per seat. For a chapter of about 250 members, a mailbox each would be a monthly bill the chapter could never justify. Self-hosted, a new mailbox costs a few clicks in the admin panel and no licence fee. Members get an address that says they’re writing on behalf of the chapter, and the chapter decides what happens to those addresses, not a billing page.
How does Discord automate member onboarding?
The chapter’s Discord is organised around departments and positions, so access matters: a Tech executive should see the Tech channels, and what else they see depends on their position. Handing that out by hand to every new member at the start of the year is a slow evening with a lot of mistakes, so a bot does it.
An organizer registers a member with a command, or a script registers a whole intake from a CSV through a webhook. For each person the bot creates a unique invite that expires after seven days, saves it against their name, department and position in PostgreSQL, and emails it to them. When someone joins, the bot looks at which of its invites was just used, finds the member it belongs to, gives them their position role (executive, core or supercore) and their department role, renames them to their real name with a department tag, and deletes the invite.
It’s a heuristic rather than a guarantee: Discord doesn’t tell a bot which invite a new member used, so the bot infers it from invite use counts, and two joins in the same instant could be mixed up. In exchange, nobody has to match usernames to people by hand.
acm-cord isn’t the first version of this idea. I wrote the first one in Java for the 2024–25 committee, and the same pattern has run the MUN Society’s Discord and Taqneeq’s CyberCypher hackathon, where it onboarded 1,100+ participants into their team channels. The Discord bots page has the details of each.
How does Discord account linking restrict Minecraft access?
For 2026–27 the chapter also runs a Minecraft server that only ACM members can play on. Knowing the address isn’t enough: before you can play, you have to link your Minecraft account to your Discord account, and the only way to do that is through the chapter’s Discord bot.
That bot lives only in the ACM server, so nobody outside the chapter can even message it. Being in the ACM Discord is already proof of membership, because onboarding is how you get in, so the Minecraft server doesn’t need a member list of its own. It reuses the one the chapter already maintains.
It’s the least “infrastructure” thing on this list, but it follows the same rule as everything else here. Access comes from being a member of the chapter, and the chapter controls the list.
Which college services depend on this infrastructure?
What started as ACM’s setup has become shared infrastructure:
- ACM itself: the chapter website, a mailbox for every member, the Discord bot and the Minecraft server.
- Seven to nine college committees and fests, including Taqneeq, Sattva and Social Conclave, that send and receive their mail through the same Mailcow server.
- Apps for other committees and clubs, deployed on Coolify, including the Railway Concession system that MPSTME students use.
That changes what a mistake costs. When it was only ACM’s mail, a bad day was ACM’s problem. Now a mistake on that server reaches committees I’m not part of.
What should the next infrastructure maintainer know?
Self-hosting doesn’t remove the cost, it changes who pays it. Instead of a monthly bill there’s an operator: someone who patches the server, watches the mail queue and answers when a committee’s mail stops arriving. I wrote about the same idea from a different angle in When a form becomes infrastructure. The software is only half of what you’re responsible for.
Email is the part that never stays done. Not because Mailcow is difficult, but because deliverability isn’t something you configure once. SPF, DKIM and DMARC get you in the door; how the server is used decides whether you stay.
Automate the people work. Some of the most useful code in this setup isn’t infrastructure at all. It’s the bot that turns “please give me access to the Tech channels” from a message someone has to answer into something that has already happened by the time they join.
The real test is the handover. None of this matters if it only works while I’m around. The whole point of moving the chapter onto infrastructure it owns is that the next team can pick it up, so it has to make sense to someone other than the person who built it.
The project summary is on the MPSTME ACM infrastructure page.
Questions or corrections? Email Kartik. Read about this site's authorship and publishing.
Security engineer and backend developer in Mumbai. Available for web-app security testing, penetration testing, and backend/API builds.
Work with me →