How to change the port of nginx when using with docker
When you're starting with Docker you may find helpful information about images at DockerHub. For example with nginx you have a section about how to expose public ports.
You can just use:
docker run --publish 3000:80 nginx
Port 3000 in your localhost will be forwarded to port 80 which is the port that nginx images use to wait for http connections.
I also recommend you to read these official docs about networking in Docker.
The accepted answer does not change the actual port that nginx is starting up on.
If you want to change the port nginx starts up on inside the container, you have to modify the /etc/nginx/nginx.conf file inside the container.
For example, to start on port 9080:
Dockerfile
FROM nginx:1.17-alpine
COPY <your static content> /usr/share/nginx/html
COPY nginx.conf /etc/nginx/
EXPOSE 9080
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
# on alpine, copy to /etc/nginx/nginx.conf
user root;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile off;
access_log off;
keepalive_timeout 3000;
server {
listen 9080;
root /usr/share/nginx/html;
index index.html;
server_name localhost;
client_max_body_size 16m;
}
}
Now to access the server from your computer:
docker build . -t my-app
docker run -p 3333:9080 my-app
navigating to localhost:3333 in a browser, you'll see your content.
There is probably a way to include the default nginx.conf, and override only the server.listen = PORT property, but I'm not too familiar with nginx config, so I just overwrote the entire default configuration.
You can use nginx.conf to change it to any port.
nginx.conf will have all the configurations related to nginx. Default value for port here is 80 which we can change as below.
nginx.conf
server {
listen 3000;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
include /etc/nginx/extra-conf.d/*.conf;
}
and in DockerFile add a line:
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
You wrote you are a beginner, so first of all I'll just mention that the default configuration for the nginx image (I'll assume you're using a standard image) is to listen in port 80
.
This is why you can't map to port 3000
inside the container because there is no process that listen to this port.
Now if I understood you correctly and with the fact that you're using nginx with docker I guess you want to be able to configure the container's port (and not the host port because this is quiet trivial).
@mancini0 started a good direction, but I'll show how to do it in a more dynamic fashion.
We'll use the envsubst command which substitutes environment variables in shell format strings.
This command is available with the offical nginx image and also with the alpine version.
Now for the solution.
Step #1
write your nginx configuration in a template file - let's call it: site.template
:
server {
listen ${PORT};
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
Notice the PORT placeholder.
Step #2 - with docker-compose
Mount that inside the /etc/nginx/conf.d
directory and then execute the envsubst
command to use the template as a reference for default.conf
which is the file which will be used to setup the port configuration inside the container:
web:
image: nginx:alpine
volumes:
- ./site.template:/etc/nginx/conf.d/site.template
ports:
- "3000:8080"
environment:
- PORT=8080
command: /bin/sh -c "envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
Notice that:
1. You need to execute the nginx daemon after that.
2. I used /bin/sh
and not /bin/bash
because my base image is alpine.
Step #2 (Another option) - inline docker run
If, for some reason you don't want to work with docker-compose you can use the following bash script:
#!/usr/bin/env bash
##### Variables #####
PORT=8080 #Or $1 if you pass it from command line
TEMPLATE_DIR=$(pwd)/site.template
TEMPLATE_REMOTE_DIR=/etc/nginx/conf.d/site.template
IMAGE_NAME=nginx:alpine
echo "Starting nginx on port: $PORT ..."
##### The docker command #####
docker run -p 3000:$PORT -v $TEMPLATE_DIR:$TEMPLATE_REMOTE_DIR $IMAGE_NAME \
/bin/sh -c "envsubst < $TEMPLATE_REMOTE_DIR > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
(*) You can also write it inside your Dockerfile with the CMD
command, but I won't recommend you doing that.