diff --git a/.github/workflows/web_docker.yml b/.github/workflows/web_docker.yml new file mode 100644 index 000000000..825b1e697 --- /dev/null +++ b/.github/workflows/web_docker.yml @@ -0,0 +1,33 @@ +name: AppFlowy Web image build and push +on: + workflow_dispatch: + inputs: + appflowy_web_version: + description: 'AppFlowy Web version' + required: true +jobs: + appflowy_web_image: + runs-on: ubuntu-22.04 + steps: + - name: Check out the repository + uses: actions/checkout@v3 + with: + fetch-depth: 1 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Build AppFlowy Web + run: | + export VERSION=${{ github.event.inputs.appflowy_web_version }} + export TAG=${VERSION#v} + docker buildx build --build-arg VERSION=${VERSION} --platform linux/amd64,linux/arm64 -t appflowyinc/appflowy-web:${TAG} -t appflowyinc/appflowy-web:latest -f docker/web/Dockerfile docker/web diff --git a/docker/web/Dockerfile b/docker/web/Dockerfile new file mode 100644 index 000000000..981c8486c --- /dev/null +++ b/docker/web/Dockerfile @@ -0,0 +1,18 @@ +FROM node:20.12.0 AS builder + +WORKDIR /app + +ARG VERSION=main + +RUN npm install -g pnpm@8.5.0 +RUN git clone --depth 1 --branch ${VERSION} https://github.com/AppFlowy-IO/AppFlowy-Web.git . +RUN pnpm install +ENV AF_BASE_URL=AF_BASE_URL_PLACEHOLDER +ENV AF_GOTRUE_URL=AF_GOTRUE_URL_PLACEHOLDER +RUN pnpm run build + +FROM nginx:alpine +COPY --from=builder /app/dist /usr/share/nginx/html/ +COPY nginx.conf /etc/nginx/nginx.conf +COPY env.sh /docker-entrypoint.d/env.sh +RUN chmod +x /docker-entrypoint.d/env.sh diff --git a/docker/web/env.sh b/docker/web/env.sh new file mode 100644 index 000000000..976b0abb8 --- /dev/null +++ b/docker/web/env.sh @@ -0,0 +1,12 @@ +#!bin/sh +STATIC_JS_FILE_PATH="/usr/share/nginx/html/static/js" +if [ -z "${AF_BASE_URL}" ]; then + echo "Error: AF_BASE_URL is not set." + exit 1 +fi +if [ -z "${AF_GOTRUE_URL}" ]; then + echo "Error: AF_BASE_URL is not set." + exit 1 +fi +find ${STATIC_JS_FILE_PATH} -type f -exec sed -i "s|AF_BASE_URL_PLACEHOLDER|$AF_BASE_UR|g" {} + +find ${STATIC_JS_FILE_PATH} -type f -exec sed -i "s|AF_GOTRUE_URL_PLACEHOLDER|$AF_GOTRUE_URL|g" {} + diff --git a/docker/web/nginx.conf b/docker/web/nginx.conf new file mode 100644 index 000000000..4e65cd510 --- /dev/null +++ b/docker/web/nginx.conf @@ -0,0 +1,48 @@ +worker_processes auto; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + # Basic optimization + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + + # GZIP compression + gzip on; + gzip_vary on; + gzip_min_length 1k; + gzip_comp_level 6; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript; + + server { + listen 80; + + root /usr/share/nginx/html; + index index.html; + + # Static files cache + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 30d; + add_header Cache-Control "public, no-transform"; + } + + # SPA routing + location / { + try_files $uri $uri/ /index.html; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + } + + # Deny access to non public path + location ~ /\. { + deny all; + } + } +}