My Overly Complicated iOS Camera Upload Solution
This solution will transfer photos photos from my iPhone to my home NAS automatically (Or manually) based on location, and its all self-hosted and encrypted.
I used to use Dropbox for getting images from my iPhone, to a computer, but I wanted a better solution.
I had several issues with using Dropbox for this:
- Every single image I would ever take with my phone would be on the internet ready for Dropbox to have a data breach, or for some over-reaching government agency to collect. I don't like this. I just don't trust cloud storage unless I am the only one holding and controlling the keys.
- Even if I am already at home, it relies on my Internets upload speed.
- Storage space is limited. Even with my 26GB of space from referrals, it would get low after taking a long trip and taking a lot of video
- Without using extra software, the pictures would end up on a computer, not my NAS which is backed up.
So I went looking for solutions. There were plenty, but they all had issues too
- NextCloud - While I run NextCloud, I don't really like it all too much. It doesn't feel like something that is going to be there forever, and I didn't want to rely on something that may stop working. I did try the app, but it would frequently get confused if I took pictures in quick succession and then deleted them at the destination.
- Synology Apps - I tried many of the different Synology solutions, but all of their apps seem quite poorly made, and not very well supported. It also seems like the tools I would use for this seem to change and get replaced over the years. It also means I would need to connect to a VPN all the time while out, or expose my Synology NAS to the internet (Which is a TERRIBLE idea). I then would need to keep a Synology NAS for my solution to keep working, which I didn't like. I tried them anyway, and they all got confused too easily
- Seafile - I tried the Seafile app together with Seafile, and this too didn't work too well. It seems all of these applications have issues with seeing new pictures. I also just didn't like Seafile, and I didn't want to the data to be stored within it
- Others - I think there were other too, I will add them when I remember, but none of them really worked.
So I looked for a solution, and quite a few people suggested the iOS app PhotoSync (Link). I hesitantly (I like free...) bought it, and was surprised at the number of options available. I could sync pictures to just about anywhere, and pretty much however I wanted to.
I tested it to a local SMB share and it seemed to work well enough, so I had to figure out what transfer protocol to use next. I ended up settling on SFTP. It's very simple to set up, it has strong encryption, and its not some weird proprietary protocol that will disappear or become unsupported any time soon.
Now on to how I have it setup. It may seem complicated, but its just building on systems and infrastructure I already have in place, and when you break it down its quite simple. Here are all the components to my setup
- Clients: My iOS Devices
- Client Application: PhotoSync
- Protocol: SFTP
- Servers: Two Docker containers running OpenSSH
- Backend storage: Two Synology NAS devices (But could be replaced with anything)
Lets start from the bottom and work our way up
The storage is two Synology NAS devices. One at home, and one off-site on my colocated server (Read about it here). Both have redundant storage, BTRFS filesystems snapshots, frequent backups, and are fully encrypted. So the storage is very safe and secure.
Having two means that when I am at home, I can backup directly to the local NAS, but when I am outside of my home I can upload directly to the off-site NAS which has a much better internet connection. The two devices have a bi-directional sync using CloudStation ShareSync. So when I upload an image remotely, its back at home within seconds. And even if my home network is completely disconnected, it will just wait until it comes back. The upload from my phone will continue to work just as normal without interruption.
The main reason I decided to use the second off-site NAS for remote upload is because of the internet connection. I have had issues with packet loss and high latency, and general outages on my home internet connection. All of which would cause issues when trying to upload photos. Using the colocated server bypasses my home internet connection entirely and uses a much lower latency, and just generally better internet connection.
If you have great internet at home, you could just do this directly home without any issues. Remember that uploading TO your home will utilize the download bandwidth, which is usually higher
I decided to use SFTP because the client supported it, it was easy to setup and can be configured to use key based authentication with encryption. This makes opening up the connection to the world quite safe, while also making it impossible for anyone to intercept the traffic and view my images.
I have identical SFTP servers setup at home, and on my colocated server so that the process will work the same, no matter my location. I am using identical machine keys at both sites, so the PhotoSync app doesn't even know there is a difference, and authentication works the same. They are both running in Docker containers, and have the storage from the Synology NAS's mounted via SMB
I decided to use port 8000 since it wold dramatically cut down on bad traffic trying to hit the port. Opening port 22 is like opening a firehose of Chinese bots trying to connect
Here you can see some snapshots of how I have it configured. Here is the container running
Here you can see that I have the keys and photo directory mounted to persistent locations
Here is the storage mounted in fstab back to the Synology NAS
I have an external DNS record for upload.exampledomain.com that points to the colocated server's external IP. From here there is just an inbound NAT rule for port forwarding that takes it directly into the SFTP server
But, if I am inside my home, I don't want to to go there. So I have a local DNS record for upload.exampledomain.com that points to the internal IP of the Docker host on my home firewall. For good measure, I have an outbound NAT rule that will redirect any TCP/8000 traffic heading to the colocated server back to the local Docker host. So far this has proven 100% reliable at making sure my phone uploads over the local network no matter what. It doesn't matter if I have a stale DNS record, the firewall sends it where it needs to go
Because its going over the local network, the only limiting factor on speed is my local wireless, which is easily fast enough to transfer some pictures.
With all that out the way, here is how the application is actually configured.
I played around with the configuration for a while, and this is what I ended up with.
Here is where you configure the auto-upload. I have it set to my home and my work. Any time I reach the location, it uploads all photos
I have a quick sync setup when I force touch the icon on my home screen
You can decide exactly what you want on that screen
You can decide exactly how you want the filename to be recorded. I decided on a custom name with results in something like 2018-12-31 12.16.57.JPG
Here you can see all of the storage options available
And the configuration options within
Let me know what you think!