首页 > 解决方案 > Active Storage + rails 不适用于 docker + nginx

问题描述

我在带有 Docker 和 Nginx 的 rails 6 中使用主动存储。我正在通过 rails 控制台上传图像,即

object.images.attach(io: File.open("#{Rails.root}/image_path"), filename: "image.jpg")

上传成功,但文件未存储在指定位置,即Rails.root.join("storage"). 为此,我没有得到图像文件。

我不确定问题出在 Docker、Nginx 还是 ActiveStorage

请帮忙...

FROM ruby:3.0.0
RUN apt-get update \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . /app

COPY ./entrypoint.sh /app
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb", "-p", "3000"]
FROM nginx
RUN apt-get update -qq && apt-get -y install apache2-utils
ENV RAILS_ROOT /app
WORKDIR $RAILS_ROOT
RUN mkdir log
COPY public public/
COPY ./nginx.conf /tmp/docker.nginx
RUN envsubst '$RAILS_ROOT' < /tmp/docker.nginx > /etc/nginx/conf.d/default.conf
EXPOSE 3000
CMD [ "nginx", "-g", "daemon off;" ]
upstream app {
  server 'app:3000';
}
server {
  listen 3000;
  server_name localhost;
  keepalive_timeout 5;
  root /app/public;
  access_log /app/log/nginx.access.log;
  error_log /app/log/nginx.error.log info;
  if (-f $document_root/maintenance.html) {
    rewrite  ^(.*)$  /maintenance.html last;
    break;
  }
  location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    if (-f $request_filename) {
      break;
    }
    if (-f $request_filename/index.html) {
      rewrite (.*) $1/index.html break;
    }
    if (-f $request_filename.html) {
      rewrite (.*) $1.html break;
    }
    if (!-f $request_filename) {
      proxy_pass http://app;
      break;
    }
  }
  location ~ ^(?!/rails/).+\.(jpg|jpeg|gif|png|ico|json|txt|xml)$ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    try_files $uri =404;
    error_page 404 /404.html;
  }
  location = /500.html {
    root /app/current/public;
  }
}
version: '3.9'
services:
  db:
    image: mariadb:10.3.29
    restart: unless-stopped
    volumes:
      - .:/my_app
      - db-volume:/var/lib/mysql
    ports:
      - '3306:3306'
    environment:
      MARIADB_DATABASE_NAME: database
      MARIADB_ROOT_USERNAME: username
      MARIADB_ROOT_PASSWORD: password
    networks:
      - network_name
  app:
    build:
      context: .
      dockerfile: app.Dockerfile
    container_name: container_name
    command: bash -c "bundle exec puma -C config/puma.rb -p 3000"
    restart: unless-stopped
    volumes:
      - .:/my_app
      - bundle-volume:/usr/local/bundle
    depends_on:
      - db
    networks:
      - network_name
  nginx:
    build:
      context: .
      dockerfile: nginx.Dockerfile
    restart: unless-stopped
    depends_on:
      - app
    ports:
      - 3000:3000
    networks:
      - network_name
volumes:
  db-volume:
  bundle-volume:
networks:
  network_name:

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

标签: ruby-on-railsdockernginxdocker-composerails-activestorage

解决方案


我相信您的 docker-compose.yml 中存在命名约定问题

services:
  db:
    image: mariadb:10.3.29
    restart: unless-stopped
    volumes:
      - .:/my_app
      - db-volume:/var/lib/mysql

在卷中,由于您已给出文件夹名称my_app,因此为服务my_app服务创建文件,而不是为app服务创建文件。所以.:/my_app应该更改为您的应用程序服务名称,即.:/app. 修改所有卷,它应该可以工作。


推荐阅读