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()
|
||||
|
||||
// Get the technology data (handle both string and object)
|
||||
const techData = computed(() => {
|
||||
const techData = computed((): Technology => {
|
||||
if (typeof props.tech === 'string') {
|
||||
const techName = props.tech as string
|
||||
|
||||
// Create a mapping for technologies that don't match exactly
|
||||
const techMapping: Record<string, string> = {
|
||||
'Three.js': 'JavaScript',
|
||||
@@ -36,13 +38,14 @@ const techData = computed(() => {
|
||||
// Try to find the exact match first
|
||||
let foundTech = Object.values(techStack)
|
||||
.flat()
|
||||
.find(t => t.name.toLowerCase() === props.tech.toLowerCase())
|
||||
.find(t => t.name.toLowerCase() === techName.toLowerCase())
|
||||
|
||||
// If not found, try the mapping
|
||||
if (!foundTech && techMapping[props.tech]) {
|
||||
if (!foundTech && techMapping[techName]) {
|
||||
const mappedName = techMapping[techName]
|
||||
foundTech = Object.values(techStack)
|
||||
.flat()
|
||||
.find(t => t.name.toLowerCase() === techMapping[props.tech].toLowerCase())
|
||||
.find(t => t.name.toLowerCase() === mappedName.toLowerCase())
|
||||
}
|
||||
|
||||
if (foundTech) {
|
||||
@@ -51,13 +54,13 @@ const techData = computed(() => {
|
||||
|
||||
// Fallback: create a basic tech object from string
|
||||
return {
|
||||
name: props.tech,
|
||||
name: techName,
|
||||
image: '', // No image for unknown techs
|
||||
level: 'Intermediate' as const
|
||||
}
|
||||
}
|
||||
|
||||
return props.tech
|
||||
return props.tech as Technology
|
||||
})
|
||||
|
||||
// Get the actual image URL
|
||||
@@ -66,7 +69,7 @@ const imageUrl = computed(() => {
|
||||
return getImageUrl(techData.value.image)
|
||||
})
|
||||
|
||||
const getLevelColor = (level: string) => {
|
||||
const getLevelColor = (level: Technology['level']) => {
|
||||
switch (level) {
|
||||
case 'Advanced':
|
||||
return 'badge-success'
|
||||
|
Reference in New Issue
Block a user