diff --git a/.docker-hub/docker-compose.yml b/.docker-hub/docker-compose.yml index 785d7dfec78..9c39c04cc28 100644 --- a/.docker-hub/docker-compose.yml +++ b/.docker-hub/docker-compose.yml @@ -14,3 +14,21 @@ services: context: .. dockerfile: .docker-hub/backend/Dockerfile image: ecamp/ecamp3-backend:latest + + print: + build: + context: .. + dockerfile: .docker-hub/print/Dockerfile + image: ecamp/ecamp3-print:latest + + worker-print-puppeteer: + build: + context: .. + dockerfile: .docker-hub/worker-print-puppeteer/Dockerfile + image: ecamp/ecamp3-worker-print-puppeteer:latest + + worker-print-weasy: + build: + context: .. + dockerfile: .docker-hub/worker-print-weasy/Dockerfile + image: ecamp/ecamp3-worker-print-weasy:latest diff --git a/.docker-hub/print/Dockerfile b/.docker-hub/print/Dockerfile new file mode 100644 index 00000000000..9ff2273a81b --- /dev/null +++ b/.docker-hub/print/Dockerfile @@ -0,0 +1,8 @@ +FROM node:12.18 +WORKDIR /app +COPY print/package*.json ./ +RUN npm install +COPY print . +RUN npm run build +EXPOSE 80 +CMD npm run start diff --git a/.docker-hub/push.sh b/.docker-hub/push.sh index 46f05006e11..6c2431b6cbc 100644 --- a/.docker-hub/push.sh +++ b/.docker-hub/push.sh @@ -3,4 +3,4 @@ set -e echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_USERNAME" --password-stdin docker-compose -f .docker-hub/docker-compose.yml build -docker-compose -f .docker-hub/docker-compose.yml push backend frontend +docker-compose -f .docker-hub/docker-compose.yml push backend frontend print worker-print-puppeteer worker-print-weasy diff --git a/.docker-hub/worker-print-puppeteer/Dockerfile b/.docker-hub/worker-print-puppeteer/Dockerfile new file mode 100644 index 00000000000..29d6f7ffffb --- /dev/null +++ b/.docker-hub/worker-print-puppeteer/Dockerfile @@ -0,0 +1,6 @@ +FROM buildkite/puppeteer +WORKDIR /app +COPY workers/print-puppeteer/package*.json ./ +RUN npm install +COPY workers/print-puppeteer . +CMD npm run print diff --git a/.docker-hub/worker-print-weasy/Dockerfile b/.docker-hub/worker-print-weasy/Dockerfile new file mode 100644 index 00000000000..2662f0320cb --- /dev/null +++ b/.docker-hub/worker-print-weasy/Dockerfile @@ -0,0 +1,21 @@ +FROM python:3.8 + +# install all the dependencies except libcairo2 from jessie, then install libcairo2 from stretch +RUN apt-get -y update \ + && apt-get install -y \ + fonts-font-awesome \ + libffi-dev \ + libgdk-pixbuf2.0-0 \ + libpango1.0-0 \ + python-dev \ + python-lxml \ + shared-mime-info \ + libcairo2 + +WORKDIR /app + +RUN pip install WeasyPrint pika requests + +COPY workers/print-weasy . + +CMD python -u print.py diff --git a/backend/config/autoload/sessions.local.docker.dist b/backend/config/autoload/sessions.local.docker.dist new file mode 100644 index 00000000000..082000cf458 --- /dev/null +++ b/backend/config/autoload/sessions.local.docker.dist @@ -0,0 +1,7 @@ + [ + 'cookie_domain' => '', + ], +]; diff --git a/docker-compose.yml b/docker-compose.yml index 6a69ca2029d..5681b7dbf82 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,7 +31,7 @@ services: image: node:12.18 container_name: 'ecamp3-print' ports: - - '3003:3000' + - '3003:80' volumes: - ./print:/app:delegated - npm-cache:/root/.npm @@ -40,6 +40,8 @@ services: command: ./docker-setup.sh environment: - HOST=0.0.0.0 + env_file: + - ./print/print.env composer: image: composer:2 @@ -77,7 +79,7 @@ services: - '3004:15672' worker-print-puppeteer: - image: buildkite/puppeteer + build: ./workers/print-puppeteer container_name: 'ecamp3-worker-print-puppeteer' volumes: - ./workers/print-puppeteer:/app:delegated diff --git a/print/README.md b/print/README.md index d4f658104c5..7efd5210ca7 100644 --- a/print/README.md +++ b/print/README.md @@ -6,7 +6,7 @@ # install dependencies $ npm install -# serve with hot reload at localhost:3000 +# serve with hot reload at localhost $ npm run dev # build for production and launch server diff --git a/print/nuxt.config.js b/print/nuxt.config.js index 5a7a6db5674..897cba69ee2 100644 --- a/print/nuxt.config.js +++ b/print/nuxt.config.js @@ -11,6 +11,10 @@ export default { ** See https://nuxtjs.org/api/configuration-target */ target: 'server', + server: { + port: 80, + host: '0.0.0.0', + }, /* ** Headers of the page ** See https://nuxtjs.org/api/configuration-head @@ -82,4 +86,16 @@ export default { ** See https://nuxtjs.org/api/configuration-build/ */ build: {}, + + publicRuntimeConfig: { + axios: { + browserBaseURL: process.env.API_ROOT_URL || 'http://localhost:3001/api', + }, + }, + + privateRuntimeConfig: { + axios: { + baseURL: process.env.INTERNAL_API_ROOT_URL || 'http://backend/api', + }, + }, } diff --git a/print/package-lock.json b/print/package-lock.json index fb2a0c22d84..e2e49cbd38b 100644 --- a/print/package-lock.json +++ b/print/package-lock.json @@ -2076,15 +2076,27 @@ } }, "@nuxtjs/axios": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/axios/-/axios-5.11.0.tgz", - "integrity": "sha512-6M87KUXWWlAjRIwqBTXoollTwsUDnf8bdOR3qY1cVggvUP4hYgb2Oby7/Jr0u7bWGyb+/GuagwBBtubGTLsoyA==", + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/@nuxtjs/axios/-/axios-5.12.2.tgz", + "integrity": "sha512-MKSuwHRgLTw1tMS1mDf+7XIvQLvF8GlK3rtuJY4lNmZVxYiBYhG3Nd6OrtH07fljNmvL7/JIUzk+1o/tVS6Pkg==", "requires": { - "@nuxtjs/proxy": "^2.0.0", - "axios": "^0.19.2", + "@nuxtjs/proxy": "^2.0.1", + "axios": "^0.20.0", "axios-retry": "^3.1.8", - "consola": "^2.11.3", - "defu": "^2.0.2" + "consola": "^2.15.0", + "defu": "^3.1.0" + }, + "dependencies": { + "consola": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.0.tgz", + "integrity": "sha512-vlcSGgdYS26mPf7qNi+dCisbhiyDnrN1zaRbw3CSuc2wGOMEGGPsp46PdRG5gqXwgtJfjxDkxRNAgRPr1B77vQ==" + }, + "defu": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/defu/-/defu-3.1.0.tgz", + "integrity": "sha512-pc7vS4wbYFtsRL+OaLHKD72VcpOz9eYgzZeoLz9pCs+R8htyPdZnD1CxKP9ttZuT90CLPYFTSaTyc3/7v4gG9A==" + } } }, "@nuxtjs/eslint-config": { @@ -2114,9 +2126,9 @@ } }, "@nuxtjs/proxy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nuxtjs/proxy/-/proxy-2.0.0.tgz", - "integrity": "sha512-ewiOLAhfQlE/QWiQkHH0MQBYrtTRRSuz5SqDly1Zy/M3cN9bxqWd9d5Ty/GnU3nLtwsfW64TrRKuTw8/gT1nFQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nuxtjs/proxy/-/proxy-2.0.1.tgz", + "integrity": "sha512-RVZ6iYeAuWteot9oer3vTDCOEiTwg37Mqf6yy8vPD0QQaw4z3ykgM++MzfUl85jM14+qNnODZj5EATRoCY009Q==", "requires": { "consola": "^2.11.3", "http-proxy-middleware": "^1.0.4" @@ -3154,27 +3166,17 @@ "dev": true }, "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", "requires": { - "follow-redirects": "1.5.10" - }, - "dependencies": { - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - } - } + "follow-redirects": "^1.10.0" } }, "axios-retry": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.1.8.tgz", - "integrity": "sha512-yPw5Y4Bg6Dgmhm35KaJFtlh23s1TecW0HsUerK4/IS1UKl0gtN2aJqdEKtVomiOS/bDo5w4P3sqgki/M10eF8Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.1.9.tgz", + "integrity": "sha512-NFCoNIHq8lYkJa6ku4m+V1837TP6lCa7n79Iuf8/AqATAHYB0ISaAS1eyIenDOfHOLtym34W65Sjke2xjg2fsA==", "requires": { "is-retry-allowed": "^1.1.0" } @@ -5117,14 +5119,6 @@ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -6563,9 +6557,9 @@ } }, "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "events": { "version": "3.1.0", @@ -7177,9 +7171,9 @@ } }, "follow-redirects": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", - "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==" + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" }, "for-in": { "version": "1.0.2", @@ -7911,15 +7905,22 @@ } }, "http-proxy-middleware": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.4.tgz", - "integrity": "sha512-8wiqujNWlsZNbeTSSWMLUl/u70xbJ5VYRwPR8RcAbvsNxzAZbgwLzRvT96btbm3fAitZUmo5i8LY6WKGyHDgvA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz", + "integrity": "sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==", "requires": { "@types/http-proxy": "^1.17.4", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "micromatch": "^4.0.2" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + } } }, "http-signature": { diff --git a/print/package.json b/print/package.json index eb18556c189..d103012c59d 100644 --- a/print/package.json +++ b/print/package.json @@ -14,7 +14,7 @@ "test": "jest" }, "dependencies": { - "@nuxtjs/axios": "^5.11.0", + "@nuxtjs/axios": "^5.12.2", "nuxt": "^2.13.0", "pagedjs": "^0.1.42" }, diff --git a/print/print.env b/print/print.env new file mode 100644 index 00000000000..10d539425b5 --- /dev/null +++ b/print/print.env @@ -0,0 +1,2 @@ +INTERNAL_API_ROOT_URL=http://backend/api +API_ROOT_URL=http://localhost:3001/api diff --git a/workers/print-puppeteer/Dockerfile b/workers/print-puppeteer/Dockerfile new file mode 100644 index 00000000000..169b8aff6ba --- /dev/null +++ b/workers/print-puppeteer/Dockerfile @@ -0,0 +1,6 @@ +FROM buildkite/puppeteer +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +CMD npm run print diff --git a/workers/print-puppeteer/environment.js b/workers/print-puppeteer/environment.js new file mode 100644 index 00000000000..ed6eeabd88c --- /dev/null +++ b/workers/print-puppeteer/environment.js @@ -0,0 +1,9 @@ +module.exports = { + PRINT_SERVER: process.env.PRINT_SERVER || "http://print", + SESSION_COOKIE_DOMAIN: process.env.SESSION_COOKIE_DOMAIN || "backend", + AMQP_HOST: process.env.AMQP_HOST || 'rabbitmq', + AMQP_PORT: process.env.AMQP_PORT || '5672', + AMQP_VHOST: process.env.AMQP_VHOST || '/', + AMQP_USER: process.env.AMQP_USER || 'guest', + AMQP_PASS: process.env.AMQP_PASS || 'guest', +}; diff --git a/workers/print-puppeteer/index.js b/workers/print-puppeteer/index.js index 424c34d8041..51696265069 100644 --- a/workers/print-puppeteer/index.js +++ b/workers/print-puppeteer/index.js @@ -1,14 +1,7 @@ const puppeteer = require('puppeteer'); const amqp = require('amqplib/callback_api'); -const PRINT_SERVER = process.env.PRINT_SERVER || "http://print:3000"; - -const AMQP_HOST = process.env.AMQP_HOST || 'rabbitmq'; -const AMQP_PORT = process.env.AMQP_PORT || '5672'; -const AMQP_VHOST= process.env.AMQP_VHOST || '/'; -const AMQP_USER = process.env.AMQP_USER || 'guest'; -const AMQP_PASS = process.env.AMQP_PASS || 'guest'; - +const { PRINT_SERVER, SESSION_COOKIE_DOMAIN, AMQP_HOST, AMQP_PORT, AMQP_VHOST, AMQP_USER, AMQP_PASS } = require('./environment.js'); async function startBrowser() { const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']}); @@ -25,17 +18,9 @@ async function html2pdf(url, filename, sessionId) { const cookies = [ { - "domain": "print", - "hostOnly": true, - "httpOnly": false, + "domain": SESSION_COOKIE_DOMAIN, "name": "PHPSESSID", - "path": "/", - "sameSite": "unspecified", - "secure": false, - "session": true, - "storeId": "1", "value": sessionId, - "id": 1 } ] @@ -44,7 +29,7 @@ async function html2pdf(url, filename, sessionId) { await page.goto(url); await page.waitFor(500); - await page.waitForSelector(".pagedjs_pages", {timeout:2000}); + await page.waitForSelector(".pagedjs_pages", {timeout:10000}); await page.pdf({path: `data/${filename}-puppeteer.pdf`}); } @@ -60,7 +45,7 @@ function start() { throw error1; } - var queue = 'printer-puppeteer'; + const queue = 'printer-puppeteer'; channel.assertQueue(queue, { durable: true diff --git a/workers/print-weasy/.gitignore b/workers/print-weasy/.gitignore new file mode 100644 index 00000000000..ed8ebf583f7 --- /dev/null +++ b/workers/print-weasy/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/workers/print-weasy/environment.py b/workers/print-weasy/environment.py new file mode 100644 index 00000000000..f5be860f0d5 --- /dev/null +++ b/workers/print-weasy/environment.py @@ -0,0 +1,8 @@ +import os + +PRINT_SERVER = os.getenv('PRINT_SERVER', 'http://print/') +AMQP_HOST = os.getenv('AMQP_HOST', 'rabbitmq') +AMQP_PORT = os.getenv('AMQP_PORT', '5672') +AMQP_VHOST = os.getenv('AMQP_VHOST', '/') +AMQP_USER = os.getenv('AMQP_USER', 'guest') +AMQP_PASS = os.getenv('AMQP_PASS', 'guest') diff --git a/workers/print-weasy/print.py b/workers/print-weasy/print.py index 879867155b9..f2a595df5ea 100755 --- a/workers/print-weasy/print.py +++ b/workers/print-weasy/print.py @@ -5,15 +5,8 @@ import pika import json import requests -import os -PRINT_SERVER = os.getenv('PRINT_SERVER', 'http://print:3000/') - -AMQP_HOST = os.getenv('AMQP_HOST', 'rabbitmq') -AMQP_PORT = os.getenv('AMQP_PORT', '5672') -AMQP_VHOST = os.getenv('AMQP_VHOST', '/') -AMQP_USER = os.getenv('AMQP_USER', 'guest') -AMQP_PASS = os.getenv('AMQP_PASS', 'guest') +from environment import * # create custom URL fetcher to include cookie def url_fetcher_factory(sessionId):