Guide to Using “Shell” Deployments in GRACE
EveryoneMLOps essentials
stand: 2024-06-10
Overview
The Shell Deployments feature in GRACE allows you to run any service you define via a shell script, exposed on port 8000. You have full control over the environment, dependencies, and service logic. The base environment is Ubuntu + Python.
- Image Building – Create a snapshot of your application environment.
- Deployment – Launch the snapshot as a running service.
Phase 1: Image Building
-
(Optional) Define
grace.apt
If your service requires system-level packages, list them in a file namedgrace.apt. These will be installed via theaptpackage manager during image build.
Examplegrace.apt:curl libssl-dev -
Provide Image Metadata
When prompted, enter:- Name – A unique identifier for your image.
- Version – Useful for tracking changes.
- Description – Brief summary of what the image does.
-
Define
grace.sh
This shell script is the entry point for your service. It should:- Set up the environment.
- Start your service on port 8000.
grace.sh:uv sync uv run fastapi run app.py --port 8000 -
Build the Image (Snapshot)
From your project directory, initiate the image build process. This will package your code, dependencies, and any specified system packages into a deployable snapshot.
Phase 2: Deployment
-
Deploy the Built Image
Select the image you built in Phase 1. -
Configure Deployment Settings
Provide:- Name – Deployment name.
- Resources – CPU, memory, etc.
- Scaling Strategy – Optional; define how the service scales.
-
Click Deploy
Your service will start and be accessible on port 8000.
If the deployment fails, inspect the logs to troubleshoot.
Example Project
Below is an example of a simple FastAPI service and the required configuration files for a shell deployment in GRACE:
app.py
from fastapi import FastAPI, HTTPException
import numpy as np
import pandas as pd
from pydantic import BaseModel
app = FastAPI()
class InputData(BaseModel):
MedInc: float
HouseAge: float
AveRooms: float
AveBedrms: float
Population: float | int
AveOccup: float
Latitude: float
Longitude: float
class EmptyData(BaseModel):
Empty: str
@app.post("/predict")
async def predict(data: InputData | list[InputData]):
try:
if isinstance(data, InputData):
data = [data]
df = pd.DataFrame([p.model_dump() for p in data])
y_pred = np.random.rand(len(df)).tolist()
return {"predictions": y_pred}
except Exception as e:
raise HTTPException(status_code=400, detail=f"Error: {e}")
@app.post("/test")
async def test(data: EmptyData | list[EmptyData]):
try:
return {"test answer": "hello world"}
except Exception as e:
raise HTTPException(status_code=400, detail=f"Error: {e}")
pyproject.toml
[project]
name = "shell-api"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"fastapi[standard]>=0.116.1",
"pandas>=2.3.1",
"pydantic>=2.10.6",
"scikit-learn>=1.7.1",
]
grace.sh
uv sync
uv run fastapi run app.py --port 8000
Notes
- The service must listen on port 8000.
- Logs are available for debugging if deployment fails.
- You can install additional Python packages via
pyproject.tomland system packages viagrace.apt.