【问题标题】:Rails + Docker + Nginx: unavailable assets?Rails + Docker + Nginx:不可用的资产?
【发布时间】:2019-07-26 21:34:07
【问题描述】:

我目前正在尝试在 dockerized Rails 应用程序上设置 Nginx。构建没问题,但由于某种原因不提供资产(404)。我在网上搜索,但没有成功......我开始使用 Docker,我也觉得卡在这里:(

这里有一些文件,如果有人知道我缺少什么...我以这篇文章为灵感:https://blog.wildcat.io/2019/06/rails-with-docker-part-1/

.gitlab-ci.yml

image: docker:18-git
services:
  - docker:18-dind

cache:
  paths:
    - node_modules

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2
  APP_LATEST_IMAGE: $CI_REGISTRY_IMAGE/app:latest
  APP_STABLE_IMAGE: $CI_REGISTRY_IMAGE/app:stable
  NGINX_LATEST_IMAGE: $CI_REGISTRY_IMAGE/nginx:latest
  NGINX_STABLE_IMAGE: $CI_REGISTRY_IMAGE/nginx: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_app_latest:
  stage: release
  only:
    - staging
  script:
    - docker-compose -f docker-compose.staging.yml build --pull
    - docker tag beweeg_staging $APP_LATEST_IMAGE
    - docker push $APP_LATEST_IMAGE

release_nginx_latest:
  stage: release
  only:
    - staging
  script:
    - cd nginx
    - docker pull $NGINX_LATEST_IMAGE || echo "No pre-built image found."
    - docker build --cache-from $NGINX_LATEST_IMAGE -t $NGINX_LATEST_IMAGE . || docker build -t $NGINX_LATEST_IMAGE . # Use cache for building if possible
    - docker push $NGINX_LATEST_IMAGE

deploy_latest:
  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 root@${STAGING_SERVER_IP}:~/
    - ssh root@$STAGING_SERVER_IP "docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY};
      docker pull $APP_LATEST_IMAGE;
      docker pull $NGINX_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"

docker-compose.staging.yml

version: '3.0'
services:
  app:
    image: beweeg_staging
    build:
      context: .
      args:
        - PRECOMPILEASSETS=YES
    environment:
      - RAILS_ENV=production
      - SECRET_KEY_BASE=foo
      - APP_HOST=<mydomain.com>
    ports:
      - 3000:3000

docker-deploy.staging.yml

version: '3'
services:
  db:
    image: postgres:11-alpine
    ports:
      - 5432:5432
    networks:
      - internal
    volumes:
      - /var/www/beweeg_app/pg_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgres

  app:
    image: registry.gitlab.com/soykje/beweeg-ror/app:latest
    environment:
      - RAILS_ENV=production
      - SECRET_KEY_BASE=foo
      - APP_HOST=<mydomain.com>
    ports:
      - 3000:3000
    networks:
      - internal
    links:
      - db
    volumes:
      - /var/www/beweeg_app/app/log:/var/www/app/log
      - /var/www/beweeg_app/app/tmp:/var/www/app/tmp
      - /var/www/beweeg_app/app/tmp/pids:/var/www/app/tmp/pids
      - /var/www/beweeg_app/app/storage:/var/www/app/storage
      - rails_public:/var/www/app/public

  nginx:
    image: registry.gitlab.com/soykje/beweeg-ror/nginx:latest
    depends_on:
      - app
    ports:
      - 80:80
    networks:
      - internal
    volumes:
      - /var/www/beweeg_app/nginx/log:/var/log/nginx
      - rails_public:/rails_app_public


volumes:
  rails_public: {}

networks:
  internal: {}

Dockerfile(用于 nginx 镜像)

FROM nginx:1.17-alpine

WORKDIR /var/www/rails_app

COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./rails.conf /etc/nginx/conf.d/default.conf

VOLUME /var/log/nginx/
EXPOSE 80

CMD nginx -c /etc/nginx/nginx.conf

rails.conf

upstream rails_app {
  server app:3000 fail_timeout=0;
  keepalive 3;
}

server {
  listen 80 default_server;

  # Define domain
  server_name staging.beweeg.fr;

  root /rails_app_public;

  access_log /var/log/nginx/nginx-app-access.log;
  error_log  /var/log/nginx/nginx-app-error.log;

  # No index.html because the index is from Rails
  # You may need this if your nginx will serve static files built directly from front-end build tools
  index index.html;

  location / {
    proxy_set_header        X-Forwarded-Proto https;
    proxy_set_header        Host              $http_host;
    proxy_set_header        X-Real-IP         $remote_addr;
    proxy_set_header        X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_redirect off;
    # post_action @ga;

    # If the file exists as a static file serve it directly without
    # running all the other rewrite tests on it
    if (-f $request_filename) {
      break;
    }

    if (!-f $request_filename) {
      proxy_pass http://rails_app;
      break;
    }
  }

  # Frontend assets
  location ~ ^/(js|css|img)/ {
    # access_log off;
    gzip_static on;
    expires     max;
    add_header  Cache-Control public;
    log_not_found off;
    break;
  }

  # Rails assets
  location ~ ^/(assets|packs|js)/ {
    root /rails_app_public;
    gzip_static on;
    expires     30d;
    add_header  Cache-Control public;
    log_not_found off;
    break;
  }

  client_max_body_size 32M;
}

非常感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails docker nginx


    【解决方案1】:

    我简要地查看了 compose 文件,乍一看,您似乎在 registry.gitlab.com/soykje/beweeg-ror/app:latest docker 映像内的 CI/CD 管道中构建了您的资产。然后在服务器上使用 compose 进行部署时,您将 rails_public 服务器 docker 卷安装在映像文件夹 /var/www/app/public 上,即意味着您的 rails_public 卷覆盖在 docker 映像资产中编译。

    顺便看看 Docker Swarm 模式。这是类似于 K8s 的编排器,但构建在 Docker 中并且更轻量级。

    【讨论】:

      【解决方案2】:

      我在这里为 Rails 开发人员创建了一个带有 Docker 支持的基础项目

      https://github.com/giapnhdev/rails-base
      

      【讨论】:

        猜你喜欢
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-14
        相关资源
        最近更新 更多