Setting up Docker Compose

    Let's see step by step how to write a production grade compose file. Here we will use .env file to store secrets and password and use that file to inject value.

    Step 1: Create a .env file and docker-compose.yml under root directory of the project. Here we use a .env file to store sensitive information such as secrets and passwords. These values are then injected into the application at runtime. Using a .env file is optional, you could directly write these values in the configuration if needed. However, for security and maintainability, it is considered a best practice to keep such sensitive data in an environment file. Therefore, in this guide we will continue using the .env file to manage these values.

    Project folder structure with .env and compose file

     

    Step 2: Before building image create a file which will be used for docker environment. This will contain the properties of the application, whose values will be injected while running in the container.

    Application properties file for docker profile

     

    In this example, we will use both a .properties file and a .yml file. The .properties file will contain the default application configuration, while the Docker-specific settings will be placed in the .yml file. When running the application through Docker Compose, we will activate the Docker configuration by setting the profile using the environment variable: SPRING_PROFILES_ACTIVE= this allows the application to override the default properties and load the configuration for the required profile—in this case, the docker profile.

    #application.properties file spring.application.name=airBnbApp #DB Configuration spring.datasource.url=jdbc:postgresql://localhost:5432/${DB_NAME} spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.datasource.username=${DB_USER} spring.datasource.password=${DB_PASSWORD} admin.email=${ADMIN_EMAIL} admin.password=${ADMIN_PASSWORD} server.servlet.context-path=/api/v1 #API to check the holiday date for dynamic pricing #calendarific.api.key=dfX4lzjHKwBxsQO9Uk5gWhlZz04SlO4C #calendarific.api.url=https://calendarific.com/api/v2/holidays jwt.secretKey=${JWT_TOKEN} frontend.url=${FRONTEND_URL} stripe.secret.key=${STRIPE_API_KEY} stripe.webhook.secret=${STRIPE_WEBHOOK_SECRET} # swagger-ui custom path #http://localhost:8080/api/v1/swagger-ui/index.html#/ springdoc.swagger-ui.path=/swagger-ui.html #Cron job app.scheduling.cron.price=${PRICE_TRIGGER_DURATION} app.scheduling.cron.booking=${BOOKING_TRIGGER_DURATION}
    #application-docker.yml for docker profile spring: #DB Configuration datasource: url: jdbc:postgresql://${DB_SERVER}:5432/${DB_NAME} username: ${DB_USERNAME} password: ${DB_PASSWORD}

    Step 3: Content of .env file

    #reference to the variables in docker-compose.yml either via environment: or env_file:. # Stripe STRIPE_API_KEY= STRIPE_WEBHOOK_SECRET= #JWT JWT_TOKEN=3e5c4a8d041688cc0af2da402d0456fc9193fd74af41e19fa934c2e1992ba4ca # Spring Boot / App SPRING_PROFILES_ACTIVE=docker SERVER_PORT=8080 PRICE_TRIGGER_DURATION=0 0 * * * * #TRIGGER_DURATION=0 0 * * * * BOOKING_TRIGGER_DURATION=0 */15 * * * * FRONTEND_URL=http://localhost:5173 # Database DB_HOST=airbnb-db DB_PORT=5432 DB_NAME=HotelMgmtDB DB_USER=postgres DB_PASSWORD=root123 #PG-ADMIN PG_ADMIN_USER=admin@admin.com PG_ADMIN_PASSWORD=Root@123 PG_ADMIN_PORT=5050 #Super User ADMIN_EMAIL=admin@airbnb.com ADMIN_PASSWORD=Gr@v1ty

    Step 4: Content of compose file

    services: airbnb-app: image: smrutiranjanm/airbnbapp:latest container_name: airbnb-app env_file: - .env environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE} DB_SERVER: ${DB_HOST} DB_NAME: ${DB_NAME} DB_USERNAME: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} ports: - "${SERVER_PORT}:8080" depends_on: - airbnb-db networks: - airbnb-network stripe-gateway: image: stripe/stripe-cli:latest container_name: stripe-cli env_file: - .env command: > listen --forward-to http://airbnb-app:8080/api/v1/webhook/payment environment: STRIPE_API_KEY: ${STRIPE_API_KEY} networks: - airbnb-network airbnb-db: image: postgres:16-alpine container_name: airbnb-db env_file: - .env environment: POSTGRES_DB: ${DB_NAME} POSTGRES_USER: ${DB_USER} POSTGRES_PASSWORD: ${DB_PASSWORD} ports: - "${DB_PORT}:5432" # Expose as localhost:5432/${DB_PORT} networks: - airbnb-network volumes: - pgdata_Hotel:/var/lib/postgresql/data healthcheck: test: [ "CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}" ] interval: 10s timeout: 5s retries: 5 pg-admin: image: dpage/pgadmin4:latest container_name: pgadmin env_file: - .env networks: - airbnb-network environment: PGADMIN_DEFAULT_EMAIL: ${PG_ADMIN_USER} PGADMIN_DEFAULT_PASSWORD: ${PG_ADMIN_PASSWORD} ports: - "${PG_ADMIN_PORT}:80" # Host: localhost:5050 --> container’s 80 volumes: - pgadmin_data:/var/lib/pgadmin volumes: pgadmin_data: pgdata_Hotel: networks: airbnb-network:

    Conclusion#

    Using Docker Compose with a .env file provides a clean and production-ready way to manage multi-container applications. By separating configuration, secrets, and service definitions, teams can maintain secure, reusable, and easily scalable deployments while keeping environment-specific settings outside the application code.

    Want to Master Spring Boot and Land Your Dream Job?

    Struggling with coding interviews? Learn Data Structures & Algorithms (DSA) with our expert-led course. Build strong problem-solving skills, write optimized code, and crack top tech interviews with ease

    Learn more

    Last updated on Mar 16, 2026

    Was it helpful?

    Subscribe to our newsletter

    Read articles from Coding Shuttle directly inside your inbox. Subscribe to the newsletter, and don't miss out.