Docker Compose Overview
Docker Compose is a powerful tool designed to define and manage multi-container Docker applications. When dealing with complex setups involving multiple services like Spring Boot applications, Redis, and MySQL, managing each container individually becomes cumbersome. Instead of manually configuring IP addresses and connecting separate containers, Docker Compose allows you to orchestrate all services through a single configuration file.
The tool enables developers to define all application services in a YAML configuration file, then use simple commands to start, stop, or restart the entire stack along with their dependencies.
Implementation Workflow
Working with Docker Compose typically involves three key steps:
- Create a Dockerfile to define your application's runtime environment
- Define all required services in a docker-compose.yml file
- Execute docker-compose up to launch the complete application stack
Project Configuration
For Maven-based projects, ensure your pom.xml includes proper artifact naming and the Docker Maven plugin configuration:
<groupId>com.example</groupId>
<artifactId>compose-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
Your Dockerfile should be placed in src/main/docker with the following content:
FROM openjdk:8-jdk-alpine
EXPOSE 8080
VOLUME /tmp
ADD compose-demo-1.0.0.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Docker Compose Configuration
Create a docker-compose.yml file in your project root directory:
version: "3"
services:
cache:
image: redis:latest
restart: always
ports:
- "6380:6379"
volumes:
- ./redis-config.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
database:
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: "password123"
MYSQL_USER: 'admin'
MYSQL_PASS: 'password123'
ports:
- "3307:3306"
volumes:
- "./data:/var/lib/mysql"
- "./config/db.cnf:/etc/my.cnf"
application:
image: example/compose-demo
container_name: compose-app
ports:
- 8080:8080
volumes:
- /etc/localtime:/etc/localtime
- ./logs:/var/logs
Common Configuration Issues
Several pitfalls can occur during setup:
Port Mapping Confusion: In the port mapping "6380:6379", 6380 is the host port while 6379 is the container port. Applications running on the host machine connnect via 6380, while inter-container communication uses 6379.
Volume Mount Permissions: Incorrect file paths can cause mount errors. Ensure directories exist and have proper permissions:
ERROR: for service_name Cannot create container: Mounts denied
MySQL Connection Issues: MySQL 8.0 may require additional connection parameters:
jdbc:mysql://database:3306/sample?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
Network Connectivity Problems
Even when containers appear to be running correctly, connection issues may persist:
io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: /127.0.0.1:6379
This occurs because containers cannot communicate using localhost (127.0.0.1). Use service names defined in docker-compose.yml instead:
spring:
datasource:
url: jdbc:mysql://database:3306/sample?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
redis:
host: cache
port: 6379
Image Name Verification
Ensure image names in your docker-compose.yml match exactly with built images. Check available images with:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
example/compose-demo latest 1429aa26790a 54 min ago 137MB
redis latest 40c68ed3a4d2 10 days ago 113MB
mysql latest e1d7dc9731da 14 months ago 544MB
Launching the Application
Start your multi-container application with:
sudo docker-compose up
After successful startup, initialize your database schema:
DROP DATABASE IF EXISTS sample;
CREATE DATABASE sample;
USE sample;
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(255) DEFAULT '',
age INT DEFAULT 0
);
INSERT INTO users VALUES (1, 'John Doe', 25);
INSERT INTO users VALUES (2, 'Jane Smith', 30);