iMessage on Android & Linux with BlueBubbles & ntfy.sh
Self Hosted iMessage & Notifications
iMessage on Android & Linux with BlueBubbles & ntfy.sh
Self Hosted iMessage & Notifications

BlueBubbles Logo
Disclaimer
This blog post is for informational purposes only, and anything you decide to implement on your own equipment is done at your own risk. The author is not responsible for any damage, data loss, or other consequences that may result.
GrapheneOS
It’s been 3 years since I posted about moving to GrapheneOS. In that time I’ve used GrapheneOS, stock Pixel Android, and (mostly) IOS.
When I made that post 3 years ago, GrapheneOS was in the middle of drama with other privacy focused Android OS’s as well as Louis Rossman. Not being one for drama, I was turned off by all of it and decided to move back to my iPhone.
Now 3 years later, GrapheneOS has become much more popular, even announcing an OEM partnership with Motorola.
The optics of an OEM partnership, wider adoption, and a nagging voice in my head about the privacy and security I was giving up by juggling stock Android AND an iPhone finally got me to reinstall GrapheneOS on my Pixel and give it another go.
Why GrapheneOS?
I’ll probably make another GrapheneOS post in the future. For now I’ll direct you to their features page if you’re curious.
A few features I think are worth mentioning:
- Attack surface reduction
- Sandboxed Google Play
- Enhanced permissions toggles
- Hardened libc & hardened memory allocator
- Privacy by default
- Auto reboot
Why iMessage?????
At this point you’re probably asking one of two things:
“I thought this was about iMessage on Android, why are we talking about GrapheneOS?”
or
“Why the hell would I want to use iMessage on my Android???”
Both valid questions, and both have the same answer:
I don’t want to break iMessage group chats and make all my friends update my contact info while I’m trialing a new operating system.
(In addition to using BlueBubbles I’m also forwarding all calls from my iPhone to my GrapheneOS Pixel).
If I do decide to move to GrapheneOS fully, I’ll most likely move all of my friends to my new phone number at that point, and forego BlueBubbles. However for those friends who don’t want to use signal, iMessage does give me the sense of more privacy over Google Messages, especially since I self host my notifications service for BlueBubbles (so no firebase notifications). So when the time comes I may stick with BlueBubbles after all.
Maybe you just want to be able to use iMessage on your Linux laptop, or maybe you want to use iMessage with your Apple fanboy friends. Whatever your reason, we’re going to get you up and running asap.
What is BlueBubbles?
From their Github:
BlueBubbles is an open-source ecosystem of apps aimed to bring iMessage to all your non-Apple devices! This includes Android, Windows, Linux, and your Browser.
It works by installing the BlueBubbles server on a mac that is connected to your iCloud account which will act as a relay to send/receive messages on behalf of your Android/ Linux machine, setting up some notifications, and downloading the client app to your Android/ Linux machine.

Pre-Requisites
Before we get started, there are a few things you’ll need:
- MacOS laptop/ server that you can leave running and connected to the internet. I believe you can use a Mac VM, but I have not tested it nor do I have instructions on how to even setup a MacOS VM.
- Currently registered phone number with iMessage
- Second phone number on your android phone
- If you want to use self hosted notifications without a proxy, you’ll need a way to connect back to your home network where your server lives (openvpn/wireguard/tailscale/cloudflare tunnel/etc.) You can use the cloudflare tunnels portion of this post to achieve this (just skip the guacamole setup).
What we’ll be doing
This setup will be done in 4 stages
- Prepare the mac server
- Install BlueBubbles server
- Install BlueBubbles client
- Install self hosted ntfy for notifications
Prepare the mac server
Docker Desktop
Once you’ve ensured your mac is fully up to date, you first need to install Docker.
Follow the instructions here to install Docker Desktop.
Disable Sleeping
You have 2 options to keep your mac awake when the lid is closed.
The first and more optimal option is a dummy HDMI plug like this one
Or you can run the following command:
sudo pmset disablesleep 1
Install BlueBubbles Server
IMPORTANT: If you want to self host notifications with ntfy, SKIP THE FIREBASE SETUP — we’ll be configuring notifications later
Follow the instructions provided by BlueBubbles to install the server on your Mac.
- Skip the Firebase configuration
- Set a strong password
- Choose your proxy of choice. I personally chose “LAN URL” as I am always connected to my home network via a VPN.
Private API
If you want enhanced features (like emoji reactions, faster message & attachment sending, read receipts, etc.) you need to enable the Private API.
To enable the Private API, you have to disable SIP. This is a personal security choice and it depends on how you use your Mac. Since this is ONLY a BlueBubbles/ Docker server in my homelab I was comfortable with it, but you may not be. Make the best choice for yourself.
Some of the warnings from BlueBubbles:
In order to get Private API features, you must disable MacOS extra security measures, called System Integrity Protection (SIP). The reason for this is because Apple does not let us access the internal iMessage code to do things like send reactions if SIP is enabled. When disabled, we can inject a helper process into the iMessage app to call the internal functions for us. In a way, disabling SIP is similar to Jailbreaking your iPhone.
Disable SIP at your own risk! We are not responsible for any damages, issues, or glitches caused by disabling SIP or by using the Private API.
If you use common sense when downloading and installing things, you should be just fine. Please be careful!
Disabling SIP on an Apple Silicon Mac disables the ability to install and run iOS Apps on your Mac. If this feature is important to you, don’t use the Private API.
If you do want to enable the Private API, use the BlueBubbles instructions here.
Install BlueBubbles Client
This is the most simple part of the process.
Download BlueBubbles from Google Play or install from the Github releases page.
Allow BlueBubbles to send you notifications.
You’ll step through the app setup and at the end will scan the QR code from your BlueBubbles server to connect your Android app to your BlueBubbles server.
NOTE: You may get a warning about having no Firebase notifications configured. This is expected as we’re about to setup ntfy for our self hosted notifications.
At this point you will also get a popup to enable the Private API features. If you don’t see this pop up go to Settings -> Advanced -> Private API Features
Self hosted notifications with ntfy
This is going to be the most involved part of this process, but when we’re done you will have a fully self hosted notifications service so your iMessage notifications never have to go through Google (or even leave your network).
I recommend setting up ntfy on the same server as BlueBubbles and using Docker to simplify the installation process.
On your server, create a ntfy directory and create the following docker-compose.yml file:
services:
ntfy:
image: binwiederhier/ntfy
container_name: ntfy
command:
- serve
environment:
NTFY_BASE_URL: "http://<yourserverip>"
NTFY_AUTH_FILE: "/var/lib/ntfy/auth.db"
NTFY_AUTH_DEFAULT_ACCESS: "deny-all"
#NTFY_AUTH_DEFAULT_ACCESS: "read-write" # ONLY USE FOR TROUBLESHOOTING AUTHENTICATION ERRORS. If troubleshooting, comment out the above 2 lines.
volumes:
- ./var/cache/ntfy:/var/cache/ntfy
- ./etc/ntfy:/etc/ntfy
- ./var/lib/ntfy:/var/lib/ntfy
ports:
- 80:80
healthcheck:
test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"]
interval: 60s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
init: true # needed if healthcheck is used. Prevents zombie processes
Then setup the ntfy container with:
docker compose up -d
Congrats, you now have a ntfy server!
ntfy authentication
To interact with the server we need to setup authentication. This is easily done with the following commands:
docker exec -it ntfy ntfy user add <username> # a username of your choice. Doesn't really matter what it is
docker exec -it ntfy ntfy access <username> "*" read-write
Test this users access with:
curl -u <username> http://<yourserverip>/v1/account
ntfy Android App
To configure notifications on your Android, you need the Android app.
Install the ntfy app from Google Play, F-Droid, or from the APK. If you truly don’t want any Google Services, I recommend installing from F-Droid (this is what I did) or the APK.
Allow ntfy to send Notifications.
Add your newly created user to the settings. Go to Settings -> Manage Users -> Add New User
For Service URL input http://<yourserverip>. Add the Username and Password that you just setup on your server.
Add ntfy as a Unified Push distributor in BlueBubbles
Back in the BlueBubbles app go to Settings -> Notification Providers and Toggle on “Unified Push”.
A URL will appear. It should look like http://<yourserverip>/<somestring>?up=1 Take note of the URL as you’ll need this for the next two steps.
Allow BlueBubbles to write to your ntfy server
Back on your BlueBubbles server, run the following command:
# <somestring> is the same string that you just grabbed from the URL above
# This command will allow BlueBubbles to write to your ntfy server for notifications
docker exec -it ntfy ntfy access "*" "<somestring>" write-only
Set ntfy as a webhook for BlueBubbles
On your BlueBubbles sever, navigate to API & Webhooks -> Manage -> Add Webhook.
For URL input the URL you grabbed two steps ago
For Event Subscriptions leave this set to All Events
Click Save
Test Your Notifications
Send your iMessage number a text from another phone. You should see a BlueBubbles notification pop up with the new message!
With that, you should now have a fully selfhosted way to use iMessage on an Android or Linux with no google notifications services!
To access this remotely, you’ll need to setup remote access back to your homelab.
Stay tuned for my next post on how to setup a VPN back to your homelab and how to automatically enable/ disable your VPN connection on GrapheneOS!
메타데이터
- post_id
- 9cd5a82a6713
- slug
- imessage-on-android-linux-with-bluebubbles-ntfy-sh-9cd5a82a6713
- url
- https://medium.com/@jonezy7173_88832/imessage-on-android-linux-with-bluebubbles-ntfy-sh-9cd5a82a6713
- canonical_url
- https://medium.com/@jonezy7173_88832/imessage-on-android-linux-with-bluebubbles-ntfy-sh-9cd5a82a6713
- author_url
- https://medium.com/@jonezy7173_88832
- status
- ok
- fetched_at
- 2026-06-29 01:02:39