How to change php-fpm default port? - docker

I'm using php-fpm which runs for default on the port 9000. The problem's that I have other docker container based on php-fpm, so I need to change the default port to another one, in order to not confuse nginx.
This is my Dockerfile:
FROM php:8.0.2-fpm-alpine
RUN sed -i 's/9000/9001/' /usr/local/etc/php-fpm.d/zz-docker.conf
WORKDIR /var/www/html
CMD ["php-fpm"]
EXPOSE 9001
I tried to use the sed command to replace the port 9000 with 9001.
Inside my docker-compose file I have this configuration:
version: '3.9'
services:
php-fpm:
container_name: app
restart: always
build:
context: .
dockerfile: ./docker/php-fpm/Dockerfile
ports:
- "9001:9000"
volumes:
- ./src:/var/www/html
- ./docker/php-fpm/config/www.conf:/usr/local/etc/php-fpm.d/www.conf
- ./src/public:/app/public
- ./src/writable:/app/writable
nginx:
image: nginx:stable-alpine
container_name: nginx
restart: always
volumes:
- ./src:/var/www/html
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx/sites/:/etc/nginx/sites-available
- ./docker/nginx/conf.d/:/etc/nginx/conf.d
depends_on:
- php-fpm
environment:
VIRTUAL_HOST: ${HOST}
LETSENCRYPT_HOST: ${HOST}
LETSENCRYPT_EMAIL: ${EMAIL}
as you can see I have exposed the port 9001 also in the docker-compose file.
The file default.conf available within conf.d folder contains this:
upstream php-upstream {
server php-fpm:9001;
}
the problem's that for some reason, when I load my site I get the error 500. So this means that the stream doesn't send any signal. If I change to port 9000 everything works, but the stream is wrong 'cause it's the content of another application.
How can I correctly change the default port?

I think the problem is not the sed command itself, it's related to the wrong file you mentioned for it.
/usr/local/etc/php-fpm.d/zz-docker.conf
this is the file you are trying to change the port in it but inside your docker-compose file you are mapping something else
./docker/php-fpm/config/www.conf:/usr/local/etc/php-fpm.d/www.conf

Keep in mind that your nginx docker connects via the internal docker net work, your docker host port mapping 9001:9000 is not taken into account.
If your php-fpm is really listening on port 9001, then that is the port you must use in your nginx config.
Also EXPOSE is primarily declarative and does not expose anything by itself (https://docs.docker.com/engine/reference/builder/#expose) the corresponding service must still be configured correctly to use that port.

for this line in Dockerfile is not working(?):
RUN sed -i 's/9000/9001/' /usr/local/etc/php-fpm.d/zz-docker.conf
so I decided to make this change after the container is up with:
docker exec -i your_container bash -c 'sed -i 's/9000/9001/' /usr/local/etc/php-fpm.d/zz-docker.conf'
and then restert the container to make changes happened
hope help you

Related

Can't access web container from outside (Windows Docker-Desktop)

i'm using Docker-Desktop on Windows and i'm trying to get running 3 containers inside docker-desktop.
After few research and test, i get the 3 container running [WEB - API - DB], everything seems to compile/run without issue in the logs but i'can't access my web container from outside.
Here's my dockerfile and docker-compose, what did i miss or get wrong ?
[WEB] dockerfile
FROM node:16.17.0-bullseye-slim
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
#EXPOSE 4200 (the issue is the same with or without this line)
CMD ["npm", "run", "start"]
[API] dockerfile
FROM openjdk:17.0.1-jdk-slim
WORKDIR /app
COPY ./target/test-0.0.1-SNAPSHOT.jar /app
#EXPOSE 2022 (the issue is the same with or without this line)
CMD ["java", "-jar", "test-0.0.1-SNAPSHOT.jar"]
Docker-compose file
version: "3.8"
services:
### FRONTEND ###
web:
container_name: wallet-web
restart: always
build: ./frontend
ports:
- "80:4200"
depends_on:
- "api"
networks:
customnetwork:
ipv4_address: 172.20.0.12
#networks:
# - "api"
# - "web"
### BACKEND ###
api:
container_name: wallet-api
restart: always
build: ./backend
ports:
- "2022:2022"
depends_on:
- "db"
networks:
customnetwork:
ipv4_address: 172.20.0.11
#networks:
# - "api"
# - "web"
### DATABASE ###
db:
container_name: wallet-db
restart: always
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=postgres
networks:
customnetwork:
ipv4_address: 172.20.0.10
#networks:
# - "api"
# - "web"
networks:
customnetwork:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
# api:
# web:
Listening on:
enter image description here
I found several issue similar to mine but the solution didn't worked for me.
If i understand you are trying to access on port 80. To do that, you have to map your container port 4200 to 80 in yaml file 80:4200 instead of 4200:4200.
https://docs.docker.com/config/containers/container-networking/
Have you looked in the browsers development console, if there comes any error. Your docker-compose seems not to have any issue.
How ever lets try to debug it:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6245eaffd67e nginx "/docker-entrypoint.…" About an hour ago Up About an hour 0.0.0.0:4200->80/tcp test-api-1
copy the container id then execute:
docker exec -it 6245eaffd67e bin/bash
Now you are inside the container. Instead of the id you can use also the containers name.
curl http://localhost:80
Note: in my case here i just create a container from an nginx image.
In your case use the port where your app is running. Control it in your code if you arent sure. A lot of Javascript-frameworks start default on 3000.
If you get an error: curl command not found, install it in your image:
FROM node:16.17.0-bullseye-slim
USER root # to install dependencies you need sudo permissions su we tell the image that it is root
RUN apt update -y && apt install curl -y
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
#EXPOSE 4200 (the issue is the same with or without this line)
USER node # we dont want to execute the image as root so we put user node (this user is defined in the node:16.17.0-bullseye-slim image)
CMD ["npm", "run", "start"]
Now the curl should work (if it doesnt already).
The same should work from your host.
Here is an important thing:
The localhost, always refers to the fisical computer, or the container itselfs where you are refering. Every container and your PC have localhost and they are not the same.
In the docker-compose you just map the port host/container, so your PC (host) where docker is running can access the docker network from the host on the host port you defined, inside the port of the container.
If you cant still access from your host, try to change the host ports 2022, 4200 ecc. Could be possible that something conflicts on your Windows machine.
It happens sometimes that the docker networks can create some conflicts.
Execute a docker-compose down, so it should be delete and recreated.
Still not working?
Reset docker-desktop to factory settings, control if you have last version (this is always better).
If all this doesnt help, let me know so we can debugg further.
For the sake of clarity i post you here the docker-compose which i used to check. I just used nginx to test the ports as i dont have your images.
version: "3.8"
services:
### FRONTEND ###
web:
restart: always
image: nginx
ports:
- "4200:80"
depends_on:
- "api"
networks:
- "web"
### BACKEND ###
api:
restart: always
image: nginx
ports:
- "2022:80"
depends_on:
- "db"
networks:
- "api"
- "web"
### DATABASE ###
db:
restart: always
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=postgres
networks:
- "api"
networks:
api:
web:
```
Update:
You can log what happens in the conatiner like so:
```
docker logs containerid/name
```
If you are using Visualcode there is excellent extension for docker build also by Microsoft:
Just search docker in the extensions. Has something like 20.000.000 downloads and can help you a lot debugging containers ecc. After installing it you see the dockericon on the left toolbar.
If you can see directly the errors that occurs in the logs, maybe you can post them partially. So it would be possible to understand. Please tell also something about your Frontendapp architecture, (react-app, angular). There are some frameworks that need to be startet on 0.0.0.0 instead of 127.0.0.1 or they dont work.

Docker with Nginx: host not found in upstream

I'm trying to follow this guide to setting up a reverse proxy for a docker container (serving a static file), using another container with an instance of nginx as a reverse proxy.
I expect to see my page served on /, but I am blocked in the build with the error message:
container_nginx_1 | 2020/05/10 16:54:12 [emerg] 1#1: host not found in upstream "container1:8001" in /etc/nginx/conf.d/sites-enabled/virtual.conf:2
container_nginx_1 | nginx: [emerg] host not found in upstream "container1:8001" in /etc/nginx/conf.d/sites-enabled/virtual.conf:2
nginx_docker_test_container_nginx_1 exited with code 1
I have tried many variations on the following virtual.conf file, and this is the current, based on the example given and various other pages:
upstream cont {
server container1:8001;
}
server {
listen 80;
location / {
proxy_pass http://cont/;
}
}
If you are willing to look at a 3rd party site, I've made a minimal repo here, otherwise the most relevant files are below.
My docker-compose file looks like this:
version: '3'
services:
container1:
hostname: container1
restart: always
image: danjellz/http-server
ports:
- "8001:8001"
volumes:
- ./proj1:/public
command: "http-server . -p 8001"
depends_on:
- container_nginx
networks:
- app-network
container_nginx:
build:
context: .
dockerfile: docker/Dockerfile_nginx
ports:
- 8080:8080
networks:
- app-network
networks:
app-network:
driver: bridge
and the Dockerfile
# docker/Dockerfile_nginx
FROM nginx:latest
# add nginx config files to sites-available & sites-enabled
RUN mkdir /etc/nginx/conf.d/sites-available
RUN mkdir /etc/nginx/conf.d/sites-enabled
ADD projnginx/conf.d/sites-available/virtual.conf /etc/nginx/conf.d/sites-available/virtual.conf
RUN cp /etc/nginx/conf.d/sites-available/virtual.conf /etc/nginx/conf.d/sites-enabled/virtual.conf
# Replace the standard nginx conf
RUN sed -i 's|include /etc/nginx/conf.d/\*.conf;|include /etc/nginx/conf.d/sites-enabled/*.conf;|' /etc/nginx/nginx.conf
WORKDIR /
I'm running this using docker-compose up.
Similar: react - docker host not found in upstream
The problem is if the hostname can not be resolved in upstream blocks, nginx will not start. Here you have defined service container1 to be dependent on container_nginx . But nginx container is never up due to the fact the container1 hostname is not resolved (because container1 is not yet started) Don't you think it should be reverse? Nginx container should be dependent on the app container.
Additionally in your nginx port binding you have mapped 8080:8080 while in nginx conf you have 80 listening.

How to configure mariadb docker-compose file to use other port than 3306?

I cannot get mariadb to use another port other than 3306 when running it in a docker container using a docker-compose file.
I have already read the mariadb/docker documentation, searched online and conducted my own experiments.
docker-compose file:
version: '3.1'
services:
db:
image: mariadb
restart: always
environment:
- MYSQL_ROOT_PASSWORD=mypassword
- MYSQL_TCP_PORT=33030
- MYSQL_UNIX_PORT=33020
ports:
- "33020:33020"
Dockerfile:
FROM: mariadb: 10.3.14
COPY mydbscript.sql /docker-entrypoint-initdb.d/
EXPOSE 33020
CMD ["mysqld"]
It never uses port 33020. It still uses port 3306. How can I pass the port dynamically via the docker-compose file at run-time?
You need to replace the default my.cnf to specify a custom port for MariaDB/MySQL:
cd /where/your/docker-compose.yml/located
docker run -it mariadb cat /etc/mysql/my.cnf > my.cnf
# use any text editor your like to open my.cnf, search for "port = 3306"
# and replace it to the port you like to have.
Configure your docker-compose.yml like this:
version: '3.1'
services:
db:
image: mariadb
restart: always
volumes:
- type: bind
source: ./my.cnf
target: /etc/mysql/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=mypassword
# add your other configurations here
The container image is statically bound to :3306. If you wish to change this, you'll need to build a new image and configure the database to run elsewhere.
However, Docker permits you to map (publish) this as a different port :33020.
The correct way to do this is to:
docker-compose MYSQL_TCP_PORT=3306
docker-compose ports: - "33020:3306"
Dockerfile EXPOSE 3306 (unchanged)
Containers (internally) will correctly reference :3306 but externally (from the host) the database will be exposed on :33020.
NB Within docker-compose (network), other containers must continue to reference the database on port :3306.
#DazWilkin, #philip-tzou, of course it's possible!
How to set the port without config file is even explained in the dockerhub-page of mariadb. (https://hub.docker.com/_/mariadb) #Software just did the mistake of using '=' instead of ':' in the docker-compose.yml. I did it the first time too because I copied the environment veriables from a docker run bash file.
This docker-compose.yml (with .env File) works for me to set both, internal and external port of my mariaDB service:
version: "3.9"
services:
database:
image: mariadb:10.8
container_name: ${db_containername}
environment:
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes
MARIADB_DATABASE: ${db_database}
MARIADB_USER: ${db_user}
MARIADB_PASSWORD: ${db_password}
MYSQL_TCP_PORT: ${db_port_internal}
MARIADB_AUTO_UPGRADE: 1
MYSQL_UNIX_PORT: /run/mysqld/mysqld.sock
MARIADB_MYSQL_LOCALHOST_USER: true
restart: always
ports:
- '${db_port_external}:${db_port_internal}'
expose:
- ${db_port_external}
volumes:
- 'database_data:/var/lib/mysql'
This is how you can set a different port for your mariadb inside the container
1. Create a my.cnf file inside the same directory as you dockerfile
write this inside the my.cnf file
[mysqld]
port = 33020
2. Add the cnf file to the dockerfile & edit the EXPOSE
Add this line of code to your docker file
COPY my.cnf /etc/mysql/my.cnf
And make sure to change the external exposed port to the one you want to use e.i
EXPOSE 33020
3. Make sure to change the port in the docker-compose.yml file
ports:
- "33020:33020"
You can now connect to your database in either the terminal using the docker exec -it {databasename} mysql -u root -p or in something like mysql workbench by setting the ip: localhost and the port to 33020
Hope this helps.

Specifying ports both for the docker and compose file

I've built a Docker compose file to run database and a nodejs microservice in their own containers.
The database seems to stops working if I don't specify the EXPOSE ports, even though I've specified them in the compose file. Do we have to specify ports in both places?
database/Dockerfile
FROM mysql
ENV MYSQL_DATABASE=test
ENV MYSQL_ROOT_PASSWORD=password
EXPOSE 6603:3306
COPY ./schema.sql /docker-entrypoint-initdb.d/
docker-compose.yml
version: '3'
services:
database:
build:
./database
ports:
- "6603:3306"
image: "test-mysql"
container_name: "test-mysql"
web:
build:
./service
ports:
- "8080:8080"
depends_on:
- database
image: "test-nodejs"
container_name: "test-nodejs"
restart: on-failure
Do I've to specify ports 6603:3306 in both Database/Dockerfile and docker-compose.yml file?
On modern Docker, EXPOSE statements are almost purely documentation. You also can't un-expose a port once it's been exposed in a Dockerfile, and the standard mysql image will already EXPOSE 3306, so you don't need an EXPOSE line in your own Dockerfile.
(In any case a Dockerfile can never specify a specific host port it wants to use, only a container-side port that should be made visible.)
only EXPOSE 3306 - In dockerfile which tells inside container DB running on that port.
ports:
- "6603:3306"
This is perfect which tells outside container you can access DB with 6603 Port.
Yes it's necessary to specify the ports in file without it one will not able to expose the container port and in docker compose if you will not specify port it will not be able to make connection.
But in docker file you can do
EXPOSE 3360

Running Ngrok in a container using docker

[https://github.com/gtriggiano/ngrok-tunnel ] runs ngrok inside a container. Ngrok is required to run in the container to avert security risks. But am facing problems after running the scripts, which generates the url
$ docker pull gtriggiano/ngrok-tunnel
$ docker run -it -e "TARGET_HOST=localhost" -e "TARGET_PORT=3000" -p 4040 gtriggiano/ngrok-tunnel
am running my rails app on localhost:3000
is it my problem or can it be fixed by altering the scripts(inside the repo)?
I couldn't get this working but switched to https://github.com/shkoliar/docker-ngrok and it works brilliantly.
In my case I added it to my docker-compose.yml file:
ngrok:
image: shkoliar/ngrok:latest
ports:
- 4551:4551
links:
- web
environment:
- PARAMS=http -region=eu -authtoken=${NGROK_AUTH_TOKEN} localdev.docker:80
networks:
dev_net:
ipv4_address: 10.5.0.10
And it's started with everything else when I do docker-compose up -d
Then there's a web UI at http://localhost:4551/ for you to see the status, requests, the ngrok URLs, etc.
The Github page does have examples of running it manually from the command line too though, rather than via docker-compose:
Command-line Example The example below assumes that you have running
web server docker container named dev_web_1 with exposed port 80.
docker run --rm -it --link dev_web_1 shkoliar/ngrok ngrok http dev_web_1:80
With command line usage, ngrok session is active until it
won't be terminated by Ctrl+C combination.
No. if you execute -p with single number it's container port - host port is randomly assigned.
Using -p, --publish ip:[hostPort]:containerPort at docker run can specify the the host port with the container port.
as of now the 4040 of container is exposed. Not sure if your service listens by default on it.
To get localhost port execute
docker ps
you'll see the actual port it's not listening on.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1aaaeffe789d gtriggiano/ngrok-tunnel "npm start" About a minute ago Up About a minute 0.0.0.0:32768->4040/tcp wizardly_poincare
here it's listening on localhost:32768
this composer works for me. Note that in the entrypoint command for ngrok you have to reference the other service by name
version: '3'
services:
yourwebserver:
build:
context: ./
dockerfile: ...
target: ...
container_name: yourwebserver
volumes:
- ...
ports:
- ...
extra_hosts:
- 'host.docker.internal:host-gateway'
depends_on:
- ngrok
ngrok:
image: ngrok/ngrok:alpine
environment:
NGROK_AUTHTOKEN: '...'
command: 'http yourwebserver:80'
ports:
- '4040:4040'
expose:
- '4040'
I'm not sure if you have already solved this but when I was getting this error I could only solve it like this:
# docker-compose.yml
networks:
- development
I also needed to expose the 3000 port of my web container because it still wasn't exposed.
# docker.compose.yml
web:
expose:
- "3000"
My container for the server running on development is also under the development network. The only parameters, I believe, you should pass for the container to execute are image, ports, environment with DOMAIN and PORT for the server container, a link, and an expose on your web container:
# docker-compose.yml
ngrok:
image: shkoliar/ngrok
ports:
- 4551:4551
links:
- web
networks:
- development
environment:
- DOMAIN=squad_web
- PORT=3000
Actually to make ngrok work with your docker container you can install it outside of your project just like the manual on their website says. And then add
nginx:
labels:
- "traefik.http.routers.${PROJECT_NAME}_nginx.rule=Host(`${PROJECT_BASE_URL}`, `aaa-abc-xxx-140-177.eu.ngrok.io`)"
This particular example is for docker4drupal docker-compose file and traefik mapped as 80:80

Resources