Skip to content

Commit

Permalink
feat(deploy): test deployment to kubernetes azure
Browse files Browse the repository at this point in the history
  • Loading branch information
guillaume-chervet committed Oct 30, 2024
1 parent 4b278a9 commit ad0bdf0
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 40 deletions.
2 changes: 1 addition & 1 deletion deploy/kubernetes/redis-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
SlimFaas/NumberParallelRequest: "1"
spec:
containers:
- name: redis-container
- name: redis
image: redis:latest
ports:
- containerPort: 6379
Expand Down
19 changes: 11 additions & 8 deletions production/api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN echo "deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm main" > /etc
apt-get install -y llvm

# Installer ffmpeg
RUN apt-get install -y --no-install-recommends ffmpeg
#RUN apt-get install -y --no-install-recommends ffmpeg

# Installer Poetry
RUN pip install poetry
Expand All @@ -33,8 +33,8 @@ COPY . /app
RUN poetry config virtualenvs.create false && poetry install --no-root --only main

# Stocker les chemins des binaires dans des fichiers temporaires
RUN which llvm-config > /llvm_path && \
which ffmpeg > /ffmpeg_path
RUN which llvm-config > /llvm_path #&& \
# which ffmpeg > /ffmpeg_path

# Deuxième étape : Construire l'image finale allégée
FROM python:3.11-slim
Expand All @@ -46,19 +46,22 @@ RUN useradd -ms /bin/bash appuser
COPY --from=build /llvm_path /ffmpeg_path /tmp/

# Charger les chemins des binaires depuis les fichiers temporaires en utilisant RUN pour définir les variables d’environnement
RUN export LLVM_PATH=$(cat /tmp/llvm_path) && \
export FFMPEG_PATH=$(cat /tmp/ffmpeg_path)
RUN export LLVM_PATH=$(cat /tmp/llvm_path) #&& \
# export FFMPEG_PATH=$(cat /tmp/ffmpeg_path)

COPY $LLVM_PATH /usr/local/bin/llvm-config
COPY $FFMPEG_PATH /usr/local/bin/ffmpeg
#COPY $FFMPEG_PATH /usr/local/bin/ffmpeg

# Install ffmpeg
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg

# Copier les packages Python installés
COPY --from=build /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

# Donner les permissions appropriées pour l'utilisateur non-root
RUN chown -R appuser:appuser /usr/local/lib/python3.11/site-packages /usr/local/bin
RUN chown root:root /usr/local/bin/ffmpeg && chmod +x /usr/local/bin/ffmpeg
RUN chown root:root /usr/local/bin/llvm-config && chmod +x /usr/local/bin/llvm-config
#RUN chown root:root /usr/local/bin/ffmpeg && chmod +x /usr/local/bin/ffmpeg
#RUN chown root:root /usr/local/bin/llvm-config && chmod +x /usr/local/bin/llvm-config

# Définir le dossier de travail
WORKDIR /app
Expand Down
19 changes: 11 additions & 8 deletions production/ia-worker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN echo "deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm main" > /etc
apt-get install -y llvm

# Installer ffmpeg
RUN apt-get install -y --no-install-recommends ffmpeg
#RUN apt-get install -y --no-install-recommends ffmpeg

# Installer Poetry
RUN pip install poetry
Expand All @@ -33,8 +33,8 @@ COPY . /app
RUN poetry config virtualenvs.create false && poetry install --no-root --only main

# Stocker les chemins des binaires dans des fichiers temporaires
RUN which llvm-config > /llvm_path && \
which ffmpeg > /ffmpeg_path
RUN which llvm-config > /llvm_path #&& \
# which ffmpeg > /ffmpeg_path

# Deuxième étape : Construire l'image finale allégée
FROM python:3.11-slim
Expand All @@ -46,19 +46,22 @@ RUN useradd -ms /bin/bash appuser
COPY --from=build /llvm_path /ffmpeg_path /tmp/

# Charger les chemins des binaires depuis les fichiers temporaires en utilisant RUN pour définir les variables d’environnement
RUN export LLVM_PATH=$(cat /tmp/llvm_path) && \
export FFMPEG_PATH=$(cat /tmp/ffmpeg_path)
RUN export LLVM_PATH=$(cat /tmp/llvm_path) #&& \
# export FFMPEG_PATH=$(cat /tmp/ffmpeg_path)

COPY $LLVM_PATH /usr/local/bin/llvm-config
COPY $FFMPEG_PATH /usr/local/bin/ffmpeg
#COPY $FFMPEG_PATH /usr/local/bin/ffmpeg

# Install ffmpeg
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg

# Copier les packages Python installés
COPY --from=build /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

# Donner les permissions appropriées pour l'utilisateur non-root
RUN chown -R appuser:appuser /usr/local/lib/python3.11/site-packages /usr/local/bin
RUN chown root:root /usr/local/bin/ffmpeg && chmod +x /usr/local/bin/ffmpeg
RUN chown root:root /usr/local/bin/llvm-config && chmod +x /usr/local/bin/llvm-config
#RUN chown root:root /usr/local/bin/ffmpeg && chmod +x /usr/local/bin/ffmpeg
#RUN chown root:root /usr/local/bin/llvm-config && chmod +x /usr/local/bin/llvm-config

# Définir le dossier de travail
WORKDIR /app
Expand Down
11 changes: 8 additions & 3 deletions production/webapp/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import './App.css'
import AudioRecorderComponent from "./AudioRecorderComponent.jsx";
import EnvironmentStarter from "./EnvironmentStarter.jsx";


function App() {

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
return (
<div className="App">
<AudioRecorderComponent />
</div>
<EnvironmentStarter>
<div className="App">
<AudioRecorderComponent/>
</div>
</EnvironmentStarter>
);
} else {
console.error("L'API mediaDevices n'est pas supportée par ce navigateur.");
Expand Down
32 changes: 12 additions & 20 deletions production/webapp/src/AudioRecorderComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React, { useEffect, useRef, useState } from 'react';
import AudioRecorder from './AudioRecorder.js'; // Ajustez le chemin si nécessaire
import React, {useContext, useEffect, useRef, useState} from 'react';
import AudioRecorder from './AudioRecorder.js';
import BaseUrlContext from "./BaseUrlContext.js"; // Ajustez le chemin si nécessaire

function generateColor(index) {
return `hsl(${Math.sin(index) * 360}, 100%, 50%)`;
}

const sendAudioChunk= (serverUrl) => (chunk, clientId, chunkIndex) => {
const sendAudioChunk= (baseUrl) => (chunk, clientId, chunkIndex) => {
const formData = new FormData();
formData.append('audio_chunk', chunk);
formData.append('chunk_index', chunkIndex);
formData.append('client_id', clientId);

fetch(`${serverUrl}/audio`, {
fetch(`${baseUrl}/audio`, {
method: 'POST',
body: formData,
})
Expand All @@ -25,17 +26,19 @@ const sendAudioChunk= (serverUrl) => (chunk, clientId, chunkIndex) => {
});
}

const AudioRecorderComponent = () => {
const AudioRecorderComponent = ({}) => {
const [status, setStatus] = useState('En attente de la parole...');
const [isRecording, setIsRecording] = useState(false);
const [error, setError] = useState(null);
const [transcripts, setTranscripts] = useState([]);
const [chunkIndex, setChunkIndex] = useState(0);
const [serverUrl, setServerUrl] = useState('http://localhost:8000');
const recorderRef = useRef(null);
const eventSourceRef = useRef(null);
const baseUrl = useContext(BaseUrlContext);

useEffect(() => {
console.log('Initialisation de l\'enregistreur audio');
console.log('URL de base :', baseUrl);
// Nettoyage des ressources précédentes
if (recorderRef.current) {
if (recorderRef.current.isRecording) {
Expand All @@ -53,7 +56,7 @@ const AudioRecorderComponent = () => {
}

const clientId = Math.random().toString(36).substring(7);
const eventSource = new EventSource(`${serverUrl}/stream?client_id=${clientId}`);
const eventSource = new EventSource(`${baseUrl}/stream?client_id=${clientId}`);
eventSourceRef.current = eventSource;

eventSource.onmessage = (event) => {
Expand Down Expand Up @@ -101,7 +104,7 @@ const AudioRecorderComponent = () => {
},
onDataAvailable: (data) => {
console.log('Enregistrement de données audio (callback)');
sendAudioChunk(serverUrl)(data, clientId, closureChunkIndex);
sendAudioChunk(baseUrl)(data, clientId, closureChunkIndex);
setChunkIndex((prevIndex) =>{
closureChunkIndex++;
return prevIndex + 1;
Expand Down Expand Up @@ -129,22 +132,11 @@ const AudioRecorderComponent = () => {
eventSourceRef.current = null;
}
};
}, [serverUrl]);
}, [baseUrl]);

return (
<div>
<h1>Enregistreur Audio avec Transcription en Temps Réel</h1>
<div>
<label>
URL de base de l'API :
<input
type="text"
value={serverUrl}
onChange={(e) => setServerUrl(e.target.value)}
placeholder="http://localhost:8000"
/>
</label>
</div>
{error ? (
<p style={{ color: 'red' }}>{error}</p>
) : (
Expand Down
5 changes: 5 additions & 0 deletions production/webapp/src/BaseUrlContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

const BaseUrlContext = React.createContext(null);

export default BaseUrlContext;
97 changes: 97 additions & 0 deletions production/webapp/src/EnvironmentStarter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, { useState, useEffect } from 'react';
import BaseUrlContext from './BaseUrlContext';

const EnvironmentStarter = ({ children }) => {
const [baseUrl, setBaseUrl] = useState('');
const [statusData, setStatusData] = useState(null);

useEffect(() => {
let intervalId;

if (baseUrl) {
let tempBaseUrl = baseUrl;
if(baseUrl.endsWith('/')) {
tempBaseUrl = baseUrl.slice(0, -1);
}
if(baseUrl.endsWith('/function/api')) {
tempBaseUrl = tempBaseUrl.replace('/function/api', '');
}
console.log('tempBaseUrl:', tempBaseUrl);
const fetchData = async () => {
try {
const response = await fetch(`${tempBaseUrl}/status-functions`);
const data = await response.json();
setStatusData(data);

// Pour chaque élément, si NumberReady est 0, appeler /wake-function/<Name>
data.forEach(async (item) => {
if (item.NumberReady === 0) {
await fetch(`${tempBaseUrl}/wake-function/${item.Name}`, {
method: 'POST',
});
}
});
} catch (error) {
console.error('Erreur lors de la récupération des données:', error);
}
};

// Appel initial
fetchData();

// Mise en place de l'intervalle toutes les 5 secondes
intervalId = setInterval(fetchData, 5000);

// Nettoyage de l'intervalle lors du démontage ou du changement de baseUrl
return () => clearInterval(intervalId);
}

// Nettoyage si baseUrl est vide
return () => {
if (intervalId) clearInterval(intervalId);
};
}, [baseUrl]);

if (!baseUrl) {
return (
<div>
<input
type="text"
placeholder="Entrez la baseUrl"
value={baseUrl}
onChange={(e) => setBaseUrl(e.target.value)}
/>
</div>
);
}

if (!statusData) {
return <div>Chargement des données...</div>;
}

const allReady = statusData.every((item) => item.NumberReady >= 1);

if (allReady) {
console.log('Tous les pods sont prêts');
console.log('baseUrl:', baseUrl);
return (
<BaseUrlContext.Provider value={baseUrl}>
{children}
</BaseUrlContext.Provider>
);
} else {
const startingPods = statusData
.filter((item) => item.NumberReady === 0)
.map((item) => item.Name)
.join(', ');

return (
<div>
<p>Démarrage de l'environnement en cours...</p>
<p>Pods en cours de démarrage : {startingPods}</p>
</div>
);
}
};

export default EnvironmentStarter;

0 comments on commit ad0bdf0

Please sign in to comment.