Networking between multiple Docker projects
Docker for local development is a game-changer! It lets you containerize your application and run it pretty much anywhere—even on your “Windows Machine” 🙈! Plus, Docker Compose takes things up a notch by handling all the heavy lifting, like setting up networks, running your images, and connecting everything, so you can focus on coding and let Docker do the rest. It’s like having your little helper making life that much easier!
Let’s check out how your Docker Compose file might look! 🚀
services:
app:
image: golang:latest
container_name: app1_app
ports:
- "80:80"
volumes:
- .:/app
working_dir: /app
command: go run main.go
networks:
- app1
networks:
app1:
name: app1
Our example application
package main
import (
"encoding/json"
"log"
"net/http"
)
// Response structure for JSON output
type Response struct {
Message string `json:"message"`
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := Response{Message: "ping"}
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, "Failed to encode JSON response", http.StatusInternalServerError)
return
}
})
log.Fatalln(http.ListenAndServe(":80", nil))
}
Just run docker-compose up -d
, and voilà—your project is up and running, almost like it’s in the wild on a single server! How cool is that? What works on my machine should work on yours too!
What's even better is that we can run multiple projects at the same time! Let’s take a peek at what that Docker Compose file might look like!
And our application
package main
import (
"encoding/json"
"log"
"net/http"
)
// Response structure for JSON output
type Response struct {
Message string `json:"message"`
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := Response{Message: "pong"}
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, "Failed to encode JSON response", http.StatusInternalServerError)
return
}
})
log.Fatalln(http.ListenAndServe(":80", nil))
}
You might notice that the ports are different—that’s perfectly normal with Docker since each port needs to be unique. The great news is, now we’ve got multiple projects running simultaneously!
What if we want our projects to talk to each other? In this example, since they're separate projects, bundling the code into a single repo might not be ideal. No worries, though—Docker has a cool feature that lets you connect containers across different networks. This way, your projects can communicate seamlessly even if they're in separate Docker setups.
Next, run the following command. This only needs to be done once:
docker network create app_bridge
Next, update the two Docker Compose files to look like the examples below:
services:
app:
image: golang:latest
container_name: app1_app
ports:
- "80:80"
volumes:
- .:/app
working_dir: /app
command: go run main.go
networks:
- app1
- app_bridge
networks:
app1:
name: app1
app_bridge:
external: true
services:
app:
image: golang:latest
container_name: app2_app
ports:
- "8080:80"
volumes:
- .:/app
working_dir: /app
command: go run main.go
networks:
- app2
- app_bridge
networks:
app2:
name: app2
app_bridge:
external: true
Now, when we boot up our projects and enter the containers, you can communicate between the apps using the `container_name`. For example, in the `app1_app` container, you can run:
curl http://app2_app
{"message":"pong"}
To make things easier, I’ve set up a repo you can play with: https://github.com/mtdevs28080617/docker-networking-multiple-project-example. Have fun experimenting!