
ImageFlex: Hosting a Dockerized WebP Converter on a Synology NAS
For a while my local image production workflow was a mess. Converting screenshots, photos, and design exports to WebP meant bouncing between online converters, Squoosh, or a command-line script I could never remember the flags for. I wanted something that lived on my home network, accepted batch uploads with drag-and-drop, and handed back ready-to-use .webp files without any friction.
The result is ImageFlex: a FastAPI-powered web app containerized with Docker and deployed on my Synology NAS so it is always on and accessible from any device on my local network. This post is less about the app itself and more about the end-to-end process of getting a Dockerized Python project running as a persistent local service on a Synology NAS using Container Manager.
The Idea
The app is intentionally minimal. Open it in a browser on any device in the house, drag images onto the drop zone, adjust quality if needed, and download WebP files. No accounts, no cloud service, no file size limits set by someone else's free tier. Because it runs on the NAS, it is available whether my laptop is open or not.
The technology choices were straightforward: FastAPI for the server because it is lightweight and async, Pillow for image conversion because it handles every format I throw at it, and Docker because the NAS already runs Container Manager and I wanted the app isolated from the NAS system itself.
Preparing the Project on Your PC First
Before involving the NAS at all, I assembled every file the container would need into a single folder on my PC called imageflex.
imageflex/
Dockerfile
docker-compose.yml
main.py
requirements.txt
static/
index.html
app.js
styles.css
The rule I follow: if the project cannot be described entirely by what is in that folder, I am not ready to deploy. Container Manager will build the image from this directory, so everything needs to be present and correct before it touches the NAS.
The Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
python:3.12-slim is published as a multi-platform image, so it works on both x86-64 machines and ARM64 systems (like the newer Synology models) without any changes. The --host 0.0.0.0 flag is important: it binds uvicorn to all interfaces inside the container so Docker can forward traffic to it. Binding to localhost only would make the app unreachable from outside the container.
The Compose File
services:
imageflex:
build: .
container_name: imageflex
ports:
- "8081:8000"
restart: unless-stopped
A few intentional choices here:
Port mapping. The container runs on 8000 internally. I map that to 8081 on the NAS. I initially used 8080, but nginx was already bound to that port on my NAS, so Docker could not bind a second container to it. Changing to 8081 resolved the conflict immediately.
No volumes. ImageFlex does not need persistent storage. Files are processed in memory and returned directly in the response. The container is fully self-contained. If I ever need to update the app, I rebuild the image and redeploy.
restart: unless-stopped. This tells Docker to bring the container back up automatically after a NAS reboot. The container stays down only if I explicitly stop it.
Deploying on Synology with Container Manager
With files in place on the NAS at /webprojects/imageflex, the deployment happens entirely inside Container Manager, not Web Station. Web Station is for PHP or Synology-managed sites. Container Manager is for Docker-based deployments.
Step 1: Prepare the NAS folder
Create /webprojects/imageflex on the NAS (via File Station or SSH) and copy the entire project folder into it. Every file the docker-compose.yml references must be present before Container Manager builds the image.
Step 2: Create a project in Container Manager
- Open Container Manager in DSM.
- Click Project in the left sidebar.
- Click Create.
- When prompted for the source path, point it to
/webprojects/imageflex. - Select
docker-compose.ymlas the compose file. - Set the project name to
imageflex. - Leave advanced settings at their defaults and proceed.
Container Manager reads the compose file, runs docker build . using the Dockerfile in that directory, pulls the python:3.12-slim layers, installs the Python dependencies from requirements.txt, and starts the container.
Step 3: Confirm it is running
Once the build completes, the project shows a Running status in the Container Manager project list. The container is now live on port 8081.
Accessing the App
Once the project shows Running, open a browser on any device on the same network and navigate to your NAS's local IP address on port 8081:
http://<your-nas-ip>:8081
You can find your NAS's local IP in DSM under Control Panel > Network, or by checking your router's DHCP lease table. The FastAPI app serves the drag-and-drop interface at the root route. Drop images in, adjust quality, and converted WebP files download directly to wherever your browser saves files.
Because restart: unless-stopped is set, the container comes back automatically after a NAS reboot. No manual action needed.
Things That Tripped Me Up
Port conflict on 8080. My NAS already had nginx running on 8080. Docker silently fails to bind a port that is already in use, and the container starts but is unreachable. Switching to 8081 in the compose file fixed it. The lesson: always double-check what ports are already occupied on the host before choosing a mapping.
--host 0.0.0.0 in uvicorn. Forgetting this means uvicorn only listens on 127.0.0.1 inside the container. The container starts, Docker performs the port forward, but there is nothing to forward to. Adding the flag is a one-liner fix but it is easy to miss if you are used to running uvicorn locally where localhost just works.
Web Station vs. Container Manager. Synology's Web Station is for traditional web hosting. Docker projects go through Container Manager under the Project section, which handles compose-based deployments end to end. Using the wrong section for the wrong tool costs time.
Conclusion
ImageFlex is a small tool that solves a real, recurring annoyance. Hosting it on the NAS means it is available on every device in the house without depending on a third-party service or keeping a laptop open. The total infrastructure cost is zero beyond hardware I already own.
The combination of FastAPI, Pillow, and a python:3.12-slim base image keeps the container lean. The Synology Container Manager project flow makes deployments and updates straightforward. If the app ever needs a new feature, I edit the source, rebuild the project in Container Manager, and it is live in under a minute.
Technologies Used: FastAPI, Python, Pillow, Docker, Synology DSM, Container Manager
Methodologies: Self-hosted tooling, containerized deployment, local-network web services
Share this article
Recommended Reading

Application Integration and Security at Full Sail University
A retrospective on Application Integration and Security, the course where I learned Python from scratch, worked through authentication and vulnerability management, and shipped a containerized application to AWS, all under the weight of a two-strike course policy.

Web Application Integration at Full Sail University
A retrospective on Web Application Integration (WDV4416), the course where I stopped asking whether my applications worked and started asking whether they would hold up: building unit tests, load testing a live server, automating monitoring with Selenium, and stress-testing under real traffic conditions.

Learning Server-Side Languages with Node.js at Full Sail University
A retrospective on Server-Side Languages with Node.js, the course where I built RESTful APIs from scratch, learned to test them with Jest and Postman, and connected a live backend to MongoDB running through Docker.