2

I want to build anycable with my application but I get this error:

ActionController::RoutingError (No route matches [GET] "/cable") 

and this is error in the browser:

action_cable.js:241 WebSocket connection to 'wss://portal.comp-moto.com/cable' failed:  

This is my docker-compose.yml

version: "3"

volumes:
  data-uploads:
  packs:
services:
  app:
    build:
      context: .
      dockerfile: ./dockers/app/Dockerfile
    container_name: comp_moto_app
    restart: unless-stopped
    ports:
      - 3000:3000
    volumes:
      - .:/app
      - /app/node_modules
      - /app/public/assets
      - /app/public/packs
    depends_on:
      - redis
    environment:
      - REDIS_URL_CACHING=redis://redis@redis:6379/0
  db:
    image: "postgres:14.1-alpine"
    container_name: comp_moto_db
    environment:
      POSTGRES_USER: ${DOCKER_DB_USER}
      POSTGRES_PASSWORD: ${DOCKER_DB_PASSWORD}
      POSTGRES_DB: ${DOCKER_DB_NAME}
    volumes:
      - /docker_data/comp_moto_app/postgres:/var/lib/postgresql/data
    ports:
      - 5432:5432
  nginx:
    build:
      context: .
      dockerfile: ./dockers/web/Dockerfile
    container_name: comp_moto_web
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    depends_on:
      - app
    volumes:
      - ./dockers/web/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./public:/app/public
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    image: certbot/certbot
    restart: unless-stopped
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
  redis:
    image: redis:6.2.6-alpine
    container_name: comp_moto_redis
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - /docker_data/comp_moto/production/redis:/data
      - ./dockers/redis/redis.conf:/usr/local/etc/redis/redis.conf
    ports:
      - 6379:6379
  delayed_job:
    build:
      context: .
      dockerfile: ./dockers/delayed_job/Dockerfile
    container_name: comp_moto_delayed_job
    command: bundle exec rails jobs:work
    depends_on:
      - db
    volumes:
      - .:/app    
  anycable:
    build:
      context: .
      dockerfile: ./dockers/cable/Dockerfile
    container_name: comp_moto_anycable
    command: bundle exec anycable
    environment:
      ANYCABLE_REDIS_URL: redis://redis@redis:6379/0
      ANYCABLE_RPC_HOST: 0.0.0.0:50051
      ANYCABLE_DEBUG: 1
    ports:
      - '50051'
    depends_on:
      - redis
      - db
  ws: 
    image:  anycable/anycable-go:latest-alpine
    container_name: comp_moto_ws
    ports:
      - '8080:8080'
    environment: 
      ANYCABLE_HOST: "0.0.0.0"
      ANYCABLE_REDIS_URL: redis://redis@redis:6379/0
      ANYCABLE_RPC_HOST: anycable:50051
      ANYCABLE_DEBUG: 1
    depends_on:
      - redis
      - anycable
  sidekiq:
    build:
      context: .
      dockerfile: ./dockers/sidekiq/Dockerfile
    container_name: comp_moto_sidekiq
    command: bundle exec sidekiq
    depends_on:
      - db
      - redis
    volumes:
       - data-uploads:/app/public/uploads 

this is my Dockerfile for anycale service

FROM ruby:3.0.1-alpine
RUN apk add --no-cache --update build-base \
                                linux-headers \
                                postgresql-dev \
                                tzdata \
                                git \
                                nodejs \
                                yarn \
                                libc6-compat

COPY Gemfile Gemfile.lock package*.json yarn.lock ./

RUN gem install bundler && bundle install --jobs 3 

COPY . ./
EXPOSE 50051

ENTRYPOINT ["bundle", "exec"]
CMD ["anycable"] 

I also add these to production.rb

config.after_initialize do
    config.action_cable.url = ActionCable.server.config.url = ENV.fetch("CABLE_URL", "wss://portal.comp-moto.com/cable") if AnyCable::Rails.enabled?
end 
config.action_cable.url = 'wss://portal.comp-moto.com/cable'
config.action_cable.allowed_request_origins = [ 'https://portal.comp-moto.com', /https:\/\/portal.comp-moto.com.*/ ] 

this is anycale.yml

development:
  redis_url: redis://localhost:6379/1
production:
  redis_url: redis://:redis@redis:6379/0
  access_logs_disabled: false

I use nginx, here is nginx

upstream rails_app {  
   server app:3000;
} 
server {  
   # define your domain  
   listen 80;
   server_name portal.comp-moto.com;
   server_tokens off;

   location /.well-known/acme-challenge/ {
      root /var/www/certbot;
   }
}

server {
  listen 443 ssl;
  server_name portal.comp-moto.com;
  server_tokens off;

  proxy_read_timeout 1800;
  proxy_connect_timeout 1800;
  proxy_send_timeout 1800; 
  
  client_max_body_size 20M;
  client_body_buffer_size 20M;
  client_body_timeout 1800;
  client_header_timeout 1800;
  keepalive_timeout 1800;
  send_timeout 1800;

  # define the public application root
  root   /app/public;
  index  index.html;

  # serve static (compiled) assets directly if they exist (for rails production)
  location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
    try_files $uri @rails;

    access_log off;
    gzip_static on; # to serve pre-gzipped version

    expires max;
    add_header Cache-Control public;

    # Some browsers still send conditional-GET requests if there's a
    # Last-Modified header or an ETag header even if they haven't
    # reached the expiry date sent in the Expires header.
    add_header Last-Modified "";
    add_header ETag "";
    break;
  }

  # send non-static file requests to the app server
  location / {
    try_files $uri @rails;
  }

  ssl_certificate /etc/letsencrypt/live/portal.comp-moto.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/portal.comp-moto.com/privkey.pem;

  location @rails {
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Host $http_host;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_set_header  X-Forwarded-Ssl on;
    proxy_set_header  X-Forwarded-Port $server_port;
    proxy_set_header  X-Forwarded-Host $host;
    proxy_redirect off;
    proxy_pass http://rails_app;
  }

  location /wss {
    proxy_pass https://portal.comp-moto.com:8080;
    include proxy_params;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}
rmlockerd
  • 3,776
  • 2
  • 15
  • 25
  • Does your app work outside of Docker? Check that you are mounting the cable endpoint in your `router.rb` (e.g., `mount ActionCable.server => '/cable'`) and that you are specifying `:anycable` as the adapter in `config/cable.yml`. – rmlockerd Sep 09 '22 at 21:51
  • I fix that, now i can connect to anycable already, i can send message but it is not stream back to front end and i got this error `There was an exception - NotImplementedError(NotImplementedError)` Is this because stream_from? I've try to remove stream_from, this error is gone I have this ` def subscribed stream_from "room_channel_#{params[:room_id]}" end` – Khamonluck Angkananon Sep 10 '22 at 12:50
  • this log on anycable, is it okay or something wrong? `2022-09-10T12:40:46.163Z context=hub stream=room_channel_71bbbd28-a355-4f6e-98d1-98ba120572eb No sessions ` – Khamonluck Angkananon Sep 10 '22 at 12:53

0 Answers0