Dockercommit
This commit is contained in:
26
Dockerfile
26
Dockerfile
@ -1,24 +1,18 @@
|
|||||||
# syntax=docker/dockerfile:1.4
|
# syntax=docker/dockerfile:1.4
|
||||||
|
|
||||||
# Build stage
|
# Build stage
|
||||||
FROM node:lts AS build
|
FROM node:18-alpine AS build
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Set environment variables to help with sharp installation
|
# Install build dependencies
|
||||||
ENV SHARP_IGNORE_GLOBAL_LIBVIPS=1
|
RUN apk add --no-cache python3 make g++
|
||||||
ENV npm_config_sharp_binary_host="https://npmjs.org/mirrors/sharp"
|
|
||||||
ENV npm_config_sharp_libvips_binary_host="https://npmjs.org/mirrors/sharp-libvips"
|
|
||||||
|
|
||||||
# Copy package files
|
# Copy package files
|
||||||
COPY package.json package-lock.json ./
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
# Install dependencies with legacy peer deps and increased timeout
|
# Install dependencies
|
||||||
# Use --no-optional to skip optional dependencies that might cause issues
|
RUN npm install --legacy-peer-deps
|
||||||
RUN npm config set fetch-timeout 600000 && \
|
|
||||||
npm config set fetch-retry-mintimeout 10000 && \
|
|
||||||
npm config set fetch-retry-maxtimeout 60000 && \
|
|
||||||
npm install --legacy-peer-deps --no-optional --verbose
|
|
||||||
|
|
||||||
# Copy source code
|
# Copy source code
|
||||||
COPY . .
|
COPY . .
|
||||||
@ -26,17 +20,15 @@ COPY . .
|
|||||||
# Build the Gatsby app
|
# Build the Gatsby app
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Production stage with Nginx
|
# Production stage
|
||||||
FROM nginx:alpine AS production
|
FROM nginx:alpine AS production
|
||||||
|
|
||||||
# Create simple nginx config for Gatsby with client-side routing support
|
# Copy nginx config
|
||||||
RUN echo 'server { listen 80; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } }' > /etc/nginx/conf.d/default.conf
|
RUN echo 'server { listen 80; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } }' > /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
# Copy built Gatsby files (builds to 'public' directory)
|
# Copy built files
|
||||||
COPY --from=build /app/public /usr/share/nginx/html
|
COPY --from=build /app/public /usr/share/nginx/html
|
||||||
|
|
||||||
# Expose port 80
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
# Start nginx
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
@ -9,14 +9,14 @@ const Details = ({ service }) => {
|
|||||||
<div className="col-lg-8">
|
<div className="col-lg-8">
|
||||||
<div className="main-info">
|
<div className="main-info">
|
||||||
<div className="main-img img-cover">
|
<div className="main-img img-cover">
|
||||||
<img src={service.image} alt={service.title} />
|
<img src={service?.image || service?.icon || '/assets/img/default-image.jpg'} alt={service?.title || 'Service'} />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-capitalize mb-20">Service Overview</h3>
|
<h3 className="text-capitalize mb-20">Service Overview</h3>
|
||||||
<p className="mb-10">
|
<p className="mb-10">
|
||||||
{service.overview}
|
{service?.overview || 'No overview available'}
|
||||||
</p>
|
</p>
|
||||||
<div className="imgs-items border-1 border-bottom border-top brd-gray">
|
<div className="imgs-items border-1 border-bottom border-top brd-gray">
|
||||||
{service.processes.map((process, index) => (
|
{(service?.processes || []).map((process, index) => (
|
||||||
<div className="img-item my-5" key={index}>
|
<div className="img-item my-5" key={index}>
|
||||||
<div className="row align-items-center">
|
<div className="row align-items-center">
|
||||||
<div className="col-lg-2">
|
<div className="col-lg-2">
|
||||||
@ -30,22 +30,21 @@ const Details = ({ service }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
)) || <p>No processes available</p>}
|
||||||
</div>
|
</div>
|
||||||
<h4 className="mt-5 mb-4">Key Features</h4>
|
<h4 className="mt-5 mb-4">Key Features</h4>
|
||||||
{service.features.map((feature, index) => (
|
{(service?.features || []).map((feature, index) => (
|
||||||
<p className="mt-10" key={index}>
|
<p className="mt-10" key={index}>
|
||||||
<i className="fas fa-check-circle color-blue5 me-2"></i>
|
<i className="fas fa-check-circle color-blue5 me-2"></i>
|
||||||
<strong className="color-000">{feature.name}:</strong> {feature.description}
|
<strong className="color-000">{feature.name}:</strong> {feature.description}
|
||||||
</p>
|
</p>
|
||||||
))}
|
)) || <p>No features available</p>}
|
||||||
|
|
||||||
<div className="testi-card mt-60">
|
<div className="testi-card mt-60">
|
||||||
<div className="icon">
|
<div className="icon">
|
||||||
<img src="/assets/img/testimonials/qout.png" alt="" />
|
<img src="/assets/img/testimonials/qout.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<div className="text">
|
<div className="text">
|
||||||
"RootXwire's {service.title.toLowerCase()} service has transformed our infrastructure, providing reliable and scalable solutions for our business needs."
|
"RootXwire's {service?.title?.toLowerCase() || 'service'} has transformed our infrastructure, providing reliable and scalable solutions for our business needs."
|
||||||
</div>
|
</div>
|
||||||
<div className="author">
|
<div className="author">
|
||||||
<div className="img icon-60 rounded-circle overflow-hidden img-cover me-3 flex-shrink-0">
|
<div className="img icon-60 rounded-circle overflow-hidden img-cover me-3 flex-shrink-0">
|
||||||
@ -57,7 +56,6 @@ const Details = ({ service }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="last-next-serv d-flex align-items-center justify-content-between mt-60">
|
<div className="last-next-serv d-flex align-items-center justify-content-between mt-60">
|
||||||
<a href="/services/details?service=storage" className="item">
|
<a href="/services/details?service=storage" className="item">
|
||||||
<p>Previous Service</p>
|
<p>Previous Service</p>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"icon": "/assets/img/icons/serv_icons/cloud.png",
|
"icon": "/assets/img/icons/serv_icons/5.png",
|
||||||
"title": "Cloud Computing",
|
"title": "Cloud Computing",
|
||||||
"details": "Scalable cloud solutions including compute, storage, and networking services for your business needs.",
|
"details": "Scalable cloud solutions including compute, storage, and networking services for your business needs.",
|
||||||
"link": "/services/details?service=cloud",
|
"link": "/services/details?service=cloud",
|
||||||
@ -28,7 +28,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "/assets/img/icons/serv_icons/app.png",
|
"icon": "/assets/img/icons/serv_icons/8.png",
|
||||||
"title": "Application Development",
|
"title": "Application Development",
|
||||||
"details": "Comprehensive development services for web, mobile (Android/iOS), and IoT applications.",
|
"details": "Comprehensive development services for web, mobile (Android/iOS), and IoT applications.",
|
||||||
"link": "/services/details?service=app-dev",
|
"link": "/services/details?service=app-dev",
|
||||||
@ -56,7 +56,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "/assets/img/icons/serv_icons/ai.png",
|
"icon": "/assets/img/icons/serv_icons/1.png",
|
||||||
"title": "AI & Machine Learning",
|
"title": "AI & Machine Learning",
|
||||||
"details": "Advanced AI solutions including machine learning, computer vision, and natural language processing.",
|
"details": "Advanced AI solutions including machine learning, computer vision, and natural language processing.",
|
||||||
"link": "/services/details?service=ai",
|
"link": "/services/details?service=ai",
|
||||||
|
|||||||
@ -13,6 +13,19 @@ import Footer from 'components/Saas/Footer';
|
|||||||
|
|
||||||
const PageServiceDetails = () => {
|
const PageServiceDetails = () => {
|
||||||
const navbarRef = useRef(null);
|
const navbarRef = useRef(null);
|
||||||
|
const service = {
|
||||||
|
title: "Email Marketing",
|
||||||
|
image: "/assets/img/service-email.jpg",
|
||||||
|
overview: "Targeted email campaigns and automation solutions for effective customer engagement.",
|
||||||
|
processes: [
|
||||||
|
{ icon: "/assets/img/icons/serv_icons/34.png", title: "Campaign Setup", description: "Custom email campaign creation and design." },
|
||||||
|
{ icon: "/assets/img/icons/serv_icons/35.png", title: "Automation", description: "Automated email workflows for efficiency." }
|
||||||
|
],
|
||||||
|
features: [
|
||||||
|
{ name: "Campaign Analytics", description: "Track and analyze email performance metrics." },
|
||||||
|
{ name: "Automation Tools", description: "Streamline email marketing workflows." }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navbarScrollEffect(navbarRef.current, true);
|
navbarScrollEffect(navbarRef.current, true);
|
||||||
@ -22,24 +35,24 @@ const PageServiceDetails = () => {
|
|||||||
<MainLayout>
|
<MainLayout>
|
||||||
<TopNav style="5" />
|
<TopNav style="5" />
|
||||||
<Navbar navbarRef={navbarRef} />
|
<Navbar navbarRef={navbarRef} />
|
||||||
<Header page="Service Details" title="Email Marketing" />
|
<Header page="Service Details" title={service.title} />
|
||||||
<main className="services-details-page style-5">
|
<main className="services-details-page style-5">
|
||||||
<Details />
|
<Details service={service} />
|
||||||
<Contact />
|
<Contact />
|
||||||
</main>
|
</main>
|
||||||
<Footer noWave />
|
<Footer noWave />
|
||||||
</MainLayout>
|
</MainLayout>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const Head = () => {
|
export const Head = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<title>Rootxwire - Service Details</title>
|
<title>Rootxwire - Service Details</title>
|
||||||
<link rel="stylesheet" href="/assets/css/lib/bootstrap.min.css" />
|
<link rel="stylesheet" href="/assets/css/lib/bootstrap.min.css" />
|
||||||
<link rel="stylesheet" href="/assets/css/style.css" />
|
<link rel="stylesheet" href="/assets/css/style.css" />
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default PageServiceDetails;
|
export default PageServiceDetails;
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 2.2 KiB |
BIN
static/assets/img/icons/serv_icons/ai.png
Normal file
BIN
static/assets/img/icons/serv_icons/ai.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 MiB |
BIN
static/assets/img/icons/serv_icons/app.png
Normal file
BIN
static/assets/img/icons/serv_icons/app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
static/assets/img/icons/serv_icons/cloud.png
Normal file
BIN
static/assets/img/icons/serv_icons/cloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
static/assets/img/service-email.jpg
Normal file
BIN
static/assets/img/service-email.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
Reference in New Issue
Block a user