Some systems already use 80 and 443 port. Added some env variables to control the HOST (external) ports: CAPTAIN_HOST_HTTP_PORT (to change from 80), CAPTAIN_HOST_HTTPS_PORT (to change 443), CAPTAIN_HOST_ADMIN_PORT (to change 3000).

Also defined CONTAINER PORTS that never needs to change since are the ports inside containers. But is good to have as variables to be explicit that are CONAINER and not HOST ports.
This commit is contained in:
raisercostin
2024-12-08 20:39:45 +02:00
parent abea71983d
commit a64c01c253
8 changed files with 145 additions and 62 deletions

View File

@@ -18,6 +18,7 @@ import ThemePublicRouter from './routes/public/ThemePublicRouter'
import UserRouter from './routes/user/UserRouter'
import CaptainManager from './user/system/CaptainManager'
import CaptainConstants from './utils/CaptainConstants'
import EnvVars from './utils/EnvVars'
import Logger from './utils/Logger'
import Utils from './utils/Utils'
@@ -84,7 +85,7 @@ app.use(function (req, res, next) {
req.secure || req.get('X-Forwarded-Proto') === 'https'
if (!isRequestSsl) {
const newUrl = `https://${req.get('host')}${req.originalUrl}`
const newUrl = `https://${req.hostname}:${EnvVars.CAPTAIN_HOST_HTTPS_PORT}${req.originalUrl}`
res.redirect(302, newUrl)
return
}
@@ -113,7 +114,8 @@ app.use(CaptainConstants.netDataRelativePath, function (req, res, next) {
const newUrl =
(isRequestSsl ? 'https://' : 'http://') +
req.get('host') +
req.hostname + ':' +
(isRequestSsl ? CaptainConstants.configs.nginxPortNumber443 : CaptainConstants.configs.nginxPortNumber80) +
CaptainConstants.netDataRelativePath +
'/'
res.redirect(302, newUrl)

View File

@@ -6,6 +6,7 @@ import { AppDeployTokenConfig, IAppDef } from '../../../../models/AppDefinition'
import { CaptainError } from '../../../../models/OtherTypes'
import CaptainManager from '../../../../user/system/CaptainManager'
import CaptainConstants from '../../../../utils/CaptainConstants'
import EnvVars from '../../../../utils/EnvVars'
import Logger from '../../../../utils/Logger'
import Utils from '../../../../utils/Utils'
@@ -353,7 +354,7 @@ router.post('/update/', function (req, res, next) {
const redirectDomain = req.body.redirectDomain || ''
const preDeployFunction = req.body.preDeployFunction || ''
const serviceUpdateOverride = req.body.serviceUpdateOverride || ''
const containerHttpPort = Number(req.body.containerHttpPort) || 80
const containerHttpPort = Number(req.body.containerHttpPort) || EnvVars.CAPTAIN_CONTAINER_HTTP_PORT
const httpAuth = req.body.httpAuth
let appDeployTokenConfig = req.body.appDeployTokenConfig as
| AppDeployTokenConfig

View File

@@ -30,7 +30,7 @@ function startServer() {
* Get port from environment and store in Express.
*/
const port = normalizePort(process.env.PORT || '3000')
const port = EnvVars.CAPTAIN_CONTAINER_ADMIN_PORT
app.set('port', port)
/**
@@ -47,25 +47,6 @@ function startServer() {
server.on('error', onError)
server.on('listening', onListening)
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val: string) {
const port = parseInt(val, 10)
if (isNaN(port)) {
// named pipe
return val
}
if (port >= 0) {
// port number
return port
}
return false
}
/**
* Event listener for HTTP server "error" event.

View File

@@ -11,6 +11,7 @@ import { IServerBlockDetails } from '../../models/IServerBlockDetails'
import LoadBalancerInfo from '../../models/LoadBalancerInfo'
import { AnyError } from '../../models/OtherTypes'
import CaptainConstants from '../../utils/CaptainConstants'
import EnvVars from '../../utils/EnvVars'
import Logger from '../../utils/Logger'
import CertbotManager from './CertbotManager'
import fs = require('fs-extra')
@@ -430,7 +431,7 @@ class LoadBalancerManager {
getInfo() {
return new Promise<LoadBalancerInfo>(function (resolve, reject) {
const url = `http://${CaptainConstants.nginxServiceName}/nginx_status`
const url = `http://${CaptainConstants.nginxServiceName}:${EnvVars.CAPTAIN_CONTAINER_HTTP_PORT}/nginx_status`
request(url, function (error, response, body) {
if (error || !body) {
@@ -531,8 +532,12 @@ class LoadBalancerManager {
hasRootSsl: hasRootSsl,
serviceName: CaptainConstants.captainServiceName,
domain: captainDomain,
serviceExposedPort:
CaptainConstants.captainServiceExposedPort,
containerAdminPort:
EnvVars.CAPTAIN_CONTAINER_ADMIN_PORT,
containerHttpsPort:
EnvVars.CAPTAIN_CONTAINER_HTTPS_PORT,
containerHttpPort:
EnvVars.CAPTAIN_CONTAINER_HTTP_PORT,
defaultHtmlDir:
CaptainConstants.nginxStaticRootDir +
CaptainConstants.nginxDefaultHtmlDir,
@@ -657,33 +662,38 @@ class LoadBalancerManager {
Logger.d(
'No Captain Nginx service is running. Creating one on captain node...'
)
return dockerApi
.createServiceOnNodeId(
CaptainConstants.configs.nginxImageName,
CaptainConstants.nginxServiceName,
[
const portsToMap:IAppPort[] = [
{
protocol: 'tcp',
publishMode: 'host',
containerPort: 80,
hostPort:
CaptainConstants.configs.nginxPortNumber80,
},
{
protocol: 'tcp',
publishMode: 'host',
containerPort: 443,
hostPort:
CaptainConstants.configs.nginxPortNumber443,
containerPort: EnvVars.CAPTAIN_CONTAINER_HTTP_PORT,
hostPort: CaptainConstants.configs.nginxPortNumber80,
},
{
protocol: 'udp',
publishMode: 'host',
containerPort: 443,
hostPort: 443,
containerPort: EnvVars.CAPTAIN_CONTAINER_HTTP_PORT,
hostPort: CaptainConstants.configs.nginxPortNumber80,
},
],
{
protocol: 'tcp',
publishMode: 'host',
containerPort: EnvVars.CAPTAIN_CONTAINER_HTTPS_PORT,
hostPort: CaptainConstants.configs.nginxPortNumber443,
},
{
protocol: 'udp',
publishMode: 'host',
containerPort: EnvVars.CAPTAIN_CONTAINER_HTTPS_PORT,
hostPort: CaptainConstants.configs.nginxPortNumber443,
},
]
Logger.d('Creating Captain Nginx service with ports' +portsToMap)
return dockerApi
.createServiceOnNodeId(
CaptainConstants.configs.nginxImageName,
CaptainConstants.nginxServiceName,
portsToMap,
nodeId,
undefined,
undefined,
@@ -793,6 +803,7 @@ class LoadBalancerManager {
0
)
} else {
Logger.d('Captain Nginx is NOT running.. ')
return createNginxServiceOnNode(myNodeId).then(function () {
return myNodeId
})

View File

@@ -15,7 +15,8 @@ const CONSTANT_FILE_OVERRIDE_USER =
CAPTAIN_DATA_DIRECTORY + '/config-override.json'
const configs = {
publishedNameOnDockerHub: 'caprover/caprover',
publishedNameOnDockerHub:
EnvVars.CAPROVER_IMAGE ?? (EnvVars.CAPTAIN_IS_DEBUG ? 'captain-debug' : 'caprover/caprover'),
version: '1.13.3',
@@ -51,7 +52,7 @@ const configs = {
overlayNetworkOverride: {},
useExistingSwarm: false,
useExistingSwarm: EnvVars.USE_EXISTING_SWARM,
proApiDomains: ['https://pro.caprover.com'],
@@ -64,9 +65,12 @@ const configs = {
// this is added in 1.13 just as a safety - remove this after 1.14
disableEncryptedCheck: false,
nginxPortNumber80: 80,
nginxPortNumber443: 443,
// The port can be overridden via env variable CAPTAIN_HOST_HTTP_PORT
nginxPortNumber80: EnvVars.CAPTAIN_HOST_HTTP_PORT,
// The port can be overridden via env variable CAPTAIN_HOST_HTTPS_PORT
nginxPortNumber443: EnvVars.CAPTAIN_HOST_HTTPS_PORT,
// The port can be overridden via env variable CAPTAIN_HOST_ADMIN_PORT
adminPortNumber3000: EnvVars.CAPTAIN_HOST_ADMIN_PORT,
}
export interface CertbotCertCommandRule {
@@ -89,7 +93,7 @@ const data = {
isDebug: EnvVars.CAPTAIN_IS_DEBUG,
captainServiceExposedPort: 3000,
captainServiceExposedPort: configs.adminPortNumber3000,
rootNameSpace: 'captain',
@@ -204,7 +208,7 @@ const data = {
// ********************* ETC ************************
disableFirewallCommand:
'ufw allow 80,443,3000,996,7946,4789,2377/tcp; ufw allow 7946,4789,2377/udp; ',
'ufw allow ' + configs.nginxPortNumber80 + ',' + configs.nginxPortNumber443 + ',' + configs.adminPortNumber3000 + ',996,7946,4789,2377/tcp; ufw allow 7946,4789,2377/udp; ',
gitShaEnvVarKey: 'CAPROVER_GIT_COMMIT_SHA',
}

View File

@@ -83,7 +83,7 @@ function startServerOnPort_80_443_3000() {
})
res.write(FIREWALL_PASSED)
res.end()
}).listen(80)
}).listen(EnvVar.CAPTAIN_CONTAINER_HTTP_PORT)
http.createServer(function (req, res) {
res.writeHead(200, {
@@ -91,7 +91,7 @@ function startServerOnPort_80_443_3000() {
})
res.write(FIREWALL_PASSED)
res.end()
}).listen(443)
}).listen(EnvVar.CAPTAIN_CONTAINER_HTTPS_PORT)
http.createServer(function (req, res) {
res.writeHead(200, {
@@ -99,7 +99,7 @@ function startServerOnPort_80_443_3000() {
})
res.write(FIREWALL_PASSED)
res.end()
}).listen(3000)
}).listen(EnvVar.CAPTAIN_CONTAINER_ADMIN_PORT)
return new Promise<void>(function (resolve) {
setTimeout(function () {
@@ -255,7 +255,7 @@ export function install() {
)
}
if (CaptainConstants.isDebug) {
if (CaptainConstants.isDebug && !CaptainConstants.configs.useExistingSwarm) {
return new Promise<string>(function (resolve, reject) {
DockerApi.get()
.swarmLeave(true)
@@ -280,13 +280,13 @@ export function install() {
return startServerOnPort_80_443_3000()
})
.then(function () {
return checkPortOrThrow(myIp4, 80)
return checkPortOrThrow(myIp4, CaptainConstants.configs.nginxPortNumber80 as any)
})
.then(function () {
return checkPortOrThrow(myIp4, 443)
return checkPortOrThrow(myIp4, CaptainConstants.configs.nginxPortNumber443 as any)
})
.then(function () {
return checkPortOrThrow(myIp4, 3000)
return checkPortOrThrow(myIp4, CaptainConstants.configs.adminPortNumber3000 as any)
})
.then(function () {
const imageName = CaptainConstants.configs.nginxImageName
@@ -301,7 +301,10 @@ export function install() {
.then(function () {
const imageName = CaptainConstants.configs.certbotImageName
console.log(`Pulling: ${imageName}`)
return DockerApi.get().pullImage(imageName, undefined)
return DockerApi.get().pullImage(imageName, undefined).catch(function (onrejected) {
console.log(`Continnuing failed pull, maybe image already exists: ${imageName}.`, onrejected)
return Promise.resolve()
})
})
.then(function () {
return backupManger.checkAndPrepareRestoration()
@@ -332,6 +335,18 @@ export function install() {
key: EnvVar.keys.IS_CAPTAIN_INSTANCE,
value: '1',
})
env.push({
key: EnvVar.keys.CAPTAIN_HOST_ADMIN_PORT,
value: CaptainConstants.configs.adminPortNumber3000 + '',
})
env.push({
key: EnvVar.keys.CAPTAIN_HOST_HTTP_PORT,
value: CaptainConstants.configs.nginxPortNumber80 + '',
})
env.push({
key: EnvVar.keys.CAPTAIN_HOST_HTTPS_PORT,
value: CaptainConstants.configs.nginxPortNumber443 + '',
})
if (EnvVar.DEFAULT_PASSWORD) {
env.push({
@@ -386,8 +401,8 @@ export function install() {
ports.push({
protocol: 'tcp',
publishMode: 'host',
containerPort: CaptainConstants.captainServiceExposedPort,
hostPort: CaptainConstants.captainServiceExposedPort,
containerPort: EnvVar.CAPTAIN_CONTAINER_ADMIN_PORT,
hostPort: CaptainConstants.configs.adminPortNumber3000,
})
return DockerApi.get().createServiceOnNodeId(

View File

@@ -1,3 +1,27 @@
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val: string | undefined, defaultPort: number): number {
if (val === undefined) {
return defaultPort
}
const port = parseInt(val, 10)
if (isNaN(port)) {
// named pipe
return defaultPort
}
if (port >= 0) {
// port number
return port
}
return defaultPort
}
export default {
keys: {
CAPTAIN_DOCKER_API: 'CAPTAIN_DOCKER_API',
@@ -6,6 +30,14 @@ export default {
IS_CAPTAIN_INSTANCE: 'IS_CAPTAIN_INSTANCE',
DEMO_MODE_ADMIN_IP: 'DEMO_MODE_ADMIN_IP',
CAPTAIN_BASE_DIRECTORY: 'CAPTAIN_BASE_DIRECTORY',
CAPTAIN_CONTAINER_HTTP_PORT: 'CAPTAIN_CONTAINER_HTTP_PORT',
CAPTAIN_HOST_HTTP_PORT: 'CAPTAIN_HOST_HTTP_PORT',
CAPTAIN_CONTAINER_HTTPS_PORT: 'CAPTAIN_CONTAINER_HTTPS_PORT',
CAPTAIN_HOST_HTTPS_PORT: 'CAPTAIN_HOST_HTTPS_PORT',
CAPTAIN_CONTAINER_ADMIN_PORT: 'CAPTAIN_CONTAINER_ADMIN_PORT',
CAPTAIN_HOST_ADMIN_PORT: 'CAPTAIN_HOST_ADMIN_PORT',
USE_EXISTING_SWARM: 'USE_EXISTING_SWARM',
SHOW_DOCKER_COMMANDS: 'SHOW_DOCKER_COMMANDS',
},
BY_PASS_PROXY_CHECK: process.env.BY_PASS_PROXY_CHECK,
@@ -14,8 +46,28 @@ export default {
CAPTAIN_IS_DEBUG: !!process.env.CAPTAIN_IS_DEBUG,
DEBUG_SOURCE_DIRECTORY: process.env.DEBUG_SOURCE_DIRECTORY,
CAPROVER_IMAGE: process.env.CAPROVER_IMAGE,
SHOW_DOCKER_COMMANDS: !!process.env.SHOW_DOCKER_COMMANDS,
// Internal container ports, these does not need to change.
CAPTAIN_CONTAINER_HTTP_PORT: normalizePort(process.env.CAPTAIN_CONTAINER_HTTP_PORT, 80),
CAPTAIN_CONTAINER_HTTPS_PORT: normalizePort(process.env.CAPTAIN_CONTAINER_HTTPS_PORT, 443),
CAPTAIN_CONTAINER_ADMIN_PORT: normalizePort(process.env.CAPTAIN_CONTAINER_ADMIN_PORT, 3000),
// Host ports - external to container. Refer it via CaptainConstants.configs.nginxPortNumber80
CAPTAIN_HOST_HTTP_PORT: normalizePort(process.env.CAPTAIN_HOST_HTTP_PORT, 80),//Tested with 10080
// Host ports - external to container. Refer it via CaptainConstants.configs.nginxPortNumber443
CAPTAIN_HOST_HTTPS_PORT: normalizePort(process.env.CAPTAIN_HOST_HTTPS_PORT, 443),//Tested with 10443
// Host ports - external to container. Refer it via CaptainConstants.captainServiceExposedPort
CAPTAIN_HOST_ADMIN_PORT: normalizePort(process.env.CAPTAIN_HOST_ADMIN_PORT, 3000),//Tested with 13000
MAIN_NODE_IP_ADDRESS: process.env.MAIN_NODE_IP_ADDRESS,
USE_EXISTING_SWARM: !!process.env.USE_EXISTING_SWARM,
ACCEPTED_TERMS: !!process.env.ACCEPTED_TERMS,
IS_CAPTAIN_INSTANCE: process.env.IS_CAPTAIN_INSTANCE,