Port detection is one of the step included during component detection and it refers to the ports used by the component that should be opened in the container. Because of the different nature of frameworks supported, Alizer tries to use customized ways to detect ports from source code, if necessary. Only ports with value > 0 and < 65535 are valid
Deprecation Warning: The port detection strategies will be removed in the future releases of alizer.
There are three detection strategies currently available:
- Docker file - Alizer looks for a Dockerfile, or Containerfile, in the root folder and tries to extract ports from it.
- Compose file - Alizer searches for a docker-compose file in the root folder and tries to extract port of the service from it
- Source - If a framework has been detected during component detection, a customized detection is performed. Below a detailed overview of the different strategies for each supported framework.
By default, Alizer perform a first a docker, then a compose and finally source detection. If one or more ports are found in one step, the rest are skipped. (E.g - if a port is found in the docker file, Alizer will not search and analyze any docker-compose file and the source code).
It is also possible to customize the way Alizer searches for ports by defining the detection strategies to use and their order. For example, by using a source and docker strategies, Alizer analyzes the source code and then the docker file, if any. Or docker and compose, to avoid analyzing the source.
If no port is found an empty list is returned.
The port detection in a [compose|docker-compose].[yml|yaml]
file targets the expose
and ports
fields of the service related to the component, if any. To search for the specific component, Alizer look at the build
field.
Example of expose
- the result is [3000,8000]
services:
web:
...
build: .
expose:
- "3000"
- "8000"
myapp2:
...
expose:
- "5000"
Example of short syntax ports
([HOST:]CONTAINER[/PROTOCOL]
) - the result is [3000,3005,8000,8081,8002,6060]
services:
web:
...
build: .
ports:
- "3000" # container port (3000), assigned to random host port
- "8000:8000" # container port (8000), assigned to given host port (8000)
- "127.0.0.1:8002:8002" # container port (8002), assigned to given host port (8002) and bind to 127.0.0.1
- "6060:6060/udp" # container port (6060) restricted to UDP protocol, assigned to given host (6060)
myapp2:
...
expose:
- "5000"
Example of long syntax ports
- the result is [6060]
services:
web:
...
build: .
ports:
- target: 6060
host_ip: 127.0.0.1
published: 6060
protocol: udp
mode: host
myapp2:
...
expose:
- "5000"
For Java frameworks not having a specific application file, Alizer will only try to detect ports defined inside .java
files and not inside the entire component directory.
Alizer checks if the environment variable MICRONAUT_SERVER_SSL_ENABLED is set to true. If so, both MICRONAUT_SERVER_SSL_PORT and MICRONAUT_SERVER_PORT are checked (if false, only the MICRONAUT_SERVER_PORT is used for verification). Alizer will first look for if the env vars are set in the system and if it doesn't find them it will also look for a dockerfile. If they are not set or they do not contain valid port values, Alizer searches for the application.[yml|yaml]
file in src/main/resources
folder and verify if one or more ports are set.
The known schema is:
micronaut:
server:
port: <port>
ssl:
enabled: <true|false>
port: <port>
Alizer searches for the server.xml
file within the root or src/main/liberty/config
folder and verify if a port is set.
The known schema is:
<server>
<httpEndpoint id="defaultHttpEndpoint"
httpPort="<port>"
httpsPort="<port>" />
</server>
Alizer follows the default behavior of Quarkus which reads configuration properties from multiple sources (by descending ordinal).
N.B: If insecure requests are disabled only the HTTP SSL port will be detected
- It checks if the environment variable
QUARKUS_HTTP_SSL_PORT
,QUARKUS_HTTP_INSECURE_REQUESTS
andQUARKUS_HTTP_PORT
are set - It checks for
QUARKUS_HTTP_SSL_PORT
,QUARKUS_HTTP_INSECURE_REQUESTS
andQUARKUS_HTTP_PORT
within the.env
file, if any, located in the root - It checks for
QUARKUS_HTTP_SSL_PORT
,QUARKUS_HTTP_INSECURE_REQUESTS
andQUARKUS_HTTP_PORT
within thedockerfile
file, if any, located under the root level or one level down. - It searches for any
application.[properties|yaml|yml]
file insrc/main/resources
folder and verify if a port is set.
The known schemas for application files are:
For .properties
...
quarkus.http.port=<port>
quarkus.http.insecure-requests=<enabled|redirect|disabled>
quarkus.http.ssl-port=<port>
...
For .yaml|.yml
...
quarkus
http
port=<port>
insecure-requests=<enabled|redirect|disabled>
ssl-port=<port>
...
Alizer checks if the environment variable SERVER_PORT or SERVER_HTTP_PORT are set. First, it checks into the operating system and if it doesn't find any, it then checks inside a dockerfile located under the root level or one level down (if any). If not or they do not contain valid port values, it searches for the application.[yml|yaml]
or application.properties
file in src/main/resources
folder and verify if a port is set.
The known schema for application.[yml|yaml]
is:
server:
port: <port>
http:
port <port>
and the schema for application.properties
server.port=<port>
server.http.port=<port>
Alizer searches for any json
file in src/main/conf
folder and verify if a port is set by using this schema
{
...
"http.port": <port>,
"http.server": {
"http.server.port": <port>,
},
...
}
Alizer searches inside the pom.xml
file to find any configuration inside the profiles for plugin eap-maven-plugin
:
<configuration>
...
<javaOpts>-Djboss.https.port=8080</javaOpts>
...
</configuration>
For JavaScript frameworks not having a specific application file, Alizer will only try to detect ports defined inside .js
files and not inside the entire component directory.
Alizer uses three ways to detect ports configuration in an Angular project
- It checks if the file
angular.json
exists in the root and analyze it to see if a port is set, using the following schema
{
...
"projects": {
"project-name": {
...
"architect": {
"serve": {
"options": {
"host": "...",
"port": "...",
...
}
N.B: project-name
is the actual app name retrieved within the package.json
- It checks if the
start
npm script sets aport
(e.g."start": ".... --port <port>"
) - It checks if the file
angular-cli.json
exists in the root and analyze it to see if a port is set, using the following schema
{
...
"defaults": {
"serve": {
"host": "...",
"port": "...",
}
}
...
}
Alizer searches for function listen
calls as Express uses it to define port
and host
to be used use.
Once all occurrences are found it tries to get the ports in three step:
- The port is written in clear within the
listen
function (e.g.listen(3000)
), Alizer extracts it. - The port argument is an env variable and Alizer tries to look for its value locally. If there isn't any locally, alizer tries to locate any dockerfile that may sets env values for this port.
- The port argument is a variable set within the code and Alizer tries to find it in the code that exists before the
.listen
call
Example of all 3 cases
const express = require('express')
const app = express()
const port = 3000
// variable - case 3
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
// env variable - case 2
app.listen(process.env.PORT, () => {
console.log(`Example app listening on port ${port}`)
})
// value in clear - case 1
app.listen(8080, () => {
console.log(`Example app listening on port ${port}`)
})
In case we have an OR operator with an environment variable alizer will return both ports, first the env var and then the default one. Again, it will look first locally for env var and if there is none it will check for dockerfile.
Alizer searches for any port set within the start and dev scripts when dealing with a Next project
- It checks if the
start
npm script sets aport
(e.g."start": ".... -p <port>"
) - It checks if the
dev
npm script sets aport
(e.g."dev": ".... -p <port>"
)
In a Nuxt project, port detection works by analyzing the package.json
and the nuxt.config.js
files
- It checks if the
start
npm script sets aport
(e.g."start": ".... --port=<port>"
) - It checks if the
dev
npm script sets aport
(e.g."dev": ".... --port=<port>"
) - It checks if the file
nuxt.config.js
exists in the root and analyze it to see if a port is set (e.gport: <port>
)
Alizer follows the general rules by React. The strategy used consists of 3 steps:
- It checks if the environment variable
PORT
is set - It checks for the
PORT
within the.env
file, if any, located in the root. If there isn't any, alizer will try to locate adockerfile
that might set thePORT
env var. - It checks if the
start
npm script sets aPORT
(e.g."start": "PORT=<port> react-scripts start"
)
Alizer searches for any port configured within the dev
npm script (e.g. "dev": ".... --port <port>"
or "dev": ".... PORT=<port>"
)
Alizer uses four ways to detect ports configuration in a Vue project
- It checks if the
start
npm script sets aport
(e.g."start": ".... --port <port>"
or"start": ".... PORT=<port>"
) - It checks if the
dev
npm script sets aport
(e.g."dev": ".... --port <port>"
or"dev": ".... PORT=<port>"
) - It checks if the port is configured within the
.env
file, if any, located in the root. If there isn't any, alizer will try to locate adockerfile
that might set thePORT
env var. - It checks if the file
vue.config.js
exists in the root and analyze it to see if a port is set, using the following schema
exports = {
...
port: <port>
...
}
Alizer searches inside the pom.xml
file to find any configuration inside the profiles for plugin wildfly-maven-plugin
:
<configuration>
...
<javaOpts>-Djboss.https.port=8080</javaOpts>
# or http
<javaOpts>-Djboss.http.port=8080</javaOpts>
...
</configuration>
Alizer searches for the default_port
property set within the manage.py
file
Example
import django
django.setup()
# Override default port for `runserver` command
from django.core.management.commands.runserver import Command as runserver
runserver.default_port = "<port>"
For Golang frameworks not having a specific application file, Alizer will only try to detect ports defined inside .go
files and not inside the entire component directory.
Alizer parses the conf/app.conf
file looking for the httpport
variable
Example
appname = beepkg
httpaddr = "127.0.0.1"
httpport = 9090
runmode ="dev"
autorender = false
recoverpanic = false
viewspath = "myview"
Alizer searches either for 2 different function calls - ListenAndServe(:<port>)
and Start(:<port>)
- or for the initialization of the Addr
property of Server struct.
If <port>
is a variable, it tries to find its value within the code.
Example
func main() {
e := echo.New()
// add middleware and routes
// ...
s := http.Server{
Addr: ":8080",
Handler: e,
}
if err := s.ListenAndServe(); err != http.ErrServerClosed {
log.Fatal(err)
}
}
Alizer searches for the function ListenAndServe(:<port>)
call. If <port>
is a variable, it tries to find its value within the code.
fasthttp.ListenAndServe(":8080", myHandler.HandleFastHTTP)
Alizer searches for the function Run(:<port>)
call. If <port>
is a variable, it tries to find its value within the code.
router.Run(":3000")
Alizer searches for the function Listen(:<port>)
call. If <port>
is a variable, it tries to find its value within the code.
app.Listen(":3000")
Alizer searches either for the function ListenAndServe(:<port>)
call or for the initialization of the Addr
property of Server struct.
If <port>
is a variable, it tries to find its value within the code.
srv := &http.Server{
Handler: r,
Addr: "127.0.0.1:8000",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
In case a project doesn't use one of the above frameworks, and no ports have been found, alizer will search for 2 different function calls - ListenAndServe(:<port>)
and Start(:<port>)
- or for the initialization of the Addr
property of Server struct.
Alizer will try to detect any ports set as environment variables with APP_PORT
as name. First, it will try to locate an .env
file that might exists in the source code. If there isn't any it will also try to locate any dockerfile
that might sets the APP_PORT
as environment variable.