A
A
Anton Misyagin2021-11-18 00:18:27
Ruby on Rails
Anton Misyagin, 2021-11-18 00:18:27

How to achieve continuous deployment with docker?

Good afternoon! There is a need to roll out a new version of the application without downtime, I can not achieve it.
I use capistrano + docker swarm. I run all docker services on the same server. Capistrano downloads the new version from the repository, relinks the folder with the latest release to current (I forward this folder inside the container). On my first deployment, I download and compile the images using docker compose. When compiling an image with a rail, it downloads and installs the necessary gems. When the images are ready on the server, I run docker stack deploy -c compose.yml myapp.
Inside the rail container is a script to start the application. What it does:
1. bundle install (in case the Gemfile has been updated, it updates the gems not in the image, but in the container)
2. runs migrations
3. precompiles the assets
4. starts the rail

First deploy goes well. Further, when I roll out the next version, the images themselves remain unchanged (I don’t rebuild them anymore), the current folder changes (the public folder with assets is empty here), I run docker stack deploy -c compose.yml myapp - I see that the services have been updated.
What I get - I go to the site - all the styles have disappeared there, I don't see the application restart in the logs. Those. as I understand it, since the docker sees that the images have not been updated, then there is no need to restart the application, but I need it to restart and complete those 4 points so that new styles and scripts appear, missing gems are installed. Plus, I want to get a seamless deployment - i.e. The old service should be running while the updated one starts. What am I doing wrong?

version: "3.7"
services:
  pg:
    image: postgres:11.5-alpine
    env_file:
      - ./.env
    environment:
      - POSTGRES_USER=${DATABASE_USER}
      - POSTGRES_PASSWORD=${DATABASE_PASS}
      - POSTGRES_DB=${DATABASE_NAME}
    ports:
      - 5432:5432
    volumes:
      - /var/www/myapp/shared/db/pg/etc:/etc/postgresql
      - /var/www/myapp/shared/log/pg:/var/log/postgresql
      - /var/www/myapp/shared/db/pg/data:/var/lib/postgresql/data
      - /var/www/myapp/shared/db/pg/backups:/backups
      - /tmp:/tmp
    deploy:
      placement:
        constraints: [node.role == manager]
      replicas: 1
  redis:
    image: redis:5.0.3-alpine
    volumes:
      - /var/www/myapp/shared/db/redis:/data
      - /tmp:/tmp
  rails:
    image: instajet/rails:6.1
    build:
      context: .
      dockerfile: config/docker/rails/DockerFile
    environment:
      - BUNDLE_PATH=/bundle
      - RAILS_ENV=production
    depends_on:
      - pg
      - redis
    volumes:
      - /var/www/myapp/current:/instajet:Z
      - /var/www/myapp/shared/log/rails:/instajet/log
      - /var/www/myapp/shared/log/puma:/instajet/log/puma
      - /tmp:/tmp
    command: startup.sh
    deploy:
      placement:
        constraints: [ node.role == manager ]
      replicas: 1
  nginx:
    image: nginx:1.17.6
    volumes:
      - /var/www/myapp/current/public:/public
      - /var/www/myapp/current/config/docker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /var/www/myapp/shared/log/nginx:/log
      - /tmp:/tmp
    depends_on:
      - rails
    ports:
      - '80:80'
    deploy:
      placement:
        constraints: [ node.role == manager ]
      replicas: 1

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question