mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-24 06:28:34 +01:00
feat: split into separate files
This commit is contained in:
369
docs/.vitepress/components/dockerComposeGenerator.ts
Normal file
369
docs/.vitepress/components/dockerComposeGenerator.ts
Normal file
@@ -0,0 +1,369 @@
|
||||
import type { AppConfig, DockerServices } from "./types" // Assuming types are in a separate file
|
||||
|
||||
export function generateDockerCompose(config: AppConfig): string {
|
||||
const services: DockerServices = {
|
||||
homebox: {
|
||||
image: config.rootless
|
||||
? "ghcr.io/sysadminsmedia/homebox:latest-rootless"
|
||||
: "ghcr.io/sysadminsmedia/homebox:latest",
|
||||
container_name: "homebox",
|
||||
restart: "always",
|
||||
environment: [
|
||||
`HBOX_LOG_LEVEL=${config.logLevel}`,
|
||||
`HBOX_LOG_FORMAT=${config.logFormat}`,
|
||||
`HBOX_WEB_MAX_FILE_UPLOAD=${config.maxFileUpload}`,
|
||||
`HBOX_OPTIONS_ALLOW_ANALYTICS=${config.allowAnalytics}`,
|
||||
`HBOX_OPTIONS_ALLOW_REGISTRATION=${config.allowRegistration}`,
|
||||
`HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID=${config.autoIncrementAssetId}`,
|
||||
`HBOX_OPTIONS_CHECK_GITHUB_RELEASE=${config.checkGithubRelease}`,
|
||||
],
|
||||
volumes: [],
|
||||
},
|
||||
}
|
||||
|
||||
// Configure homebox volumes based on storage type
|
||||
if (config.storageConfig.homeboxStorage.type === "volume") {
|
||||
services.homebox.volumes.push(
|
||||
`${config.storageConfig.homeboxStorage.volumeName}:/data/`,
|
||||
)
|
||||
} else {
|
||||
services.homebox.volumes.push(
|
||||
`${config.storageConfig.homeboxStorage.directory}:/data/`,
|
||||
)
|
||||
}
|
||||
|
||||
// Configure ports based on HTTPS option
|
||||
if (config.httpsOption === "none") {
|
||||
services.homebox.ports = [`${config.port}:7745`]
|
||||
} else {
|
||||
// For HTTPS options, the proxy will handle the ports
|
||||
services.homebox.expose = ["7745"]
|
||||
}
|
||||
|
||||
// Add database configuration if PostgreSQL is selected
|
||||
if (config.databaseType === "postgres") {
|
||||
// Ensure environment array exists before pushing
|
||||
if (!services.homebox.environment) {
|
||||
services.homebox.environment = []
|
||||
}
|
||||
services.homebox.environment.push(
|
||||
"HBOX_DATABASE_DRIVER=postgres",
|
||||
`HBOX_DATABASE_HOST=${config.postgresConfig.host}`,
|
||||
`HBOX_DATABASE_PORT=${config.postgresConfig.port}`,
|
||||
`HBOX_DATABASE_USERNAME=${config.postgresConfig.username}`,
|
||||
`HBOX_DATABASE_PASSWORD=${config.postgresConfig.password}`,
|
||||
`HBOX_DATABASE_DATABASE=${config.postgresConfig.database}`,
|
||||
)
|
||||
|
||||
// Add PostgreSQL service
|
||||
services["postgres"] = {
|
||||
image: "postgres:14",
|
||||
container_name: "homebox-postgres",
|
||||
restart: "always",
|
||||
environment: [
|
||||
`POSTGRES_USER=${config.postgresConfig.username}`,
|
||||
`POSTGRES_PASSWORD=${config.postgresConfig.password}`,
|
||||
`POSTGRES_DB=${config.postgresConfig.database}`,
|
||||
],
|
||||
volumes: [],
|
||||
}
|
||||
|
||||
// Configure postgres volumes based on storage type
|
||||
if (config.storageConfig.postgresStorage.type === "volume") {
|
||||
services.postgres.volumes.push(
|
||||
`${config.storageConfig.postgresStorage.volumeName}:/var/lib/postgresql/data`,
|
||||
)
|
||||
} else {
|
||||
services.postgres.volumes.push(
|
||||
`${config.storageConfig.postgresStorage.directory}:/var/lib/postgresql/data`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Add HTTPS configuration based on selected option
|
||||
switch (config.httpsOption) {
|
||||
case "traefik":
|
||||
addTraefikConfig(services, config)
|
||||
break
|
||||
case "nginx":
|
||||
addNginxConfig(services, config)
|
||||
break
|
||||
case "caddy":
|
||||
addCaddyConfig(services, config)
|
||||
break
|
||||
case "cloudflared":
|
||||
addCloudflaredConfig(services, config)
|
||||
break
|
||||
}
|
||||
|
||||
// Format the Docker Compose YAML
|
||||
let dockerCompose = "# generated by homebox config generator v0.0.1\n\nservices:\n"
|
||||
|
||||
// Add services
|
||||
Object.entries(services).forEach(([serviceName, serviceConfig]) => {
|
||||
dockerCompose += ` ${serviceName}:\n`
|
||||
Object.entries(serviceConfig).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
dockerCompose += ` ${key}:\n`
|
||||
value.forEach((item: string) => {
|
||||
// Added type assertion for item
|
||||
dockerCompose += ` - ${item}\n`
|
||||
})
|
||||
} else if (value !== undefined) {
|
||||
// Check for undefined before adding
|
||||
dockerCompose += ` ${key}: ${value}\n`
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Add volumes section if needed
|
||||
const volumeNames: string[] = []
|
||||
|
||||
// Only add volumes that are configured as Docker volumes, not directories
|
||||
if (config.storageConfig.homeboxStorage.type === "volume") {
|
||||
volumeNames.push(config.storageConfig.homeboxStorage.volumeName)
|
||||
}
|
||||
|
||||
if (
|
||||
config.databaseType === "postgres" &&
|
||||
config.storageConfig.postgresStorage.type === "volume"
|
||||
) {
|
||||
volumeNames.push(config.storageConfig.postgresStorage.volumeName)
|
||||
}
|
||||
|
||||
// Add HTTPS-related volumes
|
||||
if (
|
||||
config.httpsOption === "traefik" &&
|
||||
config.storageConfig.traefikStorage.type === "volume"
|
||||
) {
|
||||
volumeNames.push(config.storageConfig.traefikStorage.volumeName)
|
||||
}
|
||||
|
||||
if (
|
||||
config.httpsOption === "nginx" &&
|
||||
config.storageConfig.nginxStorage.type === "volume"
|
||||
) {
|
||||
volumeNames.push(config.storageConfig.nginxStorage.volumeName)
|
||||
}
|
||||
|
||||
if (
|
||||
config.httpsOption === "caddy" &&
|
||||
config.storageConfig.caddyStorage.type === "volume"
|
||||
) {
|
||||
volumeNames.push(config.storageConfig.caddyStorage.volumeName)
|
||||
}
|
||||
|
||||
if (
|
||||
config.httpsOption === "cloudflared" &&
|
||||
config.storageConfig.cloudflaredStorage.type === "volume"
|
||||
) {
|
||||
volumeNames.push(config.storageConfig.cloudflaredStorage.volumeName)
|
||||
}
|
||||
|
||||
if (volumeNames.length > 0) {
|
||||
dockerCompose += "\nvolumes:\n"
|
||||
volumeNames.forEach((volumeName: string) => {
|
||||
dockerCompose += ` ${volumeName}:\n driver: local\n`
|
||||
})
|
||||
}
|
||||
|
||||
return dockerCompose
|
||||
}
|
||||
|
||||
function addTraefikConfig(services: DockerServices, config: AppConfig): void {
|
||||
// Add Traefik labels to Homebox
|
||||
services.homebox.labels = [
|
||||
"traefik.enable=true",
|
||||
`traefik.http.routers.homebox.rule=Host(\`${config.traefikConfig.domain}\`)`,
|
||||
"traefik.http.routers.homebox.entrypoints=websecure",
|
||||
"traefik.http.routers.homebox.tls.certresolver=letsencrypt",
|
||||
"traefik.http.services.homebox.loadbalancer.server.port=7745",
|
||||
]
|
||||
|
||||
// Add Traefik service
|
||||
services["traefik"] = {
|
||||
image: "traefik:v2.10",
|
||||
container_name: "homebox-traefik",
|
||||
restart: "always",
|
||||
ports: ["80:80", "443:443"],
|
||||
command: [
|
||||
"--api.insecure=false",
|
||||
"--providers.docker=true",
|
||||
"--providers.docker.exposedbydefault=false",
|
||||
"--entrypoints.web.address=:80",
|
||||
"--entrypoints.web.http.redirections.entrypoint.to=websecure",
|
||||
"--entrypoints.web.http.redirections.entrypoint.scheme=https",
|
||||
"--entrypoints.websecure.address=:443",
|
||||
"--certificatesresolvers.letsencrypt.acme.tlschallenge=true",
|
||||
`--certificatesresolvers.letsencrypt.acme.email=${config.traefikConfig.email}`,
|
||||
"--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json",
|
||||
],
|
||||
volumes: ["/var/run/docker.sock:/var/run/docker.sock:ro"],
|
||||
}
|
||||
|
||||
// Configure traefik volumes based on storage type
|
||||
if (config.storageConfig.traefikStorage.type === "volume") {
|
||||
services.traefik.volumes.push(
|
||||
`${config.storageConfig.traefikStorage.volumeName}:/letsencrypt`,
|
||||
)
|
||||
} else {
|
||||
services.traefik.volumes.push(
|
||||
`${config.storageConfig.traefikStorage.directory}:/letsencrypt`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function addNginxConfig(services: DockerServices, config: AppConfig): void {
|
||||
// Add Nginx service
|
||||
services["nginx"] = {
|
||||
image: "nginx:latest",
|
||||
container_name: "homebox-nginx",
|
||||
restart: "always",
|
||||
ports: [`${config.nginxConfig.port}:443`, "80:80"],
|
||||
volumes: [],
|
||||
depends_on: ["homebox"],
|
||||
}
|
||||
|
||||
// Configure nginx volumes based on storage type
|
||||
if (config.storageConfig.nginxStorage.type === "volume") {
|
||||
services.nginx.volumes.push(
|
||||
`${config.storageConfig.nginxStorage.volumeName}/conf.d:/etc/nginx/conf.d`,
|
||||
)
|
||||
services.nginx.volumes.push(
|
||||
`${config.storageConfig.nginxStorage.volumeName}/ssl:/etc/nginx/ssl`,
|
||||
)
|
||||
} else {
|
||||
services.nginx.volumes.push(
|
||||
`${config.storageConfig.nginxStorage.directory}/conf.d:/etc/nginx/conf.d`,
|
||||
)
|
||||
services.nginx.volumes.push(
|
||||
`${config.storageConfig.nginxStorage.directory}/ssl:/etc/nginx/ssl`,
|
||||
)
|
||||
}
|
||||
|
||||
// Add default Nginx configuration path (assuming the file exists)
|
||||
const nginxConfVolume =
|
||||
config.storageConfig.nginxStorage.type === "volume"
|
||||
? `${config.storageConfig.nginxStorage.volumeName}/conf.d/default.conf:/etc/nginx/conf.d/default.conf`
|
||||
: `${config.storageConfig.nginxStorage.directory}/conf.d/default.conf:/etc/nginx/conf.d/default.conf`
|
||||
|
||||
services.nginx.volumes.push(nginxConfVolume)
|
||||
|
||||
// Add comments via environment variables (Docker Compose doesn't support comments directly in YAML this way)
|
||||
services.nginx.environment = [
|
||||
"# You need to create SSL certificates and place them in the SSL directory",
|
||||
`# Certificate path: ${config.nginxConfig.sslCertPath}`,
|
||||
`# Key path: ${config.nginxConfig.sslKeyPath}`,
|
||||
"# Then create a default.conf file in the conf.d directory with the following content:",
|
||||
"# server {",
|
||||
"# listen 80;",
|
||||
`# server_name ${config.nginxConfig.domain};`,
|
||||
"# return 301 https://$host$request_uri;",
|
||||
"# }",
|
||||
"# server {",
|
||||
"# listen 443 ssl;",
|
||||
`# server_name ${config.nginxConfig.domain};`,
|
||||
`# ssl_certificate ${config.nginxConfig.sslCertPath};`,
|
||||
`# ssl_certificate_key ${config.nginxConfig.sslKeyPath};`,
|
||||
"# location / {",
|
||||
"# proxy_pass http://homebox:7745;",
|
||||
"# proxy_set_header Host $host;",
|
||||
"# proxy_set_header X-Real-IP $remote_addr;",
|
||||
"# }",
|
||||
"# }",
|
||||
]
|
||||
}
|
||||
|
||||
function addCaddyConfig(services: DockerServices, config: AppConfig): void {
|
||||
// Add Caddy service
|
||||
services["caddy"] = {
|
||||
image: "caddy:latest",
|
||||
container_name: "homebox-caddy",
|
||||
restart: "always",
|
||||
ports: ["80:80", "443:443"],
|
||||
volumes: [],
|
||||
depends_on: ["homebox"],
|
||||
}
|
||||
|
||||
// Configure caddy volumes based on storage type
|
||||
if (config.storageConfig.caddyStorage.type === "volume") {
|
||||
services.caddy.volumes.push(
|
||||
`${config.storageConfig.caddyStorage.volumeName}/data:/data`,
|
||||
)
|
||||
services.caddy.volumes.push(
|
||||
`${config.storageConfig.caddyStorage.volumeName}/config:/config`,
|
||||
)
|
||||
services.caddy.volumes.push(
|
||||
`${config.storageConfig.caddyStorage.volumeName}/Caddyfile:/etc/caddy/Caddyfile`,
|
||||
)
|
||||
} else {
|
||||
services.caddy.volumes.push(
|
||||
`${config.storageConfig.caddyStorage.directory}/data:/data`,
|
||||
)
|
||||
services.caddy.volumes.push(
|
||||
`${config.storageConfig.caddyStorage.directory}/config:/config`,
|
||||
)
|
||||
services.caddy.volumes.push(
|
||||
`${config.storageConfig.caddyStorage.directory}/Caddyfile:/etc/caddy/Caddyfile`,
|
||||
)
|
||||
}
|
||||
|
||||
// Add environment variables for Caddy comments and potential ACME config
|
||||
services.caddy.environment = [
|
||||
`# Create a Caddyfile in ${config.storageConfig.caddyStorage.type === "volume" ? config.storageConfig.caddyStorage.volumeName : config.storageConfig.caddyStorage.directory} with the following content:`,
|
||||
`# ${config.caddyConfig.domain} {`,
|
||||
"# reverse_proxy homebox:7745",
|
||||
"# }",
|
||||
]
|
||||
|
||||
// Add email if provided for ACME
|
||||
if (config.caddyConfig.email) {
|
||||
// Ensure environment array exists
|
||||
if (!services.caddy.environment) {
|
||||
services.caddy.environment = []
|
||||
}
|
||||
services.caddy.environment.push(`ACME_AGREE=true`) // Note: Caddy v2 doesn't use ACME_AGREE env var, email is set in Caddyfile
|
||||
services.caddy.environment.push(`EMAIL=${config.caddyConfig.email}`) // This might be useful for scripting but Caddy reads email from Caddyfile
|
||||
services.caddy.environment.push(
|
||||
`# Add 'email ${config.caddyConfig.email}' to your Caddyfile for automatic HTTPS`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function addCloudflaredConfig(
|
||||
services: DockerServices,
|
||||
config: AppConfig,
|
||||
): void {
|
||||
// Add Cloudflared service
|
||||
services["cloudflared"] = {
|
||||
image: "cloudflare/cloudflared:latest",
|
||||
container_name: "homebox-cloudflared",
|
||||
restart: "always",
|
||||
command: ["tunnel", "--no-autoupdate", "run"],
|
||||
volumes: [],
|
||||
environment: [`TUNNEL_TOKEN=${config.cloudflaredConfig.token}`],
|
||||
depends_on: ["homebox"],
|
||||
}
|
||||
|
||||
// Configure cloudflared volumes based on storage type
|
||||
if (config.storageConfig.cloudflaredStorage.type === "volume") {
|
||||
services.cloudflared.volumes.push(
|
||||
`${config.storageConfig.cloudflaredStorage.volumeName}:/etc/cloudflared`,
|
||||
)
|
||||
} else {
|
||||
services.cloudflared.volumes.push(
|
||||
`${config.storageConfig.cloudflaredStorage.directory}:/etc/cloudflared`,
|
||||
)
|
||||
}
|
||||
|
||||
// Add comments via environment variables
|
||||
// Ensure environment array exists
|
||||
if (!services.cloudflared.environment) {
|
||||
services.cloudflared.environment = []
|
||||
}
|
||||
services.cloudflared.environment.push(
|
||||
"# Create a tunnel in the Cloudflare Zero Trust dashboard",
|
||||
`# Configure DNS for ${config.cloudflaredConfig.domain} to point to your tunnel`,
|
||||
"# Add a public hostname in the tunnel configuration pointing to http://homebox:7745",
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user