Stop Copying Docker Files Manually – Use Docker Hub Instead
Deploy Your ML Model to Any Server in 30 Seconds
Hey there,
🚀 This is Part 5 of the MLOps for Beginners series:
Part 5: Docker Hub for easy deployments (you are here)
Remember 2 weeks ago when we deployed our model?
That docker save
→ scp
→ docker load
?
Yeah, about that...
The Deployment Dance We're All Tired Of
Picture this scene from 2 weeks:
# On your laptop
docker save sentiment-api:v2 > sentiment_v2.tar
scp sentiment_v2.tar root@server:/root/
# On your server
ssh root@server
docker load < sentiment_v2.tar
docker restart sentiment-api
# 10 minutes later...
"Wait, did I deploy v2 or v2-fixed?"
"Which server has the latest version?"
"Where did I put v1 in case I need to rollback?"
This is like emailing yourself code before Git existed.
We can do SO much better.
The "USB Stick" Problem Nobody Talks About
Here's what happens when you manage Docker images manually:
Monday: Deploy v1 to production (sentiment.tar) Tuesday: Quick fix, deploy v1.1 (sentiment_v1_1.tar)
Wednesday: "Let me just SSH and check which version is running" Thursday: Deploy v2 to staging... wait, which server is staging again? Friday: "I need to rollback!" frantically searching for old .tar files
I once spent 2 hours debugging why my model wasn't improving.
Turns out I was deploying the same old .tar file with a different name. 🤦♂️
Enter Docker Hub: Your Model's New Home
Docker Hub is like GitHub, but for Docker images.
Instead of this:
laptop → save as file → copy file → server → load file → run
You get this:
laptop → push to hub → pull from anywhere → run
That's it. No files, no SCP, no SSH needed for deployment.
What We're Building Today
Starting Point:
Build locally, save as .tar
Manually copy to each server
No version history
Pray you don't need to rollback
⬇️
End Goal:
Push once to Docker Hub
Deploy anywhere with one command
Full version history
Rollback in 10 seconds
Let's make deployment boring (in the best way possible).
Step 1: Set Up Docker Hub (3 Minutes)
First, get your free Docker Hub account:
Go to hub.docker.com
Sign up (free account gives you unlimited public repos)
Remember your username (you'll need it in 30 seconds)
That's it. No credit card, no complex setup.
Pro tip: Choose a username you won't be embarrassed about in production.
mlmaster69
might seem funny now, but explaining it to your CTO later... not so much.
I will be using “mlops91” for this series.
Step 2: Login From Your Machine
On your local machine (where you build your Docker images):
First, make sure docker is running, then run the following command:
docker login
You will be asked to open a URL and enter the code you see:
In your browser, enter the code:
Confirm, and you'll see:
Login Succeeded
This saves your credentials so you don't have to login every time.
Security note: On shared machines, remember to
docker logout
when done!
Step 3: Tag Your Image Properly
Here's where most people mess up.
Docker Hub uses this format: username/repository:tag
Let's fix your image name:
# See your current images
docker images
# You'll see something like:
# airline-sentiment v1 abc123def 2 hours ago 1.2GB
# Tag it properly for Docker Hub
docker tag airline-sentiment:v1 yourusername/airline-sentiment:v1
# Also create a 'latest' tag (this is important!)
docker tag airline-sentiment:v1 yourusername/airline-sentiment:latest
Think of tags like this:
:latest
→ The current production version:v1
,:v2
→ Specific versions you can rollback to:dev
→ Maybe your experimental version
Step 4: Push to Docker Hub (The Magic Moment)
# Push specific version
docker push yourusername/airline-sentiment:v1
# Push latest
docker push yourusername/airline-sentiment:latest
Watch the upload happen:
The push refers to repository [docker.io/yourusername/airline-sentiment]
5f70bf18a086: Pushed
3f7b3c317c4d: Pushed
v1: digest: sha256:abc123... size: 2827
🎉 Your model is now in the cloud!
Go to hub.docker.com and see your repository. Share that link with anyone!
Step 5: Deploy From ANY Server
Now the fun part. SSH into your server, and remove the old container:
docker stop sentiment-api
docker rm sentiment-api
Pull and run your image from Docker Hub:
# Pull the latest version
docker pull yourusername/airline-sentiment:latest
# Run it
docker run -d --name sentiment-api --restart unless-stopped -p 8000:8000 yourusername/airline-sentiment:latest
That's it! No file transfers. No tar files. Just pull and run.
Version Management Like a Pro
Deploying a New Version
On your local machine, in the project, lets do a small update simulating an API update.
Change the FastAPI Version to 2.0.0 in app.py
:
Then build the docker image again… you know how, yes?!
Then update the tags!
# Update the latest tag
docker tag yourusername/airline-sentiment yourusername/airline-sentiment:v2
docker tag yourusername/airline-sentiment yourusername/airline-sentiment:latest
# Push both tags
docker push yourusername/airline-sentiment:v2
docker push yourusername/airline-sentiment:latest
On your server:
# Pull new version
docker pull yourusername/airline-sentiment:v2
# Stop old, start new
docker stop sentiment-api
docker rm sentiment-api
docker run -d --name sentiment-api --restart unless-stopped -p 8000:8000 yourusername/airline-sentiment:v2
You will see now in your browser, we have version 2.0.0 running! it is that simple!
Emergency Rollback (10 Seconds!)
Something went wrong with v2? No problem:
# Stop the broken version
docker stop sentiment-api
docker rm sentiment-api
# Run the previous version (already pulled!)
docker run -d --name sentiment-api --restart unless-stopped -p 8000:8000 yourusername/airline-sentiment:v1
Since v1 is already on your server, rollback is instant. No downloading, no file hunting.
The One-Line Update Script
Save this as /root/update-model.sh
on your server:
#!/bin/bash
# Smart ML Model Updater
VERSION=${1:-latest}
IMAGE="yourusername/airline-sentiment:$VERSION"
echo "🚀 Deploying $IMAGE..."
# Pull the new image
docker pull $IMAGE
# Stop and remove old container
docker stop sentiment-api 2>/dev/null
docker rm sentiment-api 2>/dev/null
# Start new container
docker run -d --name sentiment-api --restart unless-stopped -p 8000:8000 $IMAGE
# Check if it's running
sleep 3
if docker ps | grep sentiment-api > /dev/null; then
echo "✅ Deployment successful!"
echo "🔗 API running at https://api.yourdomain.com"
else
echo "❌ Deployment failed! Check logs with: docker logs sentiment-api"
fi
Make it executable:
chmod +x /root/update-model.sh
Now deployment is literally:
# Deploy latest
./update-model.sh
# Deploy specific version
./update-model.sh v2
# Rollback to v1
./update-model.sh v1
Your Model Versioning Strategy
Semantic Versioning (v1.2.3)
Major (1.x.x): New model architecture
Minor (x.2.x): Retrained on new data
Patch (x.x.3): Bug fixes, preprocessing tweaks
Date-Based Versioning
docker tag mymodel:latest mymodel:2024-08-19
Perfect when you retrain regularly.
Experiment Tags
docker tag mymodel:latest mymodel:lstm-attention
docker tag mymodel:latest mymodel:bert-base
Great for A/B testing different architectures.
My recommendation? Start with simple v1, v2, v3. You can get fancy later.
Try This Right Now (Seriously, Do It!)
Let's practice the full workflow:
Push your current model:
docker tag airline-sentiment:v1 yourusername/airline-sentiment:v1
docker push yourusername/airline-sentiment:v1
Make a small change (even just update the response message)
Build and push v2:
docker build -t yourusername/airline-sentiment:v2 .
docker push yourusername/airline-sentiment:v2
Deploy v2 to your server:
ssh root@your-server
docker pull yourusername/airline-sentiment:v2
docker stop sentiment-api && docker rm sentiment-api
docker run -d --name sentiment-api --restart unless-stopped -p 8000:8000 yourusername/airline-sentiment:v2
Practice rolling back to v1:
docker stop sentiment-api && docker rm sentiment-api
docker run -d --name sentiment-api --restart unless-stopped -p 8000:8000 yourusername/airline-sentiment:v1
If you can do this, you're ready for production deployments!
Common Docker Hub Gotchas
"Denied: requested access to the resource is denied"
You forgot to include your username in the tag
Wrong:
docker push sentiment-api:v1
Right:
docker push yourusername/sentiment-api:v1
"Repository does not exist"
Docker Hub creates repositories automatically on first push
Make sure you're logged in:
docker login
Pushing is slow?
First push uploads everything (slow)
Subsequent pushes only upload changes (fast)
Use smaller base images when possible
Free tier limitations?
Unlimited public repositories
1 private repository for free
Rate limits: 200 pulls per 6 hours (plenty for personal projects)
You've Just Eliminated Deployment Friction! 🎊
Let's appreciate this transformation:
Before Docker Hub:
10 minutes to deploy
Manual file management
No version history
Rollback = panic mode
After Docker Hub:
30 seconds to deploy
Centralized image storage
Complete version history
Rollback = one command
You're not copying files anymore. You're publishing models.
That's not just an upgrade—that's a complete paradigm shift.
A Reality Check
Three weeks ago, deployment might have seemed like black magic.
Now you're:
Building Docker images
Pushing to registries
Deploying with one command
Rolling back without breaking a sweat
You know what? You're becoming dangerous (in the good way) 😎
What's Coming Next Week
Next week, we level up even more with your own private registry:
Your Own Private Docker Registry:
Keep your models in-house
No external dependencies
Unlimited private repositories
Deploy within your network
Complete control over your ML assets
Think of it as hosting your own private GitHub for Docker images.
This Week's Challenge
Ready to prove you've mastered Docker Hub?
Push 3 versions of your model to Docker Hub
Deploy v3, then rollback to v2, then to v1
Share your Docker Hub repository link in the comments
Extra credit: Deploy the same model to TWO different servers using Docker Hub. Time how long it takes. Bet it's under 2 minutes total.
One Last Thing...
Remember that deployment dance from the beginning?
The docker save
→ scp
→ docker load
shuffle?
You'll never have to do that again.
And that feeling when you type docker pull
and your model just appears?
That's not convenience. That's power.
Keep shipping,
Hasan
P.S. If someone asks "How do you deploy your ML models?", you can now say "I just push to Docker Hub and pull from anywhere." Watch their face. That's the face of respect.
Your Assignment This Week
Time to put this into practice! Here's your homework:
Required:
Create your Docker Hub account
Push at least 2 versions of your model
Successfully deploy and rollback on your server
Create the update script on your server
Optional but Recommended:
Try deploying at 2am (you'll see why automation matters)
Delete all .tar files (you won't need them anymore)
Teach someone else this workflow (teaching = learning × 2)
Next week, we'll build our own private registry so your secret sauce stays secret.
Until then, keep pushing... to Docker Hub! 🚀