When building a Socket-based server using PHP, socket_accept() is a key function to implement the server-side connection to the client. However, when running such programs in a Docker container, network configuration may cause socket_accept() to not work properly, such as connection timeout, inability to listen, or client connection failure. This article will provide detailed instructions on how to configure the network in a Docker environment so that PHP's Socket Server can run smoothly.
Socket services in PHP are generally implemented through the following steps:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
$client = socket_accept($socket);
There is basically no problem running the above code in a local development environment, but after deploying it to a Docker container, you often encounter socket_accept() blocking and the client cannot connect. Most of the problems stem from Docker's network configuration.
If the port listened to by the server is not mapped to the host when starting the container, the client will naturally be unable to connect. For example:
docker run -d php-server
The above command does not specify a port mapping, and the 8080 port listened to by the PHP server is not visible to the outside world.
If you bind Socket to 127.0.0.1 , only programs in the container can access this service. To allow access to the host or other container, you should bind to 0.0.0.0 .
When communication is required between multiple containers, they must be connected to the same Docker network, otherwise they are invisible to each other.
When starting the container, use the -p parameter to map the container port to the host:
docker run -d -p 8080:8080 php-server
This maps the container's port 8080 to the same port on the host, and the client can access it via http://m66.net:8080/ .
In PHP Socket program, make sure to use 0.0.0.0 to bind the address:
socket_bind($socket, '0.0.0.0', 8080);
This allows you to listen to all available network interfaces, including the internal address of the container and the ports mapped by the host.
If multiple containers (such as a PHP Socket service container and a client container) are required to communicate, it is recommended to create a custom network:
docker network create my-network
Then use that network to start the container:
docker run -d --name php-server --network my-network php-server
docker run -it --network my-network php-client
At this time, php-client can directly connect to the service through the container name php-server , for example:
socket_connect($client, 'php-server', 8080);
When using Docker Compose, you can explicitly specify the network in docker-compose.yml :
version: '3'
services:
php-server:
build: .
ports:
- "8080:8080"
networks:
- app-net
php-client:
build: ./client
networks:
- app-net
networks:
app-net:
driver: bridge
The client code can still access the service through php-server:8080 .
Use netstat -tlnp or ss -tlnp to see if the port is listening;
Use telnet m66.net 8080 or nc -zv m66.net 8080 to test port connectivity;
Check Docker logs and PHP error logs to check whether socket creation and binding are incorrect.
When socket_accept() is used in Docker containers, the main problem is often not the function itself, but the reason for improper network configuration. Ensuring that the listening address is 0.0.0.0 , the container port is correctly mapped, and the network connection between containers is the key to achieving stable Socket services. Combining the Docker network mode and Docker Compose service discovery mechanism can greatly reduce debugging difficulty and improve deployment efficiency.
With reasonable configuration, you can build stable and efficient PHP Socket services in Docker containers, providing powerful support for inter-system communication.