add optinal apps
This commit is contained in:
@@ -622,6 +622,16 @@ export class BuildService {
|
||||
return this.laravelDockerfile(app);
|
||||
case AppRuntime.WORDPRESS:
|
||||
return this.wordpressDockerfile(app);
|
||||
case AppRuntime.GO:
|
||||
return this.goDockerfile(app);
|
||||
case AppRuntime.PHP:
|
||||
return this.phpDockerfile(app);
|
||||
case AppRuntime.PYTHON:
|
||||
return this.pythonDockerfile(app);
|
||||
case AppRuntime.DJANGO:
|
||||
return this.djangoDockerfile(app);
|
||||
case AppRuntime.DOTNET:
|
||||
return this.dotnetDockerfile(app);
|
||||
default:
|
||||
throw new Error(`Unsupported runtime: ${runtime}`);
|
||||
}
|
||||
@@ -874,6 +884,286 @@ CMD []` : `CMD ["apache2-foreground"]`}
|
||||
`;
|
||||
}
|
||||
|
||||
// ─── Go Dockerfile ─────────────────────────────────────────────────
|
||||
private goDockerfile(app: Application): string {
|
||||
const goVersion = app.runtimeVersion || '1.22';
|
||||
const port = app.port || 8080;
|
||||
return `# --- Build stage ---
|
||||
FROM golang:${goVersion}-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
# Install git for fetching dependencies
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Copy go mod files first for better caching
|
||||
COPY go.mod go.sum* ./
|
||||
RUN go mod download || true
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags="-w -s" -o main .
|
||||
|
||||
# --- Production stage ---
|
||||
FROM alpine:3.19
|
||||
WORKDIR /app
|
||||
|
||||
# Add CA certificates for HTTPS requests
|
||||
RUN apk --no-cache add ca-certificates tzdata
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001 -G appgroup
|
||||
|
||||
# Copy the binary from builder
|
||||
COPY --from=builder /app/main .
|
||||
COPY --from=builder /app/static ./static 2>/dev/null || true
|
||||
COPY --from=builder /app/templates ./templates 2>/dev/null || true
|
||||
COPY --from=builder /app/public ./public 2>/dev/null || true
|
||||
|
||||
# Create data directory for persistent storage
|
||||
RUN mkdir -p /app/data && chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
|
||||
ENV PORT=${port}
|
||||
EXPOSE ${port}
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${port}/health || exit 1
|
||||
|
||||
CMD ["./main"]
|
||||
`;
|
||||
}
|
||||
|
||||
// ─── PHP (Plain) Dockerfile ────────────────────────────────────────
|
||||
private phpDockerfile(app: Application): string {
|
||||
const phpVersion = app.phpVersion || '8.3';
|
||||
const port = app.port || 80;
|
||||
return `FROM php:${phpVersion}-fpm-alpine
|
||||
|
||||
RUN apk add --no-cache nginx supervisor curl \\
|
||||
&& docker-php-ext-install pdo pdo_mysql opcache \\
|
||||
&& docker-php-ext-install pdo_pgsql 2>/dev/null || true
|
||||
|
||||
# Install common PHP extensions
|
||||
RUN apk add --no-cache libpng-dev libjpeg-turbo-dev freetype-dev \\
|
||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \\
|
||||
&& docker-php-ext-install gd
|
||||
|
||||
WORKDIR /var/www/html
|
||||
COPY . .
|
||||
|
||||
# Generate nginx config
|
||||
RUN mkdir -p /etc/nginx/http.d && \\
|
||||
echo 'server {' > /etc/nginx/http.d/default.conf && \\
|
||||
echo ' listen ${port};' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' root /var/www/html;' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' index index.php index.html;' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' client_max_body_size 64M;' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' location / { try_files \\$uri \\$uri/ /index.php?\\$query_string; }' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' location ~ \\.php\\$ {' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' fastcgi_pass 127.0.0.1:9000;' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' fastcgi_param SCRIPT_FILENAME \\$document_root\\$fastcgi_script_name;' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' include fastcgi_params;' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' }' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo ' location ~ /\\.ht { deny all; }' >> /etc/nginx/http.d/default.conf && \\
|
||||
echo '}' >> /etc/nginx/http.d/default.conf
|
||||
|
||||
# Generate supervisord config
|
||||
RUN echo '[supervisord]' > /etc/supervisord.conf && \\
|
||||
echo 'nodaemon=true' >> /etc/supervisord.conf && \\
|
||||
echo 'logfile=/dev/stdout' >> /etc/supervisord.conf && \\
|
||||
echo 'logfile_maxbytes=0' >> /etc/supervisord.conf && \\
|
||||
echo '[program:php-fpm]' >> /etc/supervisord.conf && \\
|
||||
echo 'command=php-fpm -F' >> /etc/supervisord.conf && \\
|
||||
echo 'autostart=true' >> /etc/supervisord.conf && \\
|
||||
echo 'autorestart=true' >> /etc/supervisord.conf && \\
|
||||
echo 'stdout_logfile=/dev/stdout' >> /etc/supervisord.conf && \\
|
||||
echo 'stdout_logfile_maxbytes=0' >> /etc/supervisord.conf && \\
|
||||
echo 'stderr_logfile=/dev/stderr' >> /etc/supervisord.conf && \\
|
||||
echo 'stderr_logfile_maxbytes=0' >> /etc/supervisord.conf && \\
|
||||
echo '[program:nginx]' >> /etc/supervisord.conf && \\
|
||||
echo 'command=nginx -g "daemon off;"' >> /etc/supervisord.conf && \\
|
||||
echo 'autostart=true' >> /etc/supervisord.conf && \\
|
||||
echo 'autorestart=true' >> /etc/supervisord.conf && \\
|
||||
echo 'stdout_logfile=/dev/stdout' >> /etc/supervisord.conf && \\
|
||||
echo 'stdout_logfile_maxbytes=0' >> /etc/supervisord.conf && \\
|
||||
echo 'stderr_logfile=/dev/stderr' >> /etc/supervisord.conf && \\
|
||||
echo 'stderr_logfile_maxbytes=0' >> /etc/supervisord.conf
|
||||
|
||||
# Use custom configs if provided
|
||||
RUN [ -f docker/nginx.conf ] && cp docker/nginx.conf /etc/nginx/http.d/default.conf || true
|
||||
RUN [ -f docker/supervisord.conf ] && cp docker/supervisord.conf /etc/supervisord.conf || true
|
||||
|
||||
# Create upload and data directories
|
||||
RUN mkdir -p /var/www/html/uploads /var/www/html/data \\
|
||||
&& chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE ${port}
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
|
||||
`;
|
||||
}
|
||||
|
||||
// ─── Python Dockerfile ─────────────────────────────────────────────
|
||||
private pythonDockerfile(app: Application): string {
|
||||
const pythonVersion = app.runtimeVersion || '3.12';
|
||||
const port = app.port || 8000;
|
||||
return `# --- Build stage ---
|
||||
FROM python:${pythonVersion}-slim AS builder
|
||||
WORKDIR /app
|
||||
|
||||
# Install build dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \\
|
||||
build-essential libpq-dev \\
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy requirements and install dependencies
|
||||
COPY requirements.txt* ./
|
||||
RUN pip install --no-cache-dir --user -r requirements.txt 2>/dev/null || \\
|
||||
pip install --no-cache-dir --user flask gunicorn
|
||||
|
||||
# --- Production stage ---
|
||||
FROM python:${pythonVersion}-slim
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \\
|
||||
libpq5 curl \\
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create non-root user
|
||||
RUN groupadd -g 1001 appgroup && useradd -r -u 1001 -g appgroup appuser
|
||||
|
||||
# Copy installed packages from builder
|
||||
COPY --from=builder /root/.local /home/appuser/.local
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create data directory
|
||||
RUN mkdir -p /app/data && chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
ENV PATH=/home/appuser/.local/bin:$PATH
|
||||
ENV PORT=${port}
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
EXPOSE ${port}
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
||||
CMD curl -f http://localhost:${port}/health || exit 1
|
||||
|
||||
# Auto-detect: Flask, FastAPI, or plain Python
|
||||
CMD ["sh", "-c", "if [ -f main.py ]; then if grep -q 'FastAPI\\|fastapi' main.py; then uvicorn main:app --host 0.0.0.0 --port ${port}; elif grep -q 'Flask\\|flask' main.py; then gunicorn -w 4 -b 0.0.0.0:${port} main:app; else python main.py; fi; elif [ -f app.py ]; then if grep -q 'FastAPI\\|fastapi' app.py; then uvicorn app:app --host 0.0.0.0 --port ${port}; elif grep -q 'Flask\\|flask' app.py; then gunicorn -w 4 -b 0.0.0.0:${port} app:app; else python app.py; fi; else gunicorn -w 4 -b 0.0.0.0:${port} app:app; fi"]
|
||||
`;
|
||||
}
|
||||
|
||||
// ─── Django Dockerfile ─────────────────────────────────────────────
|
||||
private djangoDockerfile(app: Application): string {
|
||||
const pythonVersion = app.runtimeVersion || '3.12';
|
||||
const port = app.port || 8000;
|
||||
return `# --- Build stage ---
|
||||
FROM python:${pythonVersion}-slim AS builder
|
||||
WORKDIR /app
|
||||
|
||||
# Install build dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \\
|
||||
build-essential libpq-dev \\
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy requirements and install dependencies
|
||||
COPY requirements.txt* ./
|
||||
RUN pip install --no-cache-dir --user -r requirements.txt 2>/dev/null || \\
|
||||
pip install --no-cache-dir --user django gunicorn psycopg2-binary mysqlclient
|
||||
|
||||
# --- Production stage ---
|
||||
FROM python:${pythonVersion}-slim
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \\
|
||||
libpq5 default-libmysqlclient-dev curl \\
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create non-root user
|
||||
RUN groupadd -g 1001 appgroup && useradd -r -u 1001 -g appgroup appuser
|
||||
|
||||
# Copy installed packages from builder
|
||||
COPY --from=builder /root/.local /home/appuser/.local
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create directories for static files and media
|
||||
RUN mkdir -p /app/staticfiles /app/media /app/data \\
|
||||
&& chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
ENV PATH=/home/appuser/.local/bin:$PATH
|
||||
ENV PORT=${port}
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV DJANGO_SETTINGS_MODULE=config.settings
|
||||
|
||||
EXPOSE ${port}
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \\
|
||||
CMD curl -f http://localhost:${port}/health/ || curl -f http://localhost:${port}/ || exit 1
|
||||
|
||||
# Auto-detect project structure and run migrations + collectstatic
|
||||
CMD ["sh", "-c", "\\
|
||||
PROJECT_NAME=$(find . -maxdepth 2 -name 'wsgi.py' | head -1 | cut -d'/' -f2) && \\
|
||||
if [ -z \\\"$PROJECT_NAME\\\" ]; then PROJECT_NAME='config'; fi && \\
|
||||
echo \\\"Django project: $PROJECT_NAME\\\" && \\
|
||||
python manage.py migrate --noinput 2>/dev/null || true && \\
|
||||
python manage.py collectstatic --noinput 2>/dev/null || true && \\
|
||||
gunicorn $PROJECT_NAME.wsgi:application --bind 0.0.0.0:${port} --workers 4 --threads 2 \\
|
||||
"]
|
||||
`;
|
||||
}
|
||||
|
||||
// ─── .NET Dockerfile ───────────────────────────────────────────────
|
||||
private dotnetDockerfile(app: Application): string {
|
||||
const dotnetVersion = app.runtimeVersion || '8.0';
|
||||
const port = app.port || 5000;
|
||||
return `# --- Build stage ---
|
||||
FROM mcr.microsoft.com/dotnet/sdk:${dotnetVersion} AS build
|
||||
WORKDIR /src
|
||||
|
||||
# Copy csproj and restore dependencies
|
||||
COPY *.csproj ./
|
||||
RUN dotnet restore || true
|
||||
|
||||
# Copy everything else and build
|
||||
COPY . .
|
||||
RUN dotnet publish -c Release -o /app/publish --no-restore 2>/dev/null || \\
|
||||
dotnet publish -c Release -o /app/publish
|
||||
|
||||
# --- Production stage ---
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:${dotnetVersion}
|
||||
WORKDIR /app
|
||||
|
||||
# Create non-root user
|
||||
RUN groupadd -g 1001 appgroup && useradd -r -u 1001 -g appgroup appuser
|
||||
|
||||
# Copy published app
|
||||
COPY --from=build /app/publish .
|
||||
|
||||
# Create data directory
|
||||
RUN mkdir -p /app/data && chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
|
||||
ENV ASPNETCORE_URLS=http://+:${port}
|
||||
ENV DOTNET_RUNNING_IN_CONTAINER=true
|
||||
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||
|
||||
EXPOSE ${port}
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \\
|
||||
CMD curl -f http://localhost:${port}/health || curl -f http://localhost:${port}/ || exit 1
|
||||
|
||||
# Auto-detect entry point DLL
|
||||
CMD ["sh", "-c", "DLL=$(find . -maxdepth 1 -name '*.dll' ! -name '*.deps.dll' ! -name '*.runtimeconfig.dll' | head -1) && dotnet $DLL"]
|
||||
`;
|
||||
}
|
||||
|
||||
private async waitForJobCompletion(
|
||||
batchApi: k8s.BatchV1Api,
|
||||
coreApi: k8s.CoreV1Api,
|
||||
|
||||
Reference in New Issue
Block a user