feat(docker): ajout de la configuration Docker pour l'application Vue.js
- Création d'un Dockerfile pour construire et servir l'application avec Nginx - Ajout d'un fichier de configuration Nginx pour gérer les requêtes et les erreurs - Mise à jour du composant TechBadge pour améliorer la gestion des données technologiques
This commit is contained in:
32
Dockerfile
Normal file
32
Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Stage 1: Build the Vue.js application
|
||||||
|
FROM node:22-alpine AS build-stage
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json (or yarn.lock)
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Copy the rest of your application's source code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
# The command is taken from your "scripts" in package.json
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 2: Serve the application with a lightweight web server
|
||||||
|
FROM nginx:stable-alpine AS production-stage
|
||||||
|
|
||||||
|
# Copy the built files from the build stage
|
||||||
|
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy the nginx configuration file
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Expose port 80 to the outside world
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Command to run nginx in the foreground
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
18
nginx.conf
Normal file
18
nginx.conf
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: Add error pages
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
@@ -18,8 +18,10 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
const { getImageUrl } = useAssets()
|
const { getImageUrl } = useAssets()
|
||||||
|
|
||||||
// Get the technology data (handle both string and object)
|
// Get the technology data (handle both string and object)
|
||||||
const techData = computed(() => {
|
const techData = computed((): Technology => {
|
||||||
if (typeof props.tech === 'string') {
|
if (typeof props.tech === 'string') {
|
||||||
|
const techName = props.tech as string
|
||||||
|
|
||||||
// Create a mapping for technologies that don't match exactly
|
// Create a mapping for technologies that don't match exactly
|
||||||
const techMapping: Record<string, string> = {
|
const techMapping: Record<string, string> = {
|
||||||
'Three.js': 'JavaScript',
|
'Three.js': 'JavaScript',
|
||||||
@@ -36,13 +38,14 @@ const techData = computed(() => {
|
|||||||
// Try to find the exact match first
|
// Try to find the exact match first
|
||||||
let foundTech = Object.values(techStack)
|
let foundTech = Object.values(techStack)
|
||||||
.flat()
|
.flat()
|
||||||
.find(t => t.name.toLowerCase() === props.tech.toLowerCase())
|
.find(t => t.name.toLowerCase() === techName.toLowerCase())
|
||||||
|
|
||||||
// If not found, try the mapping
|
// If not found, try the mapping
|
||||||
if (!foundTech && techMapping[props.tech]) {
|
if (!foundTech && techMapping[techName]) {
|
||||||
|
const mappedName = techMapping[techName]
|
||||||
foundTech = Object.values(techStack)
|
foundTech = Object.values(techStack)
|
||||||
.flat()
|
.flat()
|
||||||
.find(t => t.name.toLowerCase() === techMapping[props.tech].toLowerCase())
|
.find(t => t.name.toLowerCase() === mappedName.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundTech) {
|
if (foundTech) {
|
||||||
@@ -51,13 +54,13 @@ const techData = computed(() => {
|
|||||||
|
|
||||||
// Fallback: create a basic tech object from string
|
// Fallback: create a basic tech object from string
|
||||||
return {
|
return {
|
||||||
name: props.tech,
|
name: techName,
|
||||||
image: '', // No image for unknown techs
|
image: '', // No image for unknown techs
|
||||||
level: 'Intermediate' as const
|
level: 'Intermediate' as const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return props.tech
|
return props.tech as Technology
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get the actual image URL
|
// Get the actual image URL
|
||||||
@@ -66,7 +69,7 @@ const imageUrl = computed(() => {
|
|||||||
return getImageUrl(techData.value.image)
|
return getImageUrl(techData.value.image)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getLevelColor = (level: string) => {
|
const getLevelColor = (level: Technology['level']) => {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case 'Advanced':
|
case 'Advanced':
|
||||||
return 'badge-success'
|
return 'badge-success'
|
||||||
|
Reference in New Issue
Block a user