How to run sidekiq in a separate different docker container apart from application. We are using whenever for the sidekiq jobs, but the jobs are getting triggered in all web containers
version: '3.8' services: foo-db: image: postgres:$POSTGRES_VERSION container_name: foo-db-container restart: unless-stopped env_file: .env volumes: - /var/lib/postgresql/data networks: - $FOO_NETWORK foo-redis: image: redis:$REDIS_VERSION container_name: foo-redis-container init: true sysctls: net.core.somaxconn: 511 env_file: .env volumes: - /var/lib/redis/data networks: - $FOO_NETWORK foo-sidekiq: depends_on: - foo-db - foo-redis build: ./foo-ui command: bundle exec sidekiq env_file: .env volumes: - /var/lib/redis/data networks: - $FOO_NETWORK foo-service: build: foo-service # image: gcr.io/foo/foo-service:latest container_name: foo-service-container ports: - "$FOO_SERVICE_PORT:$FOO_SERVICE_PORT" env_file: .env networks: - $FOO_NETWORK foo-ui: build: ./foo-ui # image: gcr.io/foo/foo-ui:latest container_name: foo-ui-container depends_on: - foo-db - foo-redis - foo-sidekiq - foo-service ports: - "$FOO_UI_PORT:$FOO_UI_PORT" env_file: .env networks: - $FOO_NETWORK networks: foo-network:
Here's the list of things you should setup:
You should have a different image for your sidekiq and web application. That way, you can ensure whenever -w
will be called only in the background (sidekiq) image, and not inside the web image.
Example image: https://gist.github.com/cesartalves/69f6440b97c89e9dee6cfffbdf9b7790 (adapt to your needs)
Important points:
apt-get update && apt-get install -y cron
- install crontabbundle exec whenever -w
- running wheneverCMD [ "bundle", "exec", "sidekiq"
- run sidekiq as main processENTRYPOINT [ "./docker-entrypoint.sh" ]
- run cron in the background and other aditional commands you might need to doTo check if crontab is running, you can do one of the following after your container is running https://askubuntu.com/questions/85558/verify-if-crontab-works
About the "horizontal scalling", this should be done automatically if you have multiple sidekiq instances consuming the same redis pool - the more sidekiq instances, the faster your jobs run.
If by "horizontal" you mean being able to set up on which servers your crons will run, you could have multiple schedule.rb files, and each of your background containers should deploy only one of them to the crontab, by doing whenever -w -f config/schedule_specific_cron1.rb
. You could pass the file as an environment variable.
If all the application containers use the same database, have only one of them execute migrations. This will speed up your container starting and avoid any locking errors. I suggesting doing that in the "web" image since you will have multiple sidekiq container instances.
All your images will use the same gems. Therefore, you want to create a volume to store them, to speed up their building process:
foo-sidekiq:
depends_on:
- foo-db
- foo-redis
build: ./foo-ui
command: bundle exec sidekiq
env_file: .env
volumes:
- /var/lib/redis/data
- gem_cache:/gems
networks:
- $FOO_NETWORK
volumes:
gem_cache:
Inside your image:
ENV BUNDLE_PATH /gems
Which container orchestration system are you using?
Dependecies should be run on this order:
Ideally, you should be using something which allows you to specify how many sidekiq container instances you want.
--
I think that covers the gist. Let me know if you need more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With