Home > other >  Does Sidekiq running multiple times when we replicate the Ruby on Rails container?
Does Sidekiq running multiple times when we replicate the Ruby on Rails container?

Time:09-22

I have a Ruby on Rails container with Sidekiq in it.

I have a schedule/cron job in the application. As We know, schedule jobs are registered when the application boots.

If I assume that there will be many users one day and I will create multiple container instances for the application, will this cause Sidekiq to execute on multiple containers?

If the answer is yes (execute multiple jobs in each container), how do I make this job only executed by one container?

version: '3.8'
services:

  thedatabase:
    image: postgres:12
    volumes:
      - ./database:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: theuser
      POSTGRES_PASSWORD: thepass
    ports: 
      - '5432:5432'
    networks: 
      - excnetwork

  theapi:
    build: 
      context: ./dex-api
      dockerfile: Dockerfile
    volumes:
      - ./dex-api:/web
    env_file: 
      - ./dex-api/.env
    ports:
      - "8081:3000"
    depends_on:
      - thedatabase
    networks: 
      - excnetwork

  redis:
    image: redis
    command: 'redis-server --requirepass "yourpassword"'
    volumes:
      - ./redis:/var/lib/redis/data
    ports:
      - '6379:6379'
    networks: 
      - excnetwork

volumes:
  database:
  dex-api:
  redis:
  
networks: 
  excnetwork:
    driver: bridge

CodePudding user response:

[If I] create multiple container instances for the application, will this cause Sidekiq to execute on multiple containers?

Yes; but Sidekiq is clever enough to only run each job once, even if there are multiple workers. Similarly, if you're using the paid version of Sidekiq and its periodic jobs, they shouldn't be duplicated since "the leader process enqueues cron jobs" (doc link).

You don't describe how you're starting Rails and Sidekiq, but your Compose setup only has one application container. You might find it useful to split these into two, which will make it easier to scale the components and protect the Web application if a scheduled job has a problem. In your Dockerfile, start one or the other (I'd default to the Rails server)

ENTRYPOINT ["bundle", "exec"]
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]

In your Compose file you can start multiple containers from the same image, overriding the command: in some of them if required.

services:
  theapi:
    build: ./dex-api
    env_file:
      - ./dex-api/.env
    ports:
      - "8081:3000"
    depends_on:
      - thedatabase
      - redis

  theworker:
    build: ./dex-api  # <-- same as `theapi`
    command: sidekiq  # <-- override Dockerfile `CMD`
    env_file:
      - ./dex-api/.env
    depends_on:
      - thedatabase
      - redis

CodePudding user response:

Whilst there's no single answer that solves it all you can use tried and tested means. One of them is to put Sidekiq in a sidecar. You definitely need Sidekiq to be run as a single, independent instance.

There are other patterns for a multi-container solution such as ambassador and adapter but, a sidecar seems to be the most appropriate option in this instance.

Read more here:

  • Related