ruby-on-railsnginxdevopsdigital-oceanvps

Deploy rails 7 and nginx in vps


i've a rails project with importmap, scss, rails 7 and nginx.

i use a vps on digital ocean to deploy with docker and nginx.

my rails code stay here https://github.com/TryTech/try_tech

and my nginx.conf

worker_processes auto;
worker_rlimit_nofile 500000;
pcre_jit on;

error_log /var/log/nginx/error.log warn;

events {
use epoll;
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
access_log off;
error_log /dev/null emerg;

    ssl_session_cache shared:SSL:10m; 
    ssl_session_timeout 10m; 
    
    upstream web {
        server localhost:3000;
        server localhost:3001;
        keepalive 500;
    }
    
    server {
        listen 443 ssl;
        server_name trytech.app;
    
        ssl_certificate  /var/www/certbot/live/trytech.app/fullchain.pem;
        ssl_certificate_key /var/www/certbot/live/trytech.app/privkey.pem;
    
        location / {
            proxy_buffering off;
            proxy_set_header Connection "";
            proxy_http_version 1.1;
            proxy_set_header Keep-Alive "";
            proxy_set_header Proxy-Connection "keep-alive";
            proxy_pass http://web;
        }
    
        location ~ ^/assets/ {
            expires 1y;
            add_header Cache-Control public;
    
            add_header ETag "";
        }

}
}

i use docker-compose to up containers.

docker-compose:

version: '3.8'

services:
  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/www/:/var/www/certbot/:rw
      - ./certbot/conf/:/etc/letsencrypt/:rw
  nginx:
    image: "docker.io/nginx:${NGINX_VERSION}"
    container_name: nginx
    command: ["nginx", "-g", "daemon off;"]
      #entrypoint: 'tail -f /dev/null'
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./mime.types:/etc/nginx/mime.types
      - ./certbot/conf/:/var/www/certbot/:ro
      # - public_rails:/rails/public
    depends_on:
      - web1
      - web2
    ulimits:
      nproc: 1000000
      nofile:
        soft: 1000000
        hard: 1000000
    network_mode: host
    deploy:
      resources:
        limits:
          cpus: '0.15'
          memory: '0.3GB'

  web1: &web
    image: "ghcr.io/trytech/try_tech:release"
    container_name: web1
    # volumes:
    #   - public_rails:/rails/public
    env_file:
      - ./.env.prod
    environment:
      PORT: 3000
    depends_on:
      - postgres
      - redis
    network_mode: host
    hostname: web1
    deploy:
      resources:
        limits:
          cpus: '0.45'
          memory: '0.5GB'

  web2:
    <<: *web
    hostname: web2
    container_name: web2
    environment:
      PORT: 3001


  redis:
    container_name: redis
    image: "docker.io/redis:${REDIS_VERSION}"
    command: redis-server --save "" --appendonly no --maxclients 20000
    hostname: redis
    network_mode: host
    deploy:
      resources:
        limits:
          cpus: '0.05'
          memory: '0.1GB'

  postgres:
    container_name: postgres
    image: "docker.io/postgres:${POSTGRES_VERSION}"
    network_mode: host
    hostname: postgres
    volumes:
      - ./postgres/production.sql:/docker-entrypoint-initdb.d/production.sql
      - ./postgresql.conf:/docker-entrypoint-initdb.d/postgresql.conf
      - postgres_data:/var/lib/postgresql/data
    env_file:
      - ./.env.prod
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready" ]
      interval: 5s
      timeout: 5s
      retries: 20
      start_period: 10s
    deploy:
      resources:
        limits:
          cpus: '0.35'
          memory: '1.3GB'

volumes:
  postgres_data:
  # public_rails:

I think that's enough context if you need more info. In short, my problem comes down to not being able to use the javascript and css that come from the server.

enter image description here

I've already tried several implementations, such as letting rails handle the assets or just nginx, but I haven't been successful, I'm not very experienced with both technologies, this is my first project. If you want to debug the browser in production, here is the url. https://trytech.app/

Thank you in advance for your time

What is expected is that the site consumes javascript and css correctly.


Solution

  • Your issue has nothing to do with deployment. Fix your app locally first.

    Manually add bootstrap pins to load from jspm:

    # config/importmap.rb
    
    pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@5.3.2/dist/js/bootstrap.esm.js"
    pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/core@2.11.8/lib/index.js"
    

    Downgrade importmap-rails to v1 for now:

    # Gemfile 
    
    gem "importmap-rails", "~> 1.0"
    

    importmap-rails v2 is currently unusable a lot of the time because of this change:

    https://github.com/rails/importmap-rails/pull/217