dodona-edu / dolos

:detective: Source code plagiarism detection
https://dolos.ugent.be
MIT License
244 stars 31 forks source link

Self hosting Dolos using docker-compose #1518

Closed mikaelGusse closed 3 months ago

mikaelGusse commented 3 months ago

Which component(s) is your question about? Self-hosting Dolos web app

What is your question? Hello! We here at Aalto are having some difficulties hosting Dolos on our own servers at the moment. We are trying to use the docker-compose method to host it. We are using nginx as well for this setup. Currently we are able to open up the web front end and submit a file for analysis. It manages to complete the analysis succesfully (most of the time) but when we try to open up the report it tries to fetch the report from the wrong place for some reason. Instead of going through https://DOLOS_URL/api/reports it tries to get the report from http://DOLOS_URL/reports. This happens despite us settings the VITE_API_URL to the https.

Our current nginx.conf looks like this:

events {}

http {

    upstream dolos-api {
        server api:3000;
    }

    upstream dolos-web {
        server web:8080;
    }

    server {
        listen 80;
        server_name {INSERT DOLOS URL HERE};

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 443 ssl;
        server_name {INSERT DOLOS URL HERE};

        ssl_certificate /etc/ssl/private/fullchain.pem;
        ssl_certificate_key /etc/ssl/private/privkey.pem;

        location /{
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
            proxy_pass http://dolos-web/;
        }

        location /api {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
            proxy_pass http://dolos-api/;
        }
    }
}

And our current docker-compose looks like this

name: dolos
version: "3.9"
services:
  db:
    image: mariadb:11
    volumes:
      - dolos-db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: {INSERT PASSWORD HERE}
    networks:
      - dolos
    healthcheck:
      start_period: 2s
      interval: 5s
      test: healthcheck.sh --su-mysql --connect --innodb_initialized
  web:
    image: ghcr.io/dodona-edu/dolos-web
    build: ./web/
    environment:
      VITE_HOST: 0.0.0.0
      VITE_PORT: 8080
      VITE_API_URL: https://{INSERT DOLOS URL HERE}/api
      VITE_MODE: server
    depends_on:
      - api
    networks:
      - dolos
    healthcheck:
      start_period: 2s
      interval: 5s
      test: curl --fail http://localhost:8080 || exit 1
  api:
    image: ghcr.io/dodona-edu/dolos-api
    build: ./api/
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails db:prepare && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - dolos-api-storage:/dolos/storage
      - /tmp:/tmp
    environment:
      DOLOS_API_FRONT_END_URL: https://{INSERT DOLOS URL HERE}
      DOLOS_API_HOSTS: {INSERT DOLOS URL HERE}
      DOLOS_API_DISABLE_FORCE_SSL: false
      DOLOS_API_DATABASE_USERNAME: root
      DOLOS_API_DATABASE_PASSWORD: {INSERT PASSWORD HERE}
      DOLOS_API_DATABASE_HOST: db
      RAILS_ENV: production
      RAILS_LOG_TO_STDOUT: true
      SECRET_KEY_BASE_DUMMY: true
    depends_on:
      db:
        condition: service_healthy
    networks:
      - dolos
        #    healthcheck:
        #      start_period: 2s
        #      interval: 10s
        #      test: curl --fail http://localhost:3000/up || exit 1
  worker:
    image: ghcr.io/dodona-edu/dolos-api
    build: ./api/
    command: bash -c "bundle exec rails jobs:work"
    volumes:
      - dolos-api-storage:/dolos/storage
      - /tmp:/tmp
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      DOLOS_API_FRONT_END_URL: https://{INSERT DOLOS URL HERE}
      DOLOS_API_HOSTS: {INSERT DOLOS URL HERE}
      DOLOS_API_DATABASE_USERNAME: root
      DOLOS_API_DATABASE_PASSWORD:{INSERT PASSWORD HERE}
      DOLOS_API_DATABASE_HOST: db
      RAILS_ENV: production
      SECRET_KEY_BASE_DUMMY: true
      RAILS_LOG_TO_STDOUT: true
    depends_on:
      - api
    networks:
      - dolos
    healthcheck:
      start_period: 2s
      interval: 5s
      test: ruby -e true || exit 1
  nginx:
    image: nginx:latest
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./fullchain.pem:/etc/ssl/private/fullchain.pem
      - ./privkey.pem:/etc/ssl/private/privkey.pem
    ports:
      - "443:443"
      - "80:80"
    restart: always
    networks:
      - dolos
    depends_on:
      - api
      - web

volumes:
  dolos-db-data:
  dolos-api-storage:

networks:
  dolos:
rien commented 3 months ago

Hi @mikaelGusse!

The VITE_API_URL environment variable should be present in the dolos-web container at build time. I think you can change this manually by changing this line: https://github.com/dodona-edu/dolos/blob/7e4bc1faf8c4f78034aeba1aed7465ca1211af7f/web/Dockerfile#L13

I understand this is not ideal however. I'll try to think of a better way on how the Web UI could automatically use the correct report location.

mikaelGusse commented 3 months ago

Hello, I have now had time to try with this change but it still seems to try to go through http. Is there some additional place I could check for this variable?

rien commented 3 months ago

I will need some more information: does it always try to access the API through http, or only the reports? Can you expect whether the url's in the API json's use http or https?

If the API is responding with http, you could set DOLOS_API_DISABLE_FORCE_SSL: false in the docker-compose.yml. With this environment variable set to false it will force all URL's to use https and also enforce other SSL security settings like secure cookies and so on.

mikaelGusse commented 3 months ago

We do have that flag set in the docker-compose but for some reason these specific ones are going through http. In the browser it gives me the following error when i try to open a report that has allegedly succeeded. On the right it seems to try to load some metadata.csv with http.

image
rien commented 3 months ago

Strange. I'll try to reproduce this issue locally to find out what could be causing this.

rien commented 3 months ago

I've drafted a fix for your issue, can you try out if #1522 solves this problem? You will need to build the API docker image manually as well, since that docker image isn't published yet.

mikaelGusse commented 3 months ago

Apologies for the delay but it looks like I was now able to get it to work! In addition to pulling the fixes from this #1522 I had to also change the VITE_API_URL variable in web/package.json to correspond to the corrrect one to get it to work.

Thanks for the help!

rien commented 3 months ago

Great to hear!