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!
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