Docker Community Forums

Share and learn in the Docker community.

Nginx build failure on specific Rails On Docker config... shared volumes problem?

Hi everyone,

I’m getting started on Docker, and for a small Rails application I just achieved a specific setup to improve workflow using Gitlab CI/CD: https://gitlab.com/soykje/rails-on-docker.
The idea is to build the app docker image on release stage, and then save it on Gitlab image registry in order to deploy it using a specific Compose file. And everything seems to work just fine! :slight_smile:

And so I wanted to go further, by adding an Nginx container (first step would be to use it for SSL certificates management). In development mode, it seems to be ok, but if I try to add my container on deployment compose file, it fails build Nginx container, with the following error (on a project base on the linked one):

Service 'nginx' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder917066868/public: no such file or directory

Please do not hesitate to have a look at my public repository! Anyway, here is a few snippets to help you understand:

.gitlab-ci.yml

image: docker
services:
  - docker:dind

cache:
  paths:
    - node_modules

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2
  CONTAINER_LATEST_IMAGE: $CI_REGISTRY_IMAGE:latest
  CONTAINER_STABLE_IMAGE: $CI_REGISTRY_IMAGE:stable

stages:
  - test
  - release
  - deploy

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  - apk add --no-cache py-pip python-dev libffi-dev openssl-dev gcc libc-dev make
  - pip install docker-compose
  - docker-compose --version

test:
  stage: test
  script:
    - docker-compose -f docker-compose.test.yml build --pull
    - docker-compose -f docker-compose.test.yml run --rm app sh -c "./docker/wait_for_services.sh && bundle exec rake db:create spec && yarn jest"
  after_script:
    - docker-compose -f docker-compose.test.yml run --rm app rm -rf tmp/
    - docker-compose -f docker-compose.test.yml down
    - docker volume rm `docker volume ls -qf dangling=true`

release_staging:
  stage: release
  only:
    - staging
  script:
    - docker-compose -f docker-compose.staging.yml build --pull
    - docker tag beweeg_staging $CONTAINER_LATEST_IMAGE
    - docker push $CONTAINER_LATEST_IMAGE

release_production:
  stage: release
  only:
    - production
  script:
    - docker-compose -f docker-compose.production.yml build --pull
    - docker tag beweeg_production $CONTAINER_STABLE_IMAGE
    - docker push $CONTAINER_STABLE_IMAGE

deploy_staging:
  stage: deploy
  only:
    - staging
  environment: production
  before_script:
    - mkdir -p ~/.ssh
    - echo "$STAGING_SERVER_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - which ssh-agent || (apk add openssh-client)
    - eval $(ssh-agent -s)
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H $STAGING_SERVER_IP >> ~/.ssh/known_hosts
  script:
    - scp -rp ./docker-deploy.staging.yml ./nginx/nginx.conf ./nginx/Dockerfile-nginx root@${STAGING_SERVER_IP}:~/
    - ssh root@$STAGING_SERVER_IP "docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY};
      docker pull $CONTAINER_LATEST_IMAGE;
      docker-compose -f docker-deploy.staging.yml stop;
      docker-compose -f docker-deploy.staging.yml rm app --force;
      docker-compose -f docker-deploy.staging.yml up -d"

deploy_production:
  stage: deploy
  only:
    - production
  environment: production
  before_script:
    - mkdir -p ~/.ssh
    - echo "$PRODUCTION_SERVER_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - which ssh-agent || (apk add openssh-client)
    - eval $(ssh-agent -s)
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H $PRODUCTION_SERVER_IP >> ~/.ssh/known_hosts
  script:
    - scp -rp ./docker-deploy.production.yml root@${PRODUCTION_SERVER_IP}:~/
    - ssh root@$PRODUCTION_SERVER_IP "docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY};
      docker pull $CONTAINER_STABLE_IMAGE;
      docker-compose -f docker-deploy.production.yml stop;
      docker-compose -f docker-deploy.production.yml rm app --force;
      docker-compose -f docker-deploy.production.yml up -d"

docker-compose.staging.yml

version: '3.0'
services:
  app:
    image: beweeg_staging
    build:
      context: .
      args:
        - PRECOMPILEASSETS=YES
    environment:
      - RAILS_ENV=production
      - APP_HOST=staging.beweeg.fr
      - APP_PROTOCOL=http
      - [...]
    ports:
      - 3000:3000
    volumes:
      - .:/beweeg

docker-deploy.staging.yml

version: '3'
services:
  db:
    image: postgres:11-alpine
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: postgres

  app:
    image: registry.gitlab.com/soykje/beweeg-ror:latest
    environment:
      - RAILS_ENV=production
      - APP_HOST=staging.beweeg.fr
      - APP_PROTOCOL=http
      - [...]
    links:
      - db
    ports:
      - 3000:3000
    volumes:
      - .:/beweeg

  nginx:
    build:
      context: .
      dockerfile: ./Dockerfile-nginx
    environment:
      - SERVER_NAME=staging.beweeg.fr
    depends_on:
      - app
    ports:
      - 80:80
    volumes:
      - .:/beweeg

I tried several things on volumes declarations, and also tried to clean the .dockerignore file (removing public/ from it). But nothing works… I’m quite lost here, and too much a noob to understand really the origin of my issue, in order to fix it. Is it my whole logic (using Gitlab registry) that I should change, or something else in my docker-deploy.staging.yml?

Anyway, I hope that someone will be able to take some time to help me… I want to learn but I miss the basics I guess so do not hesitate to help me learning more on Docker!

Thx in advance