Split Images for Instagram Without Killing Your iPhone Storage
Stop filling your iPhone with Instagram exports. Learn how to process landscape photos into Instagram carousels using Docker and iOS Shortcuts—without saving a single file to your Camera Roll. Images go from Lightroom to your NAS to Instagram, keeping your phone storage clean.
Split Images for Instagram Without Killing Your iPhone Storage
If you shoot landscape photos but want to post them on Instagram, you’ve got a problem: Instagram’s aspect ratios are terrible for wide shots. The usual solution is to split your image into a carousel, but every tutorial I found does the same annoying thing—saves multiple copies to your Camera Roll, eating your storage.
Here’s how I built an iOS Shortcut that processes images through a Docker container and delivers them straight to Instagram without touching my phone’s storage.
The Problem
Instagram carousels are perfect for panoramas. Split a 16:9 landscape shot into two vertical panels, swipe through them, done. But the standard workflow is:
- Export from Lightroom to phone (eating storage)
- Use an app to split it (creating more copies, eating more storage)
- Post to Instagram
- Remember to delete all the copies (you won’t)
I use Lightroom Mobile for editing. The originals live in Adobe’s cloud, which is fine—I don’t need them on my phone. But I still need to get processed images to Instagram, and I didn’t want temporary files cluttering my Camera Roll.
The Solution: Server-Side Processing with Docker
I built a simple Python image processor that runs in a Docker container on my home network. It handles:
- Splitting landscape images into carousel-ready panels
- Creating bordered versions for portrait posts
- Extracting EXIF data for captions
- Saving processed images to my NAS
The processor is a Flask API that accepts an image, processes it, and saves the results to my NAS. I then share from the NAS to Instagram—images never touch my phone’s storage.
What You Need
Hardware:
- A device that can run Docker (Raspberry Pi 4/5, NAS, old laptop, home server)
- A NAS or network storage location
- All on the same local network
Software:
- Docker
- Docker Compose (optional but recommended)
That’s it. Docker handles all the Python dependencies, no manual pip installs.
The Workflow
Here’s how it actually works for me:
- Edit photo in Lightroom Mobile
- Export/share from Lightroom
- iOS Shortcut intercepts the share
- Shortcut asks for a post name
- Image POSTs to my Docker container
- Container processes image and saves to NAS
- Caption gets copied to clipboard
- I open my NAS in the Files app
- Share the processed images from NAS to Instagram
- Paste caption, post
The key: images only exist in Lightroom’s cloud and on my NAS. My phone storage stays clean.
The Docker Setup
Project structure:
instagram/
├── docker-compose.yml
├── Dockerfile
├── flask_service.py
├── image_processor.py
└── requirements.txt
Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY flask_service.py image_processor.py ./
# Expose port
EXPOSE 5000
# Run the Flask app
CMD ["python", "flask_service.py"]
requirements.txt
Flask==3.0.0
Pillow==10.1.0
docker-compose.yml
version: '3.8'
services:
instagram-processor:
build: .
ports:
- "5000:5000"
volumes:
- /path/to/your/nas:/mnt/nas
environment:
- FLASK_ENV=production
restart: unless-stopped
Important: Change /path/to/your/nas to wherever your NAS is mounted. For example:
- Synology NAS:
/volume1/photos/instagram - SMB share:
/mnt/smb/instagram - Local directory:
/home/user/nas/instagram
Starting the Container
cd instagram
docker compose up -d
Find your server’s IP:
hostname -I
Your service is now running at http://YOUR_IP:5000.
The Image Processing Code
flask_service.py
from flask import Flask, request, jsonify
from image_processor import ImageProcessor
from pathlib import Path
import tempfile
app = Flask(__name__)
processor = ImageProcessor(output_dir="/tmp/processed_images")
@app.route('/process', methods=['POST'])
def process_image():
if 'image' not in request.files:
return jsonify({'error': 'No image provided'}), 400
image = request.files['image']
post_name = request.form.get('post_name', 'Untitled')
# Save temporarily
with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as tmp:
image.save(tmp.name)
temp_path = Path(tmp.name)
try:
# Process and save to NAS
result = processor.process_and_save(
temp_path,
nas_path="/mnt/nas",
post_name=post_name
)
return jsonify({
'caption': result['caption'],
'message': 'Images saved to NAS'
})
finally:
# Clean up temp file
temp_path.unlink(missing_ok=True)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
The Core Processing Logic
The image_processor.py does the heavy lifting:
For split panoramas:
width, height = original.size
mid_point = width // 2
left_panel = original.crop((0, 0, mid_point, height))
right_panel = original.crop((mid_point, 0, width, height))
Each panel gets saved at 1080px width max (Instagram’s limit), maintaining aspect ratio. They stitch together seamlessly in a carousel.
For bordered posts:
# Create 1080x1350 white canvas (Instagram portrait)
canvas = Image.new('RGB', (1080, 1350), 'white')
# Scale image to 95% width
target_width = int(1080 * 0.95)
# Center on canvas
EXIF extraction: Pulls camera make/model, aperture, shutter speed, ISO, focal length and formats like:
Post Name
Shot on @fujifilmuk X-T2
23mm | f/2.8 | 1/250s | ISO 200
All three files (bordered + two split panels) get saved to the NAS with the original filename plus suffixes: _bordered.jpg, _split_1.jpg, _split_2.jpg.
The iOS Shortcut
Create a shortcut with these actions:
- Receive Images from Share Sheet - Triggers when you share from Lightroom Mobile
- Get images from Shortcut Input - Grabs the exported image
- Ask for Text with prompt “Post name” - Single input for the post title
- Get contents of URL
- Method: POST
- URL:
http://192.168.1.158:5000/process(use your server’s IP) - Request Body: Form
image: Shortcut Inputpost_name: Provided Input (from Ask for Text)
- Get Dictionary Value - Get
captionfromContents of URL - Copy to Clipboard - Input: Dictionary Value
- Show Notification - “Images saved to NAS. Caption copied.”
That’s it. The shortcut completes in a couple seconds, the images are on your NAS, and the caption is ready to paste.
Posting to Instagram
- Open Files app on iPhone
- Navigate to your NAS
- Find the processed images (they’ll have the post name in the filename)
- Select the images you want (bordered for single post, both splits for carousel)
- Share to Instagram
- Paste caption from clipboard
- Post
The images are never in your Camera Roll. They go from Lightroom Cloud → Docker processing → NAS → Instagram.
Why Docker Makes This Better
Isolated environment: All dependencies contained. No “works on my machine” issues.
Easy updates: Change the code, rebuild the container. docker compose up -d --build
Portable: Move to a different server? Copy the files, run docker compose up -d. Done.
Automatic restarts: Container crashes? Docker brings it back up automatically.
No dependency hell: Python, Pillow, Flask—all handled in the container. Your host system stays clean.
NAS Integration
The Docker container mounts your NAS as /mnt/nas. When images process, they save directly there:
result = processor.process_and_save(
input_path,
nas_path="/mnt/nas",
post_name="Hampshire Streets"
)
This creates:
/mnt/nas/hampshire_streets_bordered.jpg/mnt/nas/hampshire_streets_split_1.jpg/mnt/nas/hampshire_streets_split_2.jpg
Access them immediately via Files app on iOS. No syncing, no waiting.
The Real Workflow
What I actually do:
- Edit in Lightroom Mobile on my phone
- Export → Share
- iOS Shortcut triggers
- Type post name: “Rainy Evening Portsmouth”
- Shortcut completes (2-3 seconds)
- Caption is on my clipboard
- Open Files app → NAS
- Share both split images to Instagram
- Paste caption
- Post
Storage impact on phone: Zero bytes. The exported image from Lightroom stays in memory during the share, never saves. Processed images live on NAS.
Limitations
Local network only: You need to be on your home WiFi. For me this is fine—I edit and post from home. If you want it to work anywhere, you’d need to expose the Docker container through a VPN or Cloudflare Tunnel.
NAS access required: Your iPhone needs network access to your NAS. Most support SMB/AFP and show up in Files app automatically.
Single image processing: I haven’t built batch processing. One image at a time works for my workflow since I’m curating posts individually anyway.
No error handling in the shortcut: If the server’s down, the shortcut fails silently. Should add a notification but haven’t needed it yet.
Docker Tips
View logs:
docker compose logs -f instagram-processor
Restart after code changes:
docker compose up -d --build
Check if it’s running:
docker compose ps
Stop the container:
docker compose down
Why This Actually Works
Most photography workflows assume you want everything on your phone. But if you’re using Lightroom Mobile with cloud storage, why duplicate everything locally? The originals are in Adobe’s cloud. The edits happen in Lightroom. The processed outputs go to Instagram.
The phone is just the interface. Docker handles processing. The NAS is permanent storage.
My Camera Roll has zero Instagram-related images. It’s just photos I’ve actually taken with my phone. Everything else lives where it should: Lightroom for archives, NAS for processed outputs, Instagram for published posts.
Next Steps
I’m tempted to add:
- Automatic posting via Instagram’s API (if they ever make that reasonable)
- Batch processing multiple images
- Web UI for browsing NAS images before posting
- Analytics on which posts perform best
But honestly, this works well enough that I haven’t been motivated to touch it.
The whole setup took maybe two hours. Most of that was getting the NAS mount working properly in Docker. If you’re already running containers at home, this is a solid addition to the stack. If you’re new to Docker, this is a good first project—simple service, clear inputs/outputs, solves a real problem.
The full code is on my GitHub if you want to adapt it for your own workflow.
Enjoyed this post?
Check out the prints from Portsmouth and beyond, all captured with charity shop cameras.