Active Storage + rails 不适用于 docker + nginx
Active Storage + rails not working with docker + nginx
我在 rails 6 中使用 Docker 和 Nginx 的活动存储。我正在通过 rails 控制台上传图片,即
object.images.attach(io: File.open("#{Rails.root}/image_path"), filename: "image.jpg")
上传成功,但文件未存储在指定位置,即Rails.root.join("storage")
。为此,我没有得到图像文件。
我不确定问题是出在 Docker 还是 Nginx 或 ActiveStorage
请帮忙...
- app.Dockerfile
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"]
- nginx.Dockerfile
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;" ]
- nginx.conf
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 (.*) /index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) .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;
}
}
- docker-compose.yml
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:
- config/storage.yml
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
我认为您的 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
。修改所有卷,它应该可以工作。
我在 rails 6 中使用 Docker 和 Nginx 的活动存储。我正在通过 rails 控制台上传图片,即
object.images.attach(io: File.open("#{Rails.root}/image_path"), filename: "image.jpg")
上传成功,但文件未存储在指定位置,即Rails.root.join("storage")
。为此,我没有得到图像文件。
我不确定问题是出在 Docker 还是 Nginx 或 ActiveStorage
请帮忙...
- app.Dockerfile
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"]
- nginx.Dockerfile
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;" ]
- nginx.conf
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 (.*) /index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) .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;
}
}
- docker-compose.yml
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:
- config/storage.yml
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
我认为您的 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
。修改所有卷,它应该可以工作。