DEV Community

Dmitry Daw
Dmitry Daw

Posted on • Edited on

How to cache Kamal(MRSK) deployments in CI

Caching is a key strategy in optimizing Docker deployments. But because CI don't saves previous docker layers, and, unfortunalety, MRSK doesn't have options like --cache-to, MRSK(now Kamal) rebuilds each Docker container from scratch, leading to a slower deploys.

There are two methods to implement caching with MRSK in GitHub Actions: pulling the Docker image before deployment and using the --skip_push option with the build command.

Method 1: Pull the Docker Image before Deployment

This approach is suitable for simple Dockerfiles.
First, the Docker image is pulled from the registry, then the MRSK deploy command is run. By pulling the Docker image first, MRSK can use the layers from the previously built image, reducing the need for a complete rebuild.

- name: Login to DockerHub
  uses: docker/login-action@v2
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Pull Docker Image
  run: docker pull ${{ secrets.DOCKERHUB_USERNAME }}/your-image-name || true

- name: Deploy with MRSK
  run: mrsk deploy
Enter fullscreen mode Exit fullscreen mode

In this code snippet, the docker pull command pulls the Docker image from the registry. The || true part ensures that the workflow doesn't fail if the image doesn't exist yet (for instance, during the first run).

But the problem with this method is that it's not working for workflows where only final Docker image is pushed.

Method 2: Use the --skip_push Option and Build Command before Deployment

This method is for complex workflows, for example for Dockerfiles which have separated final and builder images. Because in such Dockerfiles we push only final image, we can't get builder cache from pulling latest image.

The --skip_push option in MRSK not only skips the push, but also the Docker build process. Therefore, we can perform the build manually and then use MRSK for deployment only.

- name: MRSK envify
  env:
    VERSION: ${{ github.sha }} # set version to ensure we'll build the same version
  run: 'mrsk envify -v'

- name: Set up Docker Buildx.
  uses: docker/setup-buildx-action@v2

- name: Build and push
  uses: docker/build-push-action@v4
  with:
    context: .
    push: true
    tags: ${{ secrets.DOCKERHUB_USERNAME }}/your-image-name:${{ github.sha }},${{ secrets.DOCKERHUB_USERNAME }}/your-image-name:latest
    cache-from: type=gha # https://docs.docker.com/build/cache/backends/gha/
    cache-to: type=gha,mode=max

- name: MRSK deploy
  run: 'mrsk deploy -vvvv --skip_push'
Enter fullscreen mode Exit fullscreen mode

In that way we could fully embrace CI cache and speedup deployments.

Links

Top comments (0)