In this post, I will share the detailed steps I took to set up the infrastructure for my Gemini API File Search Tool. I chose Oracle Cloud’s Always Free Tier because it offers generous resources that are perfect for hosting small to medium-sized projects without incurring costs.
For more details about Gemini File Search Tool, you can check my other blog post Revolutionizing RAG: Why Gemini File Search Tool is the great RAG-as-a-Service.
Architecture Overview
Here is a high-level view of how the components interact:
graph LR
User[User] -- HTTPS --> Nginx[Nginx Reverse Proxy]
subgraph Oracle Cloud Instance
Nginx -- Localhost:8000 --> App[Python App]
end
App -- Read/Write --> DB[(File Search Store)]
GitHub[GitHub Repo] -- SSH Deploy --> App
This setup ensures a robust, secure, and cost-effective environment for hosting the Gemini API File Search Tool.
1. Oracle Cloud Infrastructure Setup
Account and Instance Creation
First, I created an account on Oracle Cloud to access their Always Free services. Once logged in, I proceeded to set up the networking and compute instance.
- VCN Creation: I used the VCN Wizard to create a Virtual Cloud Network (VCN) with Internet connectivity. This automatically set up the necessary subnets, gateways, and route tables.
- Instance Configuration:
- Image: Ubuntu 22.04
- Shape: VM.Standard.E2.1.Micro (This shape provides 2 vCPUs and 1GB RAM, which is eligible for the Always Free tier).
- SSH Keys: I generated a new SSH key pair and saved the private key to connect to the instance later.
Security Rules
To allow traffic to reach the server, I configured the Ingress Rules in the Default Security List associated with my public subnet:
- SSH: Allow TCP port 22 (for remote access).
- HTTP: Allow TCP port 80 from
0.0.0.0/0(Anywhere). - HTTPS: Allow TCP port 443 from
0.0.0.0/0(Anywhere).
Once the instance was running, I connected to it via SSH:
ssh -i /path/to/private.key ubuntu@<YOUR_INSTANCE_PUBLIC_IP>
[!TIP] For a more detailed walkthrough on creating your first Linux instance, refer to the official Oracle Documentation.
2. Server Configuration
After logging in, I updated the package list and installed the essential tools and dependencies required for the project.
sudo apt update
sudo apt install -y python3 python3-venv python3-pip git
Application Setup
I cloned the project repository and set up a Python virtual environment to isolate the dependencies.
cd /home/ubuntu
git clone https://github.com/sabit-shaiholla/gemini-api-file-search-tool.git
cd gemini-api-file-search-tool
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install Python dependencies
pip install --upgrade pip
pip install -r requirements.txt
3. Domain and DNS Configuration
To make the application accessible via a friendly URL, I used DuckDNS, a free dynamic DNS service.
- I created a domain:
filequerysystem.duckdns.org. - I pointed it to the Public IP address of my Oracle Cloud instance.
- To ensure the IP address stays updated (in case it changes), I set up a cron script.
DuckDNS Update Script:
mkdir -p ~/duckdns
echo 'echo url="https://www.duckdns.org/update?domains=filequerysystem&token=<YOUR_TOKEN>&ip=" | curl -k -o ~/duckdns/duck.log -K -' > ~/duckdns/duck.sh
chmod 700 ~/duckdns/duck.sh
I then added this script to my crontab to run every 5 minutes:
*/5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1
4. Nginx and Firewall Setup
I used Nginx as a reverse proxy to handle incoming HTTP/HTTPS requests and forward them to the Python application.
Install Nginx and Configure Firewall
sudo apt install -y nginx
# Allow HTTP and HTTPS traffic through iptables
sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
sudo netfilter-persistent save
Nginx Configuration
I created a new configuration file for the site at /etc/nginx/sites-available/filequerysystem.
server {
server_name filequerysystem.duckdns.org;
# Increase client body size for file uploads
client_max_body_size 200M;
location / {
proxy_pass http://127.0.0.1:8080; # Forward to the app running on port 8080
proxy_http_version 1.1;
# WebSocket support (important for Streamlit)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts for long-running requests
proxy_read_timeout 86400;
proxy_connect_timeout 86400;
proxy_send_timeout 86400;
}
}
I enabled the site by creating a symlink:
sudo ln -s /etc/nginx/sites-available/filequerysystem /etc/nginx/sites-enabled/
sudo nginx -t # Test configuration
sudo systemctl restart nginx
5. SSL Certificate with Let’s Encrypt
Security is paramount, so I secured the application with an SSL certificate using Certbot.
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d filequerysystem.duckdns.org
Certbot automatically modified the Nginx configuration to force HTTPS and set up auto-renewal.
6. Application Service
To ensure the application runs continuously and restarts on failure, I created a systemd service file.
File: /etc/systemd/system/filequerysystem.service
[Unit]
Description=Gemini API File Search Tool
After=network.target
[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/gemini-api-file-search-tool
Environment="PATH=/home/ubuntu/gemini-api-file-search-tool/.venv/bin"
ExecStart=/home/ubuntu/gemini-api-file-search-tool/.venv/bin/python app.py
Restart=always
[Install]
WantedBy=multi-user.target
Then, I enabled and started the service:
sudo systemctl daemon-reload
sudo systemctl enable filequerysystem
sudo systemctl start filequerysystem
7. Automated Deployment
To streamline updates, I configured a GitHub Actions workflow. This workflow automatically deploys changes to the server whenever code is pushed to the master branch.
Workflow File: .github/workflows/deploy.yml
You can check the whole file here.
name: Deploy to Oracle Cloud
on:
push:
branches: [ master ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to Server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /home/ubuntu/gemini-api-file-search-tool
git pull origin master
source .venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart filequerysystem