From 0f121a8a35b65fea067ec8fd40833a361de66e00 Mon Sep 17 00:00:00 2001 From: Alex Kulikov Date: Mon, 29 Dec 2025 22:53:47 +0000 Subject: [PATCH 1/2] ci: build on ci --- .github/workflows/docker-build.yml | 67 ++++++++++++++++++++++ docker/docker-compose-db-nginx-testing.yml | 11 +++- docker/docker-compose-db-nginx.yml | 17 ++++-- 3 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/docker-build.yml diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000000..37125d924de --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,67 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - sysblok-dev + - sysblok-main + +env: + REGISTRY: ghcr.io + IMAGE_NAME: sysblok/focalboard/focalboard + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to Container Registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Determine image tags + id: tags + run: | + BRANCH_NAME=${GITHUB_REF#refs/heads/} + SHORT_SHA=${GITHUB_SHA::7} + + if [ "$BRANCH_NAME" = "sysblok-dev" ]; then + TAG="dev" + elif [ "$BRANCH_NAME" = "sysblok-main" ]; then + TAG="main" + else + TAG="$BRANCH_NAME" + fi + + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "sha_tag=${TAG}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "full_image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: | + ${{ steps.tags.outputs.full_image }}:${{ steps.tags.outputs.tag }} + ${{ steps.tags.outputs.full_image }}:${{ steps.tags.outputs.sha_tag }} + build-args: | + FOCALBOARD_ENVIRONMENT=${{ vars.FOCALBOARD_ENVIRONMENT || 'prod' }} + FOCALBOARD_ADMINS=${{ vars.FOCALBOARD_ADMINS || '' }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64 + diff --git a/docker/docker-compose-db-nginx-testing.yml b/docker/docker-compose-db-nginx-testing.yml index 9af974a5e2d..24c6a489a62 100644 --- a/docker/docker-compose-db-nginx-testing.yml +++ b/docker/docker-compose-db-nginx-testing.yml @@ -2,9 +2,14 @@ version: "3" services: app: - build: - context: ../ - dockerfile: docker/Dockerfile + # Use pre-built image from GitHub Container Registry + # Set FOCALBOARD_TAG environment variable to use 'dev' (default) or 'main' tag + # To authenticate: echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin + image: ghcr.io/sysblok/focalboard/focalboard:${FOCALBOARD_TAG:-dev} + # Uncomment below and comment 'image:' above to build locally instead + # build: + # context: ../ + # dockerfile: docker/Dockerfile depends_on: - focalboard-db expose: diff --git a/docker/docker-compose-db-nginx.yml b/docker/docker-compose-db-nginx.yml index 99ddd779f5f..79666604839 100644 --- a/docker/docker-compose-db-nginx.yml +++ b/docker/docker-compose-db-nginx.yml @@ -2,12 +2,17 @@ version: "3" services: app: - build: - context: ../ - dockerfile: docker/Dockerfile - args: - FOCALBOARD_ENVIRONMENT: ${FOCALBOARD_ENVIRONMENT:-prod} - FOCALBOARD_ADMINS: ${FOCALBOARD_ADMINS:-} + # Use pre-built image from GitHub Container Registry + # Set FOCALBOARD_TAG environment variable to use 'dev' (default) or 'main' tag + # To authenticate: echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin + image: ghcr.io/sysblok/focalboard/focalboard:${FOCALBOARD_TAG:-latest} + # Uncomment below and comment 'image:' above to build locally instead + # build: + # context: ../ + # dockerfile: docker/Dockerfile + # args: + # FOCALBOARD_ENVIRONMENT: ${FOCALBOARD_ENVIRONMENT:-prod} + # FOCALBOARD_ADMINS: ${FOCALBOARD_ADMINS:-} container_name: focalboard depends_on: - focalboard-db From 1626fa7830838173f5dd59f3e9a1f7be509606b6 Mon Sep 17 00:00:00 2001 From: Alex Kulikov Date: Mon, 29 Dec 2025 23:50:52 +0000 Subject: [PATCH 2/2] feat: use traefik routing --- docker/docker-compose-db-nginx-testing.yml | 45 ++++++++------- docker/docker-compose-db-nginx.yml | 67 ++++++---------------- 2 files changed, 43 insertions(+), 69 deletions(-) diff --git a/docker/docker-compose-db-nginx-testing.yml b/docker/docker-compose-db-nginx-testing.yml index 24c6a489a62..dc02e8d088f 100644 --- a/docker/docker-compose-db-nginx-testing.yml +++ b/docker/docker-compose-db-nginx-testing.yml @@ -10,43 +10,44 @@ services: # build: # context: ../ # dockerfile: docker/Dockerfile + container_name: focalboard-dev-app depends_on: - focalboard-db expose: - - 8001 + - 8000 + labels: + - "traefik.enable=true" + - "traefik.http.routers.focalboard-dev.rule=Host(`${FOCALBOARD_HOST}`)" + - "traefik.http.routers.focalboard-dev.entrypoints=web" + - "traefik.http.routers.focalboard-dev.middlewares=focalboard-dev-redirect" + - "traefik.http.routers.focalboard-dev-secure.rule=Host(`${FOCALBOARD_HOST}`)" + - "traefik.http.routers.focalboard-dev-secure.entrypoints=websecure" + - "traefik.http.routers.focalboard-dev-secure.tls.certresolver=le" + - "traefik.http.routers.focalboard-dev-secure.service=focalboard-dev" + - "traefik.http.middlewares.focalboard-dev-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.focalboard-dev-redirect.redirectscheme.permanent=true" + - "traefik.http.services.focalboard-dev.loadbalancer.server.port=8000" + - "traefik.http.services.focalboard-dev.loadbalancer.healthcheck.path=/api/v2/system/ping" + - "traefik.http.services.focalboard-dev.loadbalancer.healthcheck.interval=10s" environment: - - VIRTUAL_HOST=${FOCALBOARD_HOST} - - LETSENCRYPT_HOST=${FOCALBOARD_HOST} - FOCALBOARD_ENVIRONMENT=${FOCALBOARD_ENVIRONMENT:-dev} - - VIRTUAL_PORT=8001 - - VIRTUAL_PROTO=http + - FOCALBOARD_ADMINS=${FOCALBOARD_ADMINS:-} volumes: - "./config.json:/opt/focalboard/config.json" - fbdata:/opt/focalboard/data restart: always networks: + - proxy - default - proxy: - image: nginx:latest - restart: always - ports: - - "8443:8443" - volumes: - - ./nginx-testing.conf:/etc/nginx/conf.d/default.conf:ro - - ./client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro - networks: - - default - depends_on: - - app - focalboard-db: - image: postgres:latest + image: postgres:16 + container_name: focalboard-dev-db restart: always volumes: - pgdata:/var/lib/postgresql/data - type: bind - source: /backups + source: /backups/focalboard-dev target: /backups environment: POSTGRES_DB: boards @@ -56,3 +57,7 @@ services: volumes: fbdata: pgdata: + +networks: + proxy: + external: true diff --git a/docker/docker-compose-db-nginx.yml b/docker/docker-compose-db-nginx.yml index 79666604839..baafc8b1000 100644 --- a/docker/docker-compose-db-nginx.yml +++ b/docker/docker-compose-db-nginx.yml @@ -13,18 +13,28 @@ services: # args: # FOCALBOARD_ENVIRONMENT: ${FOCALBOARD_ENVIRONMENT:-prod} # FOCALBOARD_ADMINS: ${FOCALBOARD_ADMINS:-} - container_name: focalboard + container_name: focalboard-prod-app depends_on: - focalboard-db expose: - 8000 environment: - - VIRTUAL_HOST=${FOCALBOARD_HOST} - - LETSENCRYPT_HOST=${FOCALBOARD_HOST} - FOCALBOARD_ENVIRONMENT=${FOCALBOARD_ENVIRONMENT:-dev} - FOCALBOARD_ADMINS=${FOCALBOARD_ADMINS:-} - - VIRTUAL_PORT=8000 - - VIRTUAL_PROTO=http + labels: + - "traefik.enable=true" + - "traefik.http.routers.focalboard-prod.rule=Host(`${FOCALBOARD_HOST}`)" + - "traefik.http.routers.focalboard-prod.entrypoints=web" + - "traefik.http.routers.focalboard-prod.middlewares=focalboard-prod-redirect" + - "traefik.http.routers.focalboard-prod-secure.rule=Host(`${FOCALBOARD_HOST}`)" + - "traefik.http.routers.focalboard-prod-secure.entrypoints=websecure" + - "traefik.http.routers.focalboard-prod-secure.tls.certresolver=le" + - "traefik.http.routers.focalboard-prod-secure.service=focalboard-prod" + - "traefik.http.middlewares.focalboard-prod-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.focalboard-prod-redirect.redirectscheme.permanent=true" + - "traefik.http.services.focalboard-prod.loadbalancer.server.port=8000" + - "traefik.http.services.focalboard-prod.loadbalancer.healthcheck.path=/api/v2/system/ping" + - "traefik.http.services.focalboard-prod.loadbalancer.healthcheck.interval=10s" volumes: - "./config.json:/opt/focalboard/config.json" - fbdata:/opt/focalboard/data @@ -33,46 +43,9 @@ services: - proxy - default - proxy: - image: jwilder/nginx-proxy:latest - container_name: focalboard-proxy - restart: always - ports: - - "80:80" - - "443:443" - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro - - "html:/usr/share/nginx/html" - - "dhparam:/etc/nginx/dhparam" - - "vhost:/etc/nginx/vhost.d" - - "certs:/etc/nginx/certs" - - "letsencrypt-acme:/etc/acme.sh" - networks: - - proxy - - letsencrypt: - image: "nginxproxy/acme-companion:latest" - container_name: "letsencrypt-helper" - volumes: - - "html:/usr/share/nginx/html" - - "dhparam:/etc/nginx/dhparam" - - "vhost:/etc/nginx/vhost.d" - - "certs:/etc/nginx/certs" - - "/run/docker.sock:/var/run/docker.sock:ro" - - "letsencrypt-acme:/etc/acme.sh" - environment: - NGINX_PROXY_CONTAINER: "focalboard-proxy" - DEFAULT_EMAIL: ${LETSENCRYPT_EMAIL} - restart: "always" - depends_on: - - "proxy" - networks: - - proxy - focalboard-db: - image: postgres:latest - container_name: focalboard-postgres + image: postgres:16 + container_name: focalboard-prod-db restart: always volumes: - pgdata:/var/lib/postgresql/data @@ -87,12 +60,8 @@ services: volumes: fbdata: pgdata: - certs: - html: - vhost: - dhparam: - letsencrypt-acme: networks: proxy: + external: true