Docker新手咨询:Java Socket音乐服务器双容器的Docker Compose文件配置问题
Hey there! Let's get your Docker Compose setup sorted out properly—you're close, but there are a few syntax and configuration issues to fix. Let's break this down step by step.
First, Let's Fix Your Current Compose File's Issues
Your existing YAML has several problems that will prevent it from working:
- Syntax errors: Missing spaces after colons (e.g.,
version:'3'should beversion: '3'), invalid port formatting (-25000:25000needs a space and quotes like- "25000:25000"), and usingnetwork(singular) instead ofnetworks(plural). - No build logic: You're using the raw
java:8image directly, but this won't include your compiledClient.java/Server.javafiles like your manual Dockerfiles did. - Unnecessary port mappings: Container-to-container communication doesn't require exposing ports to the host machine—you only need ports mapped if you want external devices to access the server.
- Missing interactive mode: Your manual
docker runuses-itto keep the terminal alive; Compose needs equivalent settings for your client container.
Correct Docker Compose Configuration
Assuming your project structure looks like this (matching your separate Dockerfiles):
your-project/ ├── server/ │ ├── Dockerfile │ └── Server.java ├── client/ │ ├── Dockerfile │ └── Client.java └── docker-compose.yml
Here's the fixed Compose file that mirrors your manual setup:
version: '3.8' # Use a modern, well-supported version services: server: build: ./server # Tells Compose to build using the Dockerfile in the server directory environment: - SERVER_HOST_ENV=server # Matches your manual env var setup networks: - client_server_network # No ports needed here unless you want external access to the server client: build: ./client # Builds from the client directory's Dockerfile environment: - SERVER_HOST_ENV=server # Make sure your Client.java reads this var to connect! networks: - client_server_network stdin_open: true # Equivalent to `-i` in docker run tty: true # Equivalent to `-t` in docker run—keeps the client terminal active # Define the shared custom network (matches your manual network name) networks: client_server_network: name: client_server_network driver: bridge # Default network driver, explicitly set for clarity
Key Details Explained
- Shared Network: The top-level
networksblock creates (or reuses, if it already exists) yourclient_server_network. Both services are attached to this network, so they can communicate using their service names as hostnames—your client can connect toserver:25000directly. - Build Configuration: Instead of referencing pre-built images,
build: ./serverandbuild: ./clienttell Compose to use your existing Dockerfiles to build the images automatically when you rundocker-compose up --build. - Interactive Mode:
stdin_open: trueandtty: trueensure your client container doesn't immediately exit, just like the-itflag in your manualdocker runcommand.
How to Run It
Just run this command from your project directory:
docker-compose up --build
This will build both images (if they don't exist), create the network (if it doesn't already exist), and start both containers.
Quick Check for Your Java Code
Make sure your Client.java is reading the SERVER_HOST_ENV environment variable to determine the server's hostname. For example:
String serverHost = System.getenv("SERVER_HOST_ENV"); Socket socket = new Socket(serverHost, 25000);
内容的提问来源于stack exchange,提问作者william12

