From d3a11e307df83920219e05172bb3beed86f0b300 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Mon, 21 Aug 2023 13:25:39 +0100 Subject: [PATCH 01/11] remove kubernetes as helm chart should be used --- README.md | 3 +- kubernetes/01-backend-networkpolicy.yaml | 13 ---- kubernetes/01-frontend-networkpolicy.yaml | 13 ---- .../01-opdata-persistentvolumeclaim.yaml | 14 ---- .../01-pgdata-persistentvolumeclaim.yaml | 14 ---- kubernetes/02-cache-deployment.yaml | 24 ------- kubernetes/02-db-deployment.yaml | 41 ------------ kubernetes/03-cache-service.yaml | 15 ----- kubernetes/03-db-service.yaml | 15 ----- kubernetes/04-seeder-pod.yaml | 39 ----------- kubernetes/05-cron-deployment.yaml | 48 -------------- kubernetes/05-web-deployment.yaml | 64 ------------------- kubernetes/05-worker-deployment.yaml | 50 --------------- kubernetes/06-web-service.yaml | 15 ----- kubernetes/07-proxy-deployment.yaml | 32 ---------- kubernetes/08-proxy-service.yaml | 14 ---- kubernetes/09-proxy-ingress.yaml | 17 ----- kubernetes/README.md | 64 +------------------ 18 files changed, 3 insertions(+), 492 deletions(-) delete mode 100755 kubernetes/01-backend-networkpolicy.yaml delete mode 100755 kubernetes/01-frontend-networkpolicy.yaml delete mode 100755 kubernetes/01-opdata-persistentvolumeclaim.yaml delete mode 100755 kubernetes/01-pgdata-persistentvolumeclaim.yaml delete mode 100755 kubernetes/02-cache-deployment.yaml delete mode 100755 kubernetes/02-db-deployment.yaml delete mode 100755 kubernetes/03-cache-service.yaml delete mode 100755 kubernetes/03-db-service.yaml delete mode 100755 kubernetes/04-seeder-pod.yaml delete mode 100755 kubernetes/05-cron-deployment.yaml delete mode 100755 kubernetes/05-web-deployment.yaml delete mode 100755 kubernetes/05-worker-deployment.yaml delete mode 100755 kubernetes/06-web-service.yaml delete mode 100755 kubernetes/07-proxy-deployment.yaml delete mode 100755 kubernetes/08-proxy-service.yaml delete mode 100755 kubernetes/09-proxy-ingress.yaml diff --git a/README.md b/README.md index 21092fa..c76eb75 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # OpenProject Deploy -Recipes and examples for deploying OpenProject using Docker, Docker Compose, Kubernetes, etc. +Recipes and examples for deploying OpenProject. * [Docker Compose](./compose/) +* [Kubernetes](./kubernetes/) diff --git a/kubernetes/01-backend-networkpolicy.yaml b/kubernetes/01-backend-networkpolicy.yaml deleted file mode 100755 index 135d183..0000000 --- a/kubernetes/01-backend-networkpolicy.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: backend -spec: - ingress: - - from: - - podSelector: - matchLabels: - openproject.network/backend: "true" - podSelector: - matchLabels: - openproject.network/backend: "true" diff --git a/kubernetes/01-frontend-networkpolicy.yaml b/kubernetes/01-frontend-networkpolicy.yaml deleted file mode 100755 index 9663d04..0000000 --- a/kubernetes/01-frontend-networkpolicy.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: frontend -spec: - ingress: - - from: - - podSelector: - matchLabels: - openproject.network/frontend: "true" - podSelector: - matchLabels: - openproject.network/frontend: "true" diff --git a/kubernetes/01-opdata-persistentvolumeclaim.yaml b/kubernetes/01-opdata-persistentvolumeclaim.yaml deleted file mode 100755 index 333a9d3..0000000 --- a/kubernetes/01-opdata-persistentvolumeclaim.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - creationTimestamp: null - labels: - openproject.service: opdata - name: opdata -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 100Mi -status: {} diff --git a/kubernetes/01-pgdata-persistentvolumeclaim.yaml b/kubernetes/01-pgdata-persistentvolumeclaim.yaml deleted file mode 100755 index 60efc2a..0000000 --- a/kubernetes/01-pgdata-persistentvolumeclaim.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - creationTimestamp: null - labels: - openproject.service: pgdata - name: pgdata -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 100Mi -status: {} diff --git a/kubernetes/02-cache-deployment.yaml b/kubernetes/02-cache-deployment.yaml deleted file mode 100755 index 042f0f0..0000000 --- a/kubernetes/02-cache-deployment.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - openproject.service: cache - name: cache -spec: - replicas: 1 - selector: - matchLabels: - openproject.service: cache - strategy: {} - template: - metadata: - labels: - openproject.network/backend: "true" - openproject.service: cache - spec: - containers: - - image: memcached - name: cache - resources: {} - restartPolicy: Always -status: {} diff --git a/kubernetes/02-db-deployment.yaml b/kubernetes/02-db-deployment.yaml deleted file mode 100755 index 8ff7307..0000000 --- a/kubernetes/02-db-deployment.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - openproject.service: db - name: db -spec: - replicas: 1 - selector: - matchLabels: - openproject.service: db - strategy: - type: Recreate - template: - metadata: - labels: - openproject.network/backend: "true" - openproject.service: db - spec: - containers: - - env: - - name: POSTGRES_DB - value: openproject - - name: POSTGRES_PASSWORD - value: p4ssw0rd - image: postgres:13 - ports: - - containerPort: 5432 - name: psql - name: db - resources: {} - volumeMounts: - - mountPath: /var/lib/postgresql/data - name: pgdata - restartPolicy: Always - terminationGracePeriodSeconds: 3 - volumes: - - name: pgdata - persistentVolumeClaim: - claimName: pgdata -status: {} diff --git a/kubernetes/03-cache-service.yaml b/kubernetes/03-cache-service.yaml deleted file mode 100755 index 752aba6..0000000 --- a/kubernetes/03-cache-service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: cache - labels: - openproject.service: cache -spec: - type: NodePort - selector: - openproject.service: cache - ports: - - name: cache - protocol: TCP - port: 11211 - targetPort: 11211 diff --git a/kubernetes/03-db-service.yaml b/kubernetes/03-db-service.yaml deleted file mode 100755 index b4baaf2..0000000 --- a/kubernetes/03-db-service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: db - labels: - openproject.service: db -spec: - type: NodePort - selector: - openproject.service: db - ports: - - name: db - protocol: TCP - port: 5432 - targetPort: 5432 diff --git a/kubernetes/04-seeder-pod.yaml b/kubernetes/04-seeder-pod.yaml deleted file mode 100755 index fa4018c..0000000 --- a/kubernetes/04-seeder-pod.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - labels: - openproject.network/backend: "true" - openproject.service: seeder - name: seeder -spec: - containers: - - args: - - ./docker/prod/seeder - env: - - name: DATABASE_URL - value: postgres://postgres:p4ssw0rd@$(DB_SERVICE_HOST):$(DB_SERVICE_PORT)/openproject?pool=20&encoding=unicode&reconnect=true - - name: IMAP_ENABLED - value: "false" - - name: OPENPROJECT_CACHE__MEMCACHE__SERVER - value: $(CACHE_SERVICE_HOST):$(CACHE_SERVICE_PORT) - - name: OPENPROJECT_RAILS__RELATIVE__URL__ROOT - - name: RAILS_CACHE_STORE - value: memcache - - name: RAILS_MAX_THREADS - value: "16" - - name: RAILS_MIN_THREADS - value: "4" - - name: OPENPROJECT_EDITION - value: standard - image: openproject/community:12 - name: seeder - resources: {} - volumeMounts: - - mountPath: /var/openproject/assets - name: opdata - restartPolicy: OnFailure - volumes: - - name: opdata - persistentVolumeClaim: - claimName: opdata -status: {} diff --git a/kubernetes/05-cron-deployment.yaml b/kubernetes/05-cron-deployment.yaml deleted file mode 100755 index ecde8f1..0000000 --- a/kubernetes/05-cron-deployment.yaml +++ /dev/null @@ -1,48 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - openproject.service: cron - name: cron -spec: - replicas: 1 - selector: - matchLabels: - openproject.service: cron - strategy: - type: Recreate - template: - metadata: - labels: - openproject.network/backend: "true" - openproject.service: cron - spec: - containers: - - args: - - ./docker/prod/cron - env: - - name: DATABASE_URL - value: postgres://postgres:p4ssw0rd@db/openproject?pool=20&encoding=unicode&reconnect=true - - name: IMAP_ENABLED - value: "false" - - name: OPENPROJECT_CACHE__MEMCACHE__SERVER - value: cache:11211 - - name: OPENPROJECT_RAILS__RELATIVE__URL__ROOT - - name: RAILS_CACHE_STORE - value: memcache - - name: RAILS_MAX_THREADS - value: "16" - - name: RAILS_MIN_THREADS - value: "4" - image: openproject/community:12 - name: cron - resources: {} - volumeMounts: - - mountPath: /var/openproject/assets - name: opdata - restartPolicy: Always - volumes: - - name: opdata - persistentVolumeClaim: - claimName: opdata -status: {} diff --git a/kubernetes/05-web-deployment.yaml b/kubernetes/05-web-deployment.yaml deleted file mode 100755 index 8a43b12..0000000 --- a/kubernetes/05-web-deployment.yaml +++ /dev/null @@ -1,64 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - openproject.service: web - name: web -spec: - replicas: 1 - selector: - matchLabels: - openproject.service: web - strategy: - type: Recreate - template: - metadata: - labels: - openproject.network/backend: "true" - openproject.network/frontend: "true" - openproject.service: web - spec: - containers: - - args: - - ./docker/prod/web - env: - - name: DATABASE_URL - value: postgres://postgres:p4ssw0rd@$(DB_SERVICE_HOST):$(DB_SERVICE_PORT)/openproject?pool=20&encoding=unicode&reconnect=true - - name: IMAP_ENABLED - value: "false" - - name: OPENPROJECT_CACHE__MEMCACHE__SERVER - value: $(CACHE_SERVICE_HOST):$(CACHE_SERVICE_PORT) - - name: OPENPROJECT_RAILS__RELATIVE__URL__ROOT - - name: RAILS_CACHE_STORE - value: memcache - - name: RAILS_MAX_THREADS - value: "16" - - name: RAILS_MIN_THREADS - value: "4" - - name: OPENPROJECT_EDITION - value: standard - image: openproject/community:12 - ports: - - containerPort: 8080 - name: http - livenessProbe: - exec: - command: - - curl - - -f - - http://localhost:8080/health_checks/default - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 3 - name: web - resources: {} - volumeMounts: - - mountPath: /var/openproject/assets - name: opdata - restartPolicy: Always - volumes: - - name: opdata - persistentVolumeClaim: - claimName: opdata -status: {} diff --git a/kubernetes/05-worker-deployment.yaml b/kubernetes/05-worker-deployment.yaml deleted file mode 100755 index 4e62403..0000000 --- a/kubernetes/05-worker-deployment.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - openproject.service: worker - name: worker -spec: - replicas: 1 - selector: - matchLabels: - openproject.service: worker - strategy: - type: Recreate - template: - metadata: - labels: - openproject.network/backend: "true" - openproject.service: worker - spec: - containers: - - args: - - ./docker/prod/worker - env: - - name: DATABASE_URL - value: postgres://postgres:p4ssw0rd@$(DB_SERVICE_HOST):$(DB_SERVICE_PORT)/openproject?pool=20&encoding=unicode&reconnect=true - - name: IMAP_ENABLED - value: "false" - - name: OPENPROJECT_CACHE__MEMCACHE__SERVER - value: $(CACHE_SERVICE_HOST):$(CACHE_SERVICE_PORT) - - name: OPENPROJECT_RAILS__RELATIVE__URL__ROOT - - name: RAILS_CACHE_STORE - value: memcache - - name: RAILS_MAX_THREADS - value: "16" - - name: RAILS_MIN_THREADS - value: "4" - - name: OPENPROJECT_EDITION - value: standard - image: openproject/community:12 - name: worker - resources: {} - volumeMounts: - - mountPath: /var/openproject/assets - name: opdata - restartPolicy: Always - volumes: - - name: opdata - persistentVolumeClaim: - claimName: opdata -status: {} diff --git a/kubernetes/06-web-service.yaml b/kubernetes/06-web-service.yaml deleted file mode 100755 index 9d264b4..0000000 --- a/kubernetes/06-web-service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: web - labels: - openproject.service: web -spec: - type: NodePort - selector: - openproject.service: web - ports: - - name: web - protocol: TCP - port: 8080 - targetPort: 8080 diff --git a/kubernetes/07-proxy-deployment.yaml b/kubernetes/07-proxy-deployment.yaml deleted file mode 100755 index 07fad58..0000000 --- a/kubernetes/07-proxy-deployment.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - openproject.service: proxy - name: proxy -spec: - replicas: 1 - selector: - matchLabels: - openproject.service: proxy - strategy: {} - template: - metadata: - labels: - openproject.network/frontend: "true" - openproject.service: proxy - spec: - containers: - - args: - - ./docker/prod/proxy - env: - - name: APP_HOST - value: $(WEB_SERVICE_HOST) - - name: OPENPROJECT_RAILS__RELATIVE__URL__ROOT - image: openproject/community:12 - name: proxy - ports: - - containerPort: 80 - resources: {} - restartPolicy: Always -status: {} diff --git a/kubernetes/08-proxy-service.yaml b/kubernetes/08-proxy-service.yaml deleted file mode 100755 index 851925b..0000000 --- a/kubernetes/08-proxy-service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - openproject.service: proxy - name: proxy -spec: - type: NodePort - selector: - openproject.service: proxy - ports: - - name: http - port: 80 - targetPort: 80 diff --git a/kubernetes/09-proxy-ingress.yaml b/kubernetes/09-proxy-ingress.yaml deleted file mode 100755 index 7b02faa..0000000 --- a/kubernetes/09-proxy-ingress.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: proxy-ingress -spec: - ingressClassName: nginx - rules: - - host: k8s.openproject-dev.com - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: proxy - port: - number: 80 diff --git a/kubernetes/README.md b/kubernetes/README.md index 9cf68ac..bef8ad5 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -1,65 +1,3 @@ # OpenProject installation using Kubernetes -This is an example setup of OpenProject on Kubernetes. - -## Install - -Clone this repository: - -``` -git clone https://github.com/opf/openproject-deploy --depth=1 --branch=stable/12 openproject -``` - -Go to the compose folder: - -``` -cd openproject/kubernetes -``` - -Adjust the host name for the ingress in [09-proxy-ingress.yaml](./09-proxy-ingress.yaml). -The default value `k8s.openproject-dev.com` simply points to `127.0.0.1`. -You will have to insert the actual host name here and set up the DNS so that it points to the cluster IP. - -Next, apply the definitions: - -``` -kubectl apply -f . -``` - -## Ingress - -For the ingress to work you will need to enable an ingress addon in your cluster. - -If you already have a load balancer you want to use to expose the service, -simply delete [09-proxy-ingress.yaml](./09-proxy-ingress.yaml) and integrate -the [proxy service](./08-proxy-service.yaml) in your existing ingress or load balancer. - -## SSL Termination - -This setup does not include SSL termination. -The ingress simply listens on port 80 and serves HTTP requests. - -You will have to set up HTTPS yourself. -You can find more information on this in the [kubernetes docs](https://kubernetes.github.io/ingress-nginx/user-guide/tls/). - -## Scaling - -You can adjust the `replica` specs in the [web](./05-web-deployment.yaml) and [worker](./05-worker-deployment.yaml) deployments -to scale up the respective processes. - -## TROUBLESHOOTING - -### The **db** deployment fails due to the data directory not being empty - -This can happen if your cluster creates the `opdata` PVC (persistent volume claims) with an ext4 file system -which will automatically have a `lost+found` folder. - -To fix the issue you can add the following to the [db-deployment](./02-db-deployment.yaml)'s env next to -`POSTGRES_USER` and `POSTGRES_PASSWORD`: - -``` -- name: PGDATA - value: /var/lib/postgresql/data/pgdata -``` - -This makes the postgres container use a subfolder of the mount path (`/var/lib/postgresql/data`) as the data directory. +Please use the [OpenProject helm chart](https://charts.openproject.org) to install OpenProject on kubernetes. From fcd6d94361a27048bdcb9b6181f07762279394c8 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Mon, 21 Aug 2023 13:26:32 +0100 Subject: [PATCH 02/11] use OpenProject 13 --- compose/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 4453833..4ae4b5e 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -11,7 +11,7 @@ volumes: x-op-restart-policy: &restart_policy restart: unless-stopped x-op-image: &image - image: openproject/community:${TAG:-12} + image: openproject/community:${TAG:-13} x-op-app: &app <<: [*image, *restart_policy] environment: From d014d1ab5ba01fd2b3dfa5c68380fe6d1fc2b3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilsen=20Hern=C3=A1ndez?= <13445515+wilsenhc@users.noreply.github.com> Date: Tue, 22 Aug 2023 22:07:22 -0400 Subject: [PATCH 03/11] feat: set default TAG in .env.example as version 13 --- compose/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/.env.example b/compose/.env.example index b43748f..f9cb27e 100644 --- a/compose/.env.example +++ b/compose/.env.example @@ -6,7 +6,7 @@ # Please refer to our documentation to see all possible variables: # https://www.openproject.org/docs/installation-and-operations/configuration/environment/ # -TAG=12 +TAG=13 OPENPROJECT_HTTPS=false OPENPROJECT_HOST__NAME=localhost PORT=127.0.0.1:8080 From 8baac80c18120c927f37335eb077f8c95aa16227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Wed, 24 Apr 2024 08:15:50 +0200 Subject: [PATCH 04/11] Use OpenProject 14 --- compose/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 4ae4b5e..70751fa 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -11,7 +11,7 @@ volumes: x-op-restart-policy: &restart_policy restart: unless-stopped x-op-image: &image - image: openproject/community:${TAG:-13} + image: openproject/community:${TAG:-14} x-op-app: &app <<: [*image, *restart_policy] environment: From c9a717d32349b85ad6bf1de9db2636da322d6463 Mon Sep 17 00:00:00 2001 From: Philipp von Marklowski Date: Wed, 24 Apr 2024 21:09:29 +0200 Subject: [PATCH 05/11] Update docker-compose.yml See Issue #65 --- compose/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 70751fa..0eb5e78 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -11,7 +11,7 @@ volumes: x-op-restart-policy: &restart_policy restart: unless-stopped x-op-image: &image - image: openproject/community:${TAG:-14} + image: openproject/openproject:${TAG:-14} x-op-app: &app <<: [*image, *restart_policy] environment: From adce411f266a2c616be285268f324d1f430c87ba Mon Sep 17 00:00:00 2001 From: Eric Schubert <38206611+Kharonus@users.noreply.github.com> Date: Fri, 3 May 2024 10:51:53 +0200 Subject: [PATCH 06/11] [chore] update default data and readme for stable/14 (#69) --- compose/.env.example | 2 +- compose/README.md | 42 +++++++++++++++++++++++--------------- compose/docker-compose.yml | 2 -- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/compose/.env.example b/compose/.env.example index f9cb27e..2a1c337 100644 --- a/compose/.env.example +++ b/compose/.env.example @@ -6,7 +6,7 @@ # Please refer to our documentation to see all possible variables: # https://www.openproject.org/docs/installation-and-operations/configuration/environment/ # -TAG=13 +TAG=14 OPENPROJECT_HTTPS=false OPENPROJECT_HOST__NAME=localhost PORT=127.0.0.1:8080 diff --git a/compose/README.md b/compose/README.md index 8425430..3e91fb9 100644 --- a/compose/README.md +++ b/compose/README.md @@ -4,31 +4,37 @@ Clone this repository: - git clone https://github.com/opf/openproject-deploy --depth=1 --branch=stable/12 openproject +```shell +git clone https://github.com/opf/openproject-deploy --depth=1 --branch=stable/14 openproject +``` -Go to the compose folder: +Go to the compose folder: - cd openproject/compose - -Make sure you are using the latest version of the Docker images: - - docker-compose pull +```shell +cd openproject/compose +``` Copy the example `.env` file and edit any values you want to change: - cp .env.example .env - vim .env +```shell +cp .env.example .env +vim .env +``` -Launch the containers: +Make sure you are using the latest version of the Docker images and launch the containers: - docker-compose up -d +```shell +docker compose pull +docker compose up -d +``` After a while, OpenProject should be up and running on . **HTTPS/SSL** -By default OpenProject starts with the HTTPS option **enabled**, but it **does not** handle SSL termination itself. -This is usually done separately via a [reverse proxy setup](https://www.openproject.org/docs/installation-and-operations/installation/docker/#apache-reverse-proxy-setup). +By default OpenProject starts with the HTTPS option **enabled**, but it **does not** handle SSL termination itself. This +is usually done separately via a [reverse proxy +setup](https://www.openproject.org/docs/installation-and-operations/installation/docker/#apache-reverse-proxy-setup). Without this you will run into an `ERR_SSL_PROTOCOL_ERROR` when accessing OpenProject. See below how to disable HTTPS. @@ -117,15 +123,19 @@ For the complete documentation, please refer to https://docs.openproject.org/ins ### Network issues -If you're running into weird network issues and timeouts such as the one described in [OP#42802](https://community.openproject.org/work_packages/42802), you might have success in remove the two separate frontend and backend networks. This might be connected to using podman for orchestration, although we haven't been able to confirm this. +If you're running into weird network issues and timeouts such as the one described in +[OP#42802](https://community.openproject.org/work_packages/42802), you might have success in remove the two separate +frontend and backend networks. This might be connected to using podman for orchestration, although we haven't been able +to confirm this. ### SMTP setup fails: Network is unreachable. -Make sure your container has DNS resolution to access external SMTP server when set up as described in [OP#44515](https://community.openproject.org/work_packages/44515). +Make sure your container has DNS resolution to access external SMTP server when set up as described in +[OP#44515](https://community.openproject.org/work_packages/44515). ```yml worker: - dns: + dns: - "Your DNS IP" # OR add a public DNS resolver like 8.8.8.8 ``` diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 0eb5e78..75c0984 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.7" - networks: frontend: backend: From dbccaae404b977fdd1e1f1e36ded12b7a1e8207d Mon Sep 17 00:00:00 2001 From: Eric Schubert <38206611+Kharonus@users.noreply.github.com> Date: Fri, 17 May 2024 14:43:16 +0200 Subject: [PATCH 07/11] [#53464] replaced containered proxy with caddy (#70) * [#53464] replaced containered proxy with caddy - running compose stack work with slim container now - using caddy as a light weight proxy - tested with and without OPENPROJECT_RAILS__RELATIVE__URL__ROOT * rename doc root to avoid confusion, use slim as default container --------- Co-authored-by: Markus Kahl --- .gitignore | 3 +++ compose/.env.example | 2 +- compose/Caddyfile.template | 9 +++++++++ compose/docker-compose.yml | 15 +++++++++++---- compose/proxy-entrypoint.sh | 7 +++++++ 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 compose/Caddyfile.template create mode 100755 compose/proxy-entrypoint.sh diff --git a/.gitignore b/.gitignore index 82b0cd2..a499c1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +# Jetbrains IDE +.idea/ + *.swp *.tar.gz diff --git a/compose/.env.example b/compose/.env.example index 2a1c337..f46b278 100644 --- a/compose/.env.example +++ b/compose/.env.example @@ -6,7 +6,7 @@ # Please refer to our documentation to see all possible variables: # https://www.openproject.org/docs/installation-and-operations/configuration/environment/ # -TAG=14 +TAG=14-slim OPENPROJECT_HTTPS=false OPENPROJECT_HOST__NAME=localhost PORT=127.0.0.1:8080 diff --git a/compose/Caddyfile.template b/compose/Caddyfile.template new file mode 100644 index 0000000..05ba47a --- /dev/null +++ b/compose/Caddyfile.template @@ -0,0 +1,9 @@ +:80 { + root * /public + + reverse_proxy * http://${APP_HOST}:8080 + + file_server + + log +} diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 75c0984..5709e2b 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -5,11 +5,12 @@ networks: volumes: pgdata: opdata: + assets: x-op-restart-policy: &restart_policy restart: unless-stopped x-op-image: &image - image: openproject/openproject:${TAG:-14} + image: openproject/openproject:${TAG:-14-slim} x-op-app: &app <<: [*image, *restart_policy] environment: @@ -47,17 +48,21 @@ services: - backend proxy: - <<: [*image, *restart_policy] - command: "./docker/prod/proxy" + image: caddy:2 + <<: *restart_policy + command: "/usr/local/bin/proxy-entrypoint.sh" ports: - "${PORT:-8080}:80" environment: APP_HOST: web - OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" depends_on: - web networks: - frontend + volumes: + - ./Caddyfile.template:/etc/caddy/Caddyfile.template:ro + - ./proxy-entrypoint.sh:/usr/local/bin/proxy-entrypoint.sh:ro + - assets:/public:ro web: <<: *app @@ -77,6 +82,8 @@ services: timeout: 3s retries: 3 start_period: 30s + volumes: + - assets:/app/public autoheal: image: willfarrell/autoheal:1.2.0 diff --git a/compose/proxy-entrypoint.sh b/compose/proxy-entrypoint.sh new file mode 100755 index 0000000..8cc5ee8 --- /dev/null +++ b/compose/proxy-entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +sed 's|${APP_HOST}|'"$APP_HOST"'|g' /etc/caddy/Caddyfile.template > /etc/caddy/Caddyfile + +caddy run --config /etc/caddy/Caddyfile From 7c00ebe2df43e34981607a0dfee94965b79d2cb9 Mon Sep 17 00:00:00 2001 From: Eric Schubert <38206611+Kharonus@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:58:08 +0200 Subject: [PATCH 08/11] [chore] extract volumes from app anchor (#74) - yaml anchors do not support merging of lists - to add specific volumes to a service, you cannot use an alias to include shared volumes - hence, every service should do the volume definition by itself, once there is a single service that has a specific volume next to the common ones --- compose/docker-compose.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 5709e2b..089e958 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -25,8 +25,6 @@ x-op-app: &app RAILS_MAX_THREADS: ${RAILS_MAX_THREADS:-16} # set to true to enable the email receiving feature. See ./docker/cron for more options IMAP_ENABLED: "${IMAP_ENABLED:-false}" - volumes: - - "${OPDATA:-opdata}:/var/openproject/assets" services: db: @@ -83,6 +81,7 @@ services: retries: 3 start_period: 30s volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" - assets:/app/public autoheal: @@ -103,6 +102,8 @@ services: - db - cache - seeder + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" cron: <<: *app @@ -113,6 +114,8 @@ services: - db - cache - seeder + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" seeder: <<: *app @@ -120,4 +123,6 @@ services: restart: on-failure networks: - backend + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" From 9a9b458a2f6bfc384ff1744738e9709845f5e264 Mon Sep 17 00:00:00 2001 From: Eric Schubert <38206611+Kharonus@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:38:30 +0200 Subject: [PATCH 09/11] [chore] added documentation to the Caddyfile (#73) * [chore] added documentation to the Caddyfile - additional information for usage with reverse proxies * forward X-Forwarded headers in default config --- compose/Caddyfile.template | 12 +++++++++++- compose/README.md | 15 ++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/compose/Caddyfile.template b/compose/Caddyfile.template index 05ba47a..d213a75 100644 --- a/compose/Caddyfile.template +++ b/compose/Caddyfile.template @@ -1,7 +1,17 @@ :80 { root * /public - reverse_proxy * http://${APP_HOST}:8080 + reverse_proxy * http://${APP_HOST}:8080 { + # The following directives are needed to make the proxy forward explicitly the X-Forwarded-* headers. If unset, + # Caddy will reset them. See: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#defaults + # This is needed, if you are using a reverse proxy in front of the compose stack and Caddy is NOT your first + # point of contact. + # When using Caddy is reachable as a first point of contact, it is highly recommended to configure the server's + # global `trusted_proxies` directive. See: https://caddyserver.com/docs/caddyfile/options#trusted-proxies + + header_up X-Forwarded-Proto {header.X-Forwarded-Proto} + header_up X-Forwarded-For {header.X-Forwarded-For} + } file_server diff --git a/compose/README.md b/compose/README.md index 3e91fb9..734d2ab 100644 --- a/compose/README.md +++ b/compose/README.md @@ -30,7 +30,7 @@ docker compose up -d After a while, OpenProject should be up and running on . -**HTTPS/SSL** +### HTTPS/SSL By default OpenProject starts with the HTTPS option **enabled**, but it **does not** handle SSL termination itself. This is usually done separately via a [reverse proxy @@ -39,7 +39,13 @@ Without this you will run into an `ERR_SSL_PROTOCOL_ERROR` when accessing OpenPr See below how to disable HTTPS. -**PORT** +Be aware that if you want to use the integrated Caddy proxy as a proxy with outbound connections, you need to rewrite the +`Caddyfile`. In the default state, it is configured to forward the `X-Forwarded-*` headers from the reverse proxy in +front of it and not setting them itself. This is considered a security flaw and should instead be solved by configuring +`trusted_proxies` inside the `Caddyfile`. For more information read +the [Caddy documentation](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy). + +### PORT By default the port is bound to `0.0.0.0` means access to OpenProject will be public. See below how to change that. @@ -128,7 +134,6 @@ If you're running into weird network issues and timeouts such as the one describ frontend and backend networks. This might be connected to using podman for orchestration, although we haven't been able to confirm this. - ### SMTP setup fails: Network is unreachable. Make sure your container has DNS resolution to access external SMTP server when set up as described in @@ -136,6 +141,6 @@ Make sure your container has DNS resolution to access external SMTP server when ```yml worker: - dns: - - "Your DNS IP" # OR add a public DNS resolver like 8.8.8.8 + dns: + - "Your DNS IP" # OR add a public DNS resolver like 8.8.8.8 ``` From 6b10106a0fe300af7523ff80bd4f3abb95bc4bc5 Mon Sep 17 00:00:00 2001 From: Eric Schubert <38206611+Kharonus@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:46:15 +0200 Subject: [PATCH 10/11] [#55776] create proxy without static assets (#83) * [#55776] added custom image for proxy - based on caddy:2 - copy assets from openproject image into proxy image * [#55776] removed static asset serving from proxy - https://community.openproject.org/wp/55776 - apparently caddy correctly redirects asset requests to the web service --- compose/.gitignore | 2 ++ compose/docker-compose.yml | 26 +++++++------------------- compose/proxy-entrypoint.sh | 7 ------- compose/{ => proxy}/Caddyfile.template | 2 -- compose/proxy/Dockerfile | 8 ++++++++ 5 files changed, 17 insertions(+), 28 deletions(-) delete mode 100755 compose/proxy-entrypoint.sh rename compose/{ => proxy}/Caddyfile.template (97%) create mode 100644 compose/proxy/Dockerfile diff --git a/compose/.gitignore b/compose/.gitignore index 4c49bd7..08eb01f 100644 --- a/compose/.gitignore +++ b/compose/.gitignore @@ -1 +1,3 @@ .env + +docker-compose.override.yml diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 089e958..98c98a4 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -5,7 +5,6 @@ networks: volumes: pgdata: opdata: - assets: x-op-restart-policy: &restart_policy restart: unless-stopped @@ -25,6 +24,8 @@ x-op-app: &app RAILS_MAX_THREADS: ${RAILS_MAX_THREADS:-16} # set to true to enable the email receiving feature. See ./docker/cron for more options IMAP_ENABLED: "${IMAP_ENABLED:-false}" + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" services: db: @@ -46,21 +47,18 @@ services: - backend proxy: - image: caddy:2 + build: + context: ./proxy + args: + APP_HOST: web + image: openproject/proxy:${TAG:-14-slim} <<: *restart_policy - command: "/usr/local/bin/proxy-entrypoint.sh" ports: - "${PORT:-8080}:80" - environment: - APP_HOST: web depends_on: - web networks: - frontend - volumes: - - ./Caddyfile.template:/etc/caddy/Caddyfile.template:ro - - ./proxy-entrypoint.sh:/usr/local/bin/proxy-entrypoint.sh:ro - - assets:/public:ro web: <<: *app @@ -80,9 +78,6 @@ services: timeout: 3s retries: 3 start_period: 30s - volumes: - - "${OPDATA:-opdata}:/var/openproject/assets" - - assets:/app/public autoheal: image: willfarrell/autoheal:1.2.0 @@ -102,8 +97,6 @@ services: - db - cache - seeder - volumes: - - "${OPDATA:-opdata}:/var/openproject/assets" cron: <<: *app @@ -114,8 +107,6 @@ services: - db - cache - seeder - volumes: - - "${OPDATA:-opdata}:/var/openproject/assets" seeder: <<: *app @@ -123,6 +114,3 @@ services: restart: on-failure networks: - backend - volumes: - - "${OPDATA:-opdata}:/var/openproject/assets" - diff --git a/compose/proxy-entrypoint.sh b/compose/proxy-entrypoint.sh deleted file mode 100755 index 8cc5ee8..0000000 --- a/compose/proxy-entrypoint.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -e - -sed 's|${APP_HOST}|'"$APP_HOST"'|g' /etc/caddy/Caddyfile.template > /etc/caddy/Caddyfile - -caddy run --config /etc/caddy/Caddyfile diff --git a/compose/Caddyfile.template b/compose/proxy/Caddyfile.template similarity index 97% rename from compose/Caddyfile.template rename to compose/proxy/Caddyfile.template index d213a75..7de7b97 100644 --- a/compose/Caddyfile.template +++ b/compose/proxy/Caddyfile.template @@ -1,6 +1,4 @@ :80 { - root * /public - reverse_proxy * http://${APP_HOST}:8080 { # The following directives are needed to make the proxy forward explicitly the X-Forwarded-* headers. If unset, # Caddy will reset them. See: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#defaults diff --git a/compose/proxy/Dockerfile b/compose/proxy/Dockerfile new file mode 100644 index 0000000..5a6591b --- /dev/null +++ b/compose/proxy/Dockerfile @@ -0,0 +1,8 @@ +FROM caddy:2 + +COPY ./Caddyfile.template /etc/caddy/Caddyfile.template + +ARG APP_HOST +RUN sed 's|${APP_HOST}|'"$APP_HOST"'|g' /etc/caddy/Caddyfile.template > /etc/caddy/Caddyfile + +ENTRYPOINT ["caddy", "run", "--config", "/etc/caddy/Caddyfile"] From 63499105b9fb1d453e98dd7d095d9b2ff5cb02f9 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Mon, 2 Sep 2024 14:00:47 +0100 Subject: [PATCH 11/11] change compose up command to avoid any confusing involving the pulling of the proxy image --- compose/README.md | 15 ++++++++++++--- compose/docker-compose.yml | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compose/README.md b/compose/README.md index 734d2ab..f9f44d7 100644 --- a/compose/README.md +++ b/compose/README.md @@ -21,15 +21,24 @@ cp .env.example .env vim .env ``` -Make sure you are using the latest version of the Docker images and launch the containers: +Next you start up the containers in the background while making sure to pull the latest versions of all used images. ```shell -docker compose pull -docker compose up -d +docker compose up -d --build --pull always ``` After a while, OpenProject should be up and running on . +### Troubleshooting + +**pull access denied for openproject/proxy, repository does not exist or may require 'docker login': denied: requested access to the resource is denied** + +If you encounter this after `docker compose up` this is merely a warning which can be ignored. + +If this happens during `docker compose pull` this is simply a warning as well. +But it will result in the command's exit code to be a failure even though all images are pulled. +To prevent this you can add the `--ignore-buildable` option, running `docker compose pull --ignore-buildable`. + ### HTTPS/SSL By default OpenProject starts with the HTTPS option **enabled**, but it **does not** handle SSL termination itself. This diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 98c98a4..5b92e40 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -51,7 +51,7 @@ services: context: ./proxy args: APP_HOST: web - image: openproject/proxy:${TAG:-14-slim} + image: openproject/proxy <<: *restart_policy ports: - "${PORT:-8080}:80"