0

I was wondering if docker-compose has the ability to either start a service and down the service within the docker-compose file, or to take an existing service and restart it with more resources

Problem

The application needs to be started with one volume to initiate some stuff and then it can be started again with the other volumes and resources to be able to make a connection to the db.

This is just an example with a sonarqube docker-compose file, IT'S NOT THE REAL COMPOSE FILE

In order for the application to work with a database it needs to be started with one volume (sonar-app-extension-vol) to initiate some stuff.

At the same time, the database is going to be started.

As soon as the db is up and healthy the application can be started with all volumes, networks, ports, env vars, etc.

version: '3.8'
    
services:
  app:
    hostname: 'sonarqube'
    image: 'sonarqube:10.0.0-community'
    container_name: 'sonarqube-app'
    restart: 'unless-stopped'
    environment:
      - SONAR_JDBC_URL=jdbc:postgresql://sonar-db:5432/sonarqube
      - SONAR_JDBC_USERNAME=sonar-db-user
      - SONAR_JDBC_PASSWORD=sonar-db-password
    volumes:
      - 'sonar-app-conf-vol:/opt/sonarqube/conf'
      - 'sonar-app-data-vol:/opt/sonarqube/data'
      - 'sonar-app-extension-vol:/opt/sonarqube/extensions'
      - 'sonar-app-bundled-plugin-vol:/opt/sonarqube/lib/bundled-plugins'
    networks:
      - 'sonar-network'
      - 'nginx-network'
    ports:
      - '9000:9000'
    depends_on:
      db:
        condition: service_healthy

  # This service is only for initializing in order for the 
  # sonarqube to work properly with the postgresql db
  init:
    image: 'sonarqube:10.0.0-community'
    container_name: 'sonarqube-init'
    restart: 'unless-stopped'
    volumes:
      - 'sonar-app-extension-vol:/opt/sonarqube/extensions'
    networks:
      - 'sonar-network'
      - 'nginx-network'

  db:
    hostname: 'postgresql'
    image: 'postgres:15'
    container_name: 'sonarqube-db'
    restart: 'unless-stopped'
    environment:
      - POSTGRES_USER=sonar-db-user
      - POSTGRES_PASSWORD=sonar-db-password
      - POSTGRES_DB=sonarqube
      #- POSTGRES_HOST_AUTH_METHOD=trust
    volumes:
      - 'sonar-db-postgresql-vol:/var/lib/postgresql'
      - 'sonar-db-postgresql-data-vol:/var/lib/postgresql/data'
    networks:
      - 'sonar-network'
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  sonar-network:
    name: 'sonar-network'
  nginx-network:
    name: 'nginx-network'

volumes:
  sonar-app-conf-vol:
    name: 'sonar-app-conf-vol'
  sonar-app-data-vol:
    name: 'sonar-app-data-vol'
  sonar-app-extension-vol:
    name: 'sonar-app-extension-vol'
  sonar-app-bundled-plugin-vol:
    name: 'sonar-app-bundled-plugin-vol'
  sonar-db-postgresql-vol:
    name: 'sonar-db-postgresql-vol'
  sonar-db-postgresql-data-vol:
    name: 'sonar-db-postgresql-data-vol'

Tried

Inside the official documentation, I could not find something like this but I'm pretty sure there must be a workaround.

I tried to create an init service to initialize my volume (sonar-app-extension-vol) to connect to the db and it is working perfectly fine. But in the end, I have 3 containers up and running which is not the ideal case in terms of host resource management.

Expectation

The goal for me is that the docker-compose file produces two containers at the end and not three so I can use it for unattended installations.

David Maze
  • 130,717
  • 29
  • 175
  • 215
Reginald
  • 41
  • 4
  • `But at the end I have 3 container up` so stop one. Stop the init one. And don't `restart: 'unless-stopped'` restart it, just let it die. – KamilCuk Apr 11 '23 at 08:55
  • @KamilCuk sure I could stop one container after the docker-compose command but I want to use this docker-compose file for unattended installations. How should the container die on its own? – Reginald Apr 11 '23 at 08:59
  • The container should `exit` once init is complete. Does init, dies. See https://airflow.apache.org/docs/apache-airflow/2.5.3/docker-compose.yaml airflow-init: for example. – KamilCuk Apr 11 '23 at 08:59
  • @KamilCuk You mean I could add a command: sh -c 'exit 1' and then the container would stop once its up? – Reginald Apr 11 '23 at 09:03
  • You can add a command `sh -c "echo do the initilaization here"` and the container will stop once the shell is done. I do not understand. What _exactly_ are you initializing? – KamilCuk Apr 11 '23 at 09:06
  • @KamilCuk Unfortunately the initialization cannot be done by me via any command. I have to run the service with the volume for the first time to initialize. – Reginald Apr 11 '23 at 09:15
  • I fail to understand. So stop the service once it is initialized. `sh -c 'something that initailizes & while is not initialized; do sleep 1; done'` – KamilCuk Apr 11 '23 at 09:22
  • @KamilCuk Sorry maybe I need to explain it well enough. I have two services, an app, and a db. The app can work with an integrated db and with an external one. In order to work with an external db the app needs to be started with the integrated one first and a specific volume and then it can be used with an external db. It is not possible to start directly with an external db. Unfortunately, I have no access to the source code to make any changes or see what he is exactly doing. I could only see the end result inside the volume- only some configurations. but don't want to copy them over and .. – Reginald Apr 11 '23 at 09:37
  • You could make the application also `depends_on: { init: { condition: service_completed_successfully } }`, in combination with @KamilCuk's suggestion to have the init container not restart. Also see [Does docker-compose support init container?](https://stackoverflow.com/questions/70322031/does-docker-compose-support-init-container). (I think the init container will still get re-run on every `docker-compose up` invocation, so make sure it's safe to re-run in this context.) – David Maze Apr 11 '23 at 10:26
  • @DavidMaze For now, I leave it that way: app depends on db => db depends on init => init has a shell command with sleep (actually not necessary but just to be safe) and exit with 0 Hope that some docker-compose hyper genius finds this post :-D – Reginald Apr 11 '23 at 12:47

0 Answers0