From ce6e465910a04ab0e3bc39220e472b758937ead6 Mon Sep 17 00:00:00 2001 From: Ivan Carlos de Almeida Date: Tue, 16 Dec 2025 04:45:03 -0300 Subject: [PATCH] first load --- .dockerignore | 8 + .github/workflows/release_build.yml | 240 ++++++++++++++++++++++++++++ .github/workflows/update_readme.yml | 78 +++++++++ .well-known/security.txt.template | 12 ++ Dockerfile | 42 +++++ LICENSE | 21 +++ README.md | 68 +++++++- docker/.env | 29 ++++ docker/docker-compose-full.yml | 43 +++++ docker/docker-compose.yml | 15 ++ favicon.ico | Bin 0 -> 15086 bytes index.html | 123 ++++++++++++++ manifest.json | 4 + robots.txt | 2 + startup.sh | 177 ++++++++++++++++++++ 15 files changed, 861 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/release_build.yml create mode 100644 .github/workflows/update_readme.yml create mode 100644 .well-known/security.txt.template create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 docker/.env create mode 100644 docker/docker-compose-full.yml create mode 100644 docker/docker-compose.yml create mode 100644 favicon.ico create mode 100644 index.html create mode 100644 manifest.json create mode 100644 robots.txt create mode 100644 startup.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2eac372 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git/ +.github/ +docker/ +.dockerignore +CNAME +Dockerfile +README.md +LICENSE diff --git a/.github/workflows/release_build.yml b/.github/workflows/release_build.yml new file mode 100644 index 0000000..fb79cd0 --- /dev/null +++ b/.github/workflows/release_build.yml @@ -0,0 +1,240 @@ +name: Build, Push, Publish + +on: + push: + branches: + - main + workflow_dispatch: + schedule: + - cron: '28 5 * * *' + workflow_run: + workflows: ["Sync Repo"] + types: + - completed + +jobs: + release: + name: Build & Release + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + + steps: + - name: 📥 Checkout code with full history and tags + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if any tags exist + id: check_tags_exist + run: | + git fetch --tags + TAG_COUNT=$(git tag | wc -l) + if [ "$TAG_COUNT" -eq 0 ]; then + echo "has_tags=false" >> "$GITHUB_OUTPUT" + echo "latest_tag=v0.0.0" >> "$GITHUB_OUTPUT" + else + echo "has_tags=true" >> "$GITHUB_OUTPUT" + LATEST_TAG=$(git describe --tags --abbrev=0) + echo "latest_tag=$LATEST_TAG" >> "$GITHUB_OUTPUT" + fi + + - name: Check if meaningful commits exist since latest tag + id: check_commits + run: | + if [ "${{ steps.check_tags_exist.outputs.has_tags }}" = "false" ]; then + # No tags exist, so we should create first release + echo "commit_count=1" >> "$GITHUB_OUTPUT" + CHANGED_FILES=$(git ls-files | grep -v '^manifest.json$' || true) + if [ -n "$CHANGED_FILES" ]; then + echo "changed_files<> "$GITHUB_OUTPUT" + printf '%s\n' "$CHANGED_FILES" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + else + echo "changed_files=Initial release" >> "$GITHUB_OUTPUT" + fi + else + LATEST_TAG="${{ steps.check_tags_exist.outputs.latest_tag }}" + CHANGED_FILES="$(git diff --name-only "${LATEST_TAG}..HEAD" | grep -v '^manifest.json$' || true)" + if [ -n "$CHANGED_FILES" ]; then + echo "commit_count=1" >> "$GITHUB_OUTPUT" + echo "changed_files<> "$GITHUB_OUTPUT" + printf '%s\n' "$CHANGED_FILES" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + else + echo "commit_count=0" >> "$GITHUB_OUTPUT" + fi + fi + + - name: Get latest release tag (from GitHub API) + id: get_latest_release + run: | + LATEST_RELEASE_TAG=$(curl -sL -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/latest" | jq -r .tag_name) + if [ -z "$LATEST_RELEASE_TAG" ] || [ "$LATEST_RELEASE_TAG" = "null" ]; then + LATEST_RELEASE_TAG="v1.0.0" + fi + echo "latest_release_tag=$LATEST_RELEASE_TAG" >> "$GITHUB_OUTPUT" + echo "latest_release_version=${LATEST_RELEASE_TAG#v}" >> "$GITHUB_OUTPUT" + + # ------------------------------- + # Sync manifest.json to last release version if behind (only when no meaningful commits) + # ------------------------------- + - name: 🛠 Ensure manifest.json matches latest release version + if: steps.check_commits.outputs.commit_count == '0' + run: | + if [ -f manifest.json ]; then + MANIFEST_VERSION=$(jq -r '.version // empty' manifest.json) + else + MANIFEST_VERSION="" + fi + LATEST_RELEASE_VERSION="${{ steps.get_latest_release.outputs.latest_release_version }}" + PYTHON_CODE="from packaging import version; \ + print(version.parse('$LATEST_RELEASE_VERSION') > version.parse('$MANIFEST_VERSION') if '$MANIFEST_VERSION' else True)" + NEED_UPDATE=$(python3 -c "$PYTHON_CODE") + if [ "$NEED_UPDATE" = "True" ]; then + echo "Updating manifest.json to version $LATEST_RELEASE_VERSION (sync with release)" + jq --arg v "$LATEST_RELEASE_VERSION" '.version = $v' manifest.json > tmp.json && mv tmp.json manifest.json + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git add manifest.json + git commit -m "Sync manifest.json to release $LATEST_RELEASE_VERSION [🔄]" || echo "Nothing to commit" + git push origin main || true + else + echo "Manifest.json is already up-to-date with the latest release." + fi + + # ------------------------------- + # Continue normal workflow if commits exist + # ------------------------------- + - name: 📃 Get list of changed files (Markdown bullet list) + if: steps.check_commits.outputs.commit_count != '0' + id: changed_files + run: | + BULLET_LIST="$(printf '%s\n' "${{ steps.check_commits.outputs.changed_files }}" | sed 's/^/- /')" + echo "CHANGED<> "$GITHUB_OUTPUT" + printf '%s\n' "$BULLET_LIST" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + COUNT="$(printf '%s\n' "${{ steps.check_commits.outputs.changed_files }}" | wc -l)" + echo "COUNT=$COUNT" >> "$GITHUB_OUTPUT" + + - name: Get manifest version + if: steps.check_commits.outputs.commit_count != '0' + id: get_manifest_version + run: | + if [ -f manifest.json ]; then + MANIFEST_VERSION=$(jq -r '.version // empty' manifest.json) + if [ -z "$MANIFEST_VERSION" ] || [ "$MANIFEST_VERSION" = "null" ]; then + MANIFEST_VERSION="1.0.0" + fi + else + MANIFEST_VERSION="1.0.0" + fi + echo "manifest_version=$MANIFEST_VERSION" >> "$GITHUB_OUTPUT" + + - name: Pick base version + if: steps.check_commits.outputs.commit_count != '0' + id: pick_base_version + run: | + LATEST_RELEASE="${{ steps.get_latest_release.outputs.latest_release_version }}" + MANIFEST="${{ steps.get_manifest_version.outputs.manifest_version }}" + BASE_VERSION=$(python3 -c "from packaging import version; \ + print(str(max(version.parse('$LATEST_RELEASE'), version.parse('$MANIFEST'))))") + echo "base_version=$BASE_VERSION" >> "$GITHUB_OUTPUT" + + - name: 🔢 Determine version + if: steps.check_commits.outputs.commit_count != '0' + id: version + run: | + BASE_VERSION="${{ steps.pick_base_version.outputs.base_version }}" + IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION" + COUNT="${{ steps.changed_files.outputs.COUNT }}" + if [ "$COUNT" -ge 5 ]; then + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + elif [ "$COUNT" -ge 3 ]; then + MINOR=$((MINOR + 1)) + PATCH=0 + else + PATCH=$((PATCH + 1)) + fi + NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" + REPO_NAME="$(basename "$GITHUB_REPOSITORY")" + ZIP_NAME="${REPO_NAME}-${NEW_VERSION}.zip" + echo "VERSION=$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "ZIP_NAME=$ZIP_NAME" >> "$GITHUB_OUTPUT" + echo "REPO_NAME=$REPO_NAME" >> "$GITHUB_OUTPUT" + + - name: 🛠 Update or create manifest.json + if: steps.check_commits.outputs.commit_count != '0' + run: | + VERSION="${{ steps.version.outputs.VERSION }}" + AUTHOR="Ivan Carlos" + VERSION_FILE="manifest.json" + if [ -f "$VERSION_FILE" ]; then + jq --arg v "$VERSION" --arg a "$AUTHOR" \ + '.version = $v | .author = $a' "$VERSION_FILE" > tmp.json && mv tmp.json "$VERSION_FILE" + else + echo "{ \"version\": \"$VERSION\", \"author\": \"$AUTHOR\" }" > "$VERSION_FILE" + fi + + - name: 💾 Commit and push updated manifest.json + if: steps.check_commits.outputs.commit_count != '0' + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git add manifest.json + git commit -m "Update manifest version to ${{ steps.version.outputs.VERSION }} [▶️]" || echo "Nothing to commit" + git push origin main + + - name: 📦 Create ZIP package (excluding certain files) + if: steps.check_commits.outputs.commit_count != '0' + run: | + ZIP_NAME="${{ steps.version.outputs.ZIP_NAME }}" + zip -r "$ZIP_NAME" . -x ".git/*" ".github/*" "docker/*" ".dockerignore" "CNAME" "Dockerfile" "README.md" "LICENSE" + + - name: 🚀 Create GitHub Release + if: steps.check_commits.outputs.commit_count != '0' + uses: softprops/action-gh-release@v2 + with: + tag_name: "v${{ steps.version.outputs.VERSION }}" + name: "${{ steps.version.outputs.REPO_NAME }} v${{ steps.version.outputs.VERSION }}" + body: | + ### Changelog + Files changed in this release: + ${{ steps.changed_files.outputs.CHANGED }} + files: ${{ steps.version.outputs.ZIP_NAME }} + + # ----- Docker steps ----- + - name: 🔍 Check if Dockerfile exists + if: steps.check_commits.outputs.commit_count != '0' + id: dockerfile_check + run: | + if [ -f Dockerfile ]; then + echo "exists=true" >> "$GITHUB_OUTPUT" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: 🛠 Set up Docker Buildx + if: steps.check_commits.outputs.commit_count != '0' && steps.dockerfile_check.outputs.exists == 'true' + uses: docker/setup-buildx-action@v3 + + - name: 🔐 Login to GitHub Container Registry + if: steps.check_commits.outputs.commit_count != '0' && steps.dockerfile_check.outputs.exists == 'true' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: 🐳 Build and Push Docker image + if: steps.check_commits.outputs.commit_count != '0' && steps.dockerfile_check.outputs.exists == 'true' + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ghcr.io/${{ github.repository }}:latest diff --git a/.github/workflows/update_readme.yml b/.github/workflows/update_readme.yml new file mode 100644 index 0000000..b635451 --- /dev/null +++ b/.github/workflows/update_readme.yml @@ -0,0 +1,78 @@ +name: Update README + +# Allow GitHub Actions to commit and push changes +permissions: + contents: write + +on: + workflow_dispatch: + schedule: + - cron: '0 4 * * *' # Every day at 4 AM UTC + +jobs: + update-readme: + runs-on: ubuntu-latest + + env: + SOURCE_REPO: ivancarlosti/.github + SOURCE_BRANCH: main + + steps: + - name: Checkout current repository + uses: actions/checkout@v4 + + - name: Checkout source README template + uses: actions/checkout@v4 + with: + repository: ${{ env.SOURCE_REPO }} + ref: ${{ env.SOURCE_BRANCH }} + path: source_readme + + - name: Update README.md (buttons and footer) + run: | + set -e + REPO_NAME="${GITHUB_REPOSITORY##*/}" + + # --- Extract buttons block from source --- + BUTTONS=$(awk '//{flag=1;next}//{flag=0}flag' source_readme/README.md) + BUTTONS_UPDATED=$(echo "$BUTTONS" | sed "s/\.github/${REPO_NAME}/g") + + # --- Extract footer block from source (everything from onward) --- + FOOTER=$(awk '//{flag=1}flag' source_readme/README.md) + + # --- Replace buttons section in README.md --- + UPDATED=$(awk -v buttons="$BUTTONS_UPDATED" ' + BEGIN { skip=0 } + // { + print + print buttons + skip=1 + next + } + // && skip { + print + skip=0 + next + } + !skip { print } + ' README.md) + + # --- Replace everything after with FOOTER --- + echo "$UPDATED" | awk -v footer="$FOOTER" ' + // { + print footer + found=1 + exit + } + { print } + ' > README.tmp && mv README.tmp README.md + + - name: Remove source_readme from git index + run: git rm --cached -r source_readme || true + + - name: Commit and push changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + file_pattern: README.md + commit_message: "Sync README from template [▶️]" + branch: ${{ github.ref_name }} diff --git a/.well-known/security.txt.template b/.well-known/security.txt.template new file mode 100644 index 0000000..565acad --- /dev/null +++ b/.well-known/security.txt.template @@ -0,0 +1,12 @@ +# Based on https://securitytxt.org/ +# All inquiries should be directed to the following communication channels: + +Contact: {{CONTACT_LINK1}} +Contact: {{CONTACT_LINK2}} +Contact: {{CONTACT_LINK3}} + +Preferred-Languages: {{LANG}} + +Policy: {{POLICY}} + +Expires: {{EXPIREDATE_ISO}} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fcc2ecb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +FROM nginx:alpine + +# Copy entire project folder content into /usr/share/nginx/html +COPY . /usr/share/nginx/html/ + +# Copy startup.sh to root and make it executable +COPY startup.sh /startup.sh +RUN chmod +x /startup.sh + +# Create a minimal nginx.conf with access restriction for /startup.sh inline +RUN printf '%s\n' \ + 'worker_processes auto;' \ + '' \ + 'events { worker_connections 1024; }' \ + '' \ + 'http {' \ + ' include mime.types;' \ + ' default_type application/octet-stream;' \ + ' sendfile on;' \ + '' \ + ' server {' \ + ' listen 80;' \ + ' server_name localhost;' \ + ' root /usr/share/nginx/html;' \ + ' index index.html index.htm;' \ + '' \ + ' location = /startup.sh {' \ + ' deny all;' \ + ' return 403;' \ + ' }' \ + '' \ + ' location / {' \ + ' try_files $uri $uri/ =404;' \ + ' }' \ + ' }' \ + '}' \ + > /etc/nginx/nginx.conf + +EXPOSE 80 + +# Use startup.sh as entrypoint to replace placeholders, then run nginx +ENTRYPOINT ["/startup.sh"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3c1c4d9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Ivan Carlos de Almeida + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bb0d954..1ac5641 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,68 @@ -# parkingpage +# Parking Page +Dynamic HTML to put on parking domains + +[![Stars](https://img.shields.io/github/stars/ivancarlosti/parkingpage?label=⭐%20Stars&color=gold&style=flat)](https://github.com/ivancarlosti/parkingpage/stargazers) +[![Watchers](https://img.shields.io/github/watchers/ivancarlosti/parkingpage?label=Watchers&style=flat&color=red)](https://github.com/sponsors/ivancarlosti) +[![Forks](https://img.shields.io/github/forks/ivancarlosti/parkingpage?label=Forks&style=flat&color=ff69b4)](https://github.com/sponsors/ivancarlosti) +[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/ivancarlosti/parkingpage?label=Activity)](https://github.com/ivancarlosti/parkingpage/pulse) +[![GitHub Issues](https://img.shields.io/github/issues/ivancarlosti/parkingpage?label=Issues&color=orange)](https://github.com/ivancarlosti/parkingpage/issues) +[![License](https://img.shields.io/github/license/ivancarlosti/parkingpage?label=License)](LICENSE) +[![GitHub last commit](https://img.shields.io/github/last-commit/ivancarlosti/parkingpage?label=Last%20Commit)](https://github.com/ivancarlosti/parkingpage/commits) +[![Security](https://img.shields.io/badge/Security-View%20Here-purple)](https://github.com/ivancarlosti/parkingpage/security) +[![Code of Conduct](https://img.shields.io/badge/Code%20of%20Conduct-2.1-4baaaa)](https://github.com/ivancarlosti/parkingpage?tab=coc-ov-file) +[![GitHub Sponsors](https://img.shields.io/github/sponsors/ivancarlosti?label=GitHub%20Sponsors&color=ffc0cb)][sponsor] + + +## Details +You can also run it on docker compose adding it to your container, do not forget to manage ports and certificates using a reverse proxy or improving nginx service: + +``` +name: yourproject + +services: + git: + image: alpine/git:latest + container_name: yourproject-gitcloner + volumes: + - ./www:/www + working_dir: /www + entrypoint: /bin/sh -c "while true; do if [ -d .git ]; then git pull; else git clone --recurse-submodules -j8 https://github.com/ivancarlosti/parkingpage.git .; fi; sleep 600; done" + restart: unless-stopped + + nginx: + image: nginx:alpine + container_name: yourproject-nginx + volumes: + - ./www:/usr/share/nginx/html + ports: + - "80:80" + restart: unless-stopped + depends_on: + - git +``` + + +--- + +## 🧑‍💻 Consulting and technical support +* For personal support and queries, please submit a new issue to have it addressed. +* For commercial related questions, please [**contact me**][ivancarlos] for consulting costs. + +## 🩷 Project support +| If you found this project helpful, consider | +| :---: | +[**buying me a coffee**][buymeacoffee], [**donate by paypal**][paypal], [**sponsor this project**][sponsor] or just [**leave a star**](../..)⭐ +|Thanks for your support, it is much appreciated!| + +[cc]: https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-code-of-conduct-to-your-project +[contributing]: https://docs.github.com/en/articles/setting-guidelines-for-repository-contributors +[security]: https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository +[support]: https://docs.github.com/en/articles/adding-support-resources-to-your-project +[it]: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser +[prt]: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository +[funding]: https://docs.github.com/en/articles/displaying-a-sponsor-button-in-your-repository +[ivancarlos]: https://ivancarlos.it +[buymeacoffee]: https://www.buymeacoffee.com/ivancarlos +[paypal]: https://icc.gg/donate +[sponsor]: https://github.com/sponsors/ivancarlosti diff --git a/docker/.env b/docker/.env new file mode 100644 index 0000000..6caf122 --- /dev/null +++ b/docker/.env @@ -0,0 +1,29 @@ +WEB_PORT=10001:80 + +LOGO_URL=logo.png +TITLE=Parking Page +SHOW_TITLE=true +SUBTEXT=Under Construction + +EMAIL=email@example.com +LINK_EMAIL=mailto:email@example.com + +PHONE=+55 11 9XXXX-XXXX +LINK_PHONE=https://wa.me/55119XXXXXXXX + +CREDIT_LOGO_URL=https://s3.sa-east-1.amazonaws.com/envio.icc.gg/logo_256x256-7ds3h.png +CREDIT_LINK=https://ivancarlos.com.br/ + +FAVICON_PNG_URL=/favicon-96x96.png +FAVICON_SVG_URL=/favicon.svg +FAVICON_ICO_URL=/favicon.ico +APPLE_TOUCH_ICON_URL=/apple-touch-icon.png + +CONTACT_LINK1=mailto:security@example.com +CONTACT_LINK2=https://example.com/security +CONTACT_LINK3=https://example.com/contact + +LANG=pt, en, es +POLICY=https://example.com/secpolicy + +EXPIREDATE_ISO=2034-04-15T15:00:00.000Z diff --git a/docker/docker-compose-full.yml b/docker/docker-compose-full.yml new file mode 100644 index 0000000..e8a0514 --- /dev/null +++ b/docker/docker-compose-full.yml @@ -0,0 +1,43 @@ +name: parkingpage + +services: + parkingpage: + image: ghcr.io/ivancarlosti/parkingpage:latest + env_file: .env + container_name: parkingpage + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.php.rule=Host(`subdomain.example.com`)" ### CHANGE subdomain.example.com TO YOUR DOMAIN ### + - "traefik.http.routers.php.entrypoints=websecure" + - "traefik.http.routers.php.tls.certresolver=letsencrypt" + networks: + - web + + traefik: + image: traefik:latest + container_name: parkingpage-traefik + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./traefik:/etc/traefik + command: + - --api.dashboard=true + - --providers.docker=true + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + - --entrypoints.web.http.redirections.entrypoint.to=websecure + - --entrypoints.web.http.redirections.entrypoint.scheme=https + - --certificatesresolvers.letsencrypt.acme.email=email@example.com ### CHANGE email@example.com TO YOUR EMAIL ADDRESS ### + - --certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme.json + - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web + networks: + - web + restart: unless-stopped + +networks: + web: + external: false diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..81a3fd1 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,15 @@ +name: parkingpage + +services: + parkingpage: + image: ghcr.io/ivancarlosti/parkingpage:latest + env_file: .env + container_name: parkingpage + restart: unless-stopped + entrypoint: ["/startup.sh"] + ports: + - "${WEB_PORT:-10001:80}" # default port exposted 10001 + deploy: + resources: + limits: + memory: 128M diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ae3794588b467ed2e7bddef13a6cc62b5ace7fa5 GIT binary patch literal 15086 zcmd6t33yf26@>!{GAKh3tV1!hT7fv*m%c;B>?lpH1;&m2-xdII??>Mu7p zw+6@o4ZY`}L4#_52SI)J{Tvz19l$4`C_#TUv~LD$KzC62=cXUMSzrfm!4 zzwj7(D}%31yY$}^#BRfG?si2m+AaYbL7w+xJOa4>t&Hn=OpL~_0{zoGhVNmp6%2RZ z{$ey$QEhmZX`Su8u(js6{vQ~pdrXYJmB6o`r#*&mr1{^rd1=`D^qNA;f#6QiMLpm* zfwbP`Iv77-KKZwRS{@Ul=`+)*V|c}5jC-4ZEv);z33wD7;&aN&Xc=nS8pCN|wb?_x zHuh}uN&k1ChR4L{`55^5f5&6^&NcsbxIQ=tXsyllIpt;3rt4kLrgWg|TRJcG+Kit! zpZuFZRga0$^AF(q|K%}!CkFl&j4Od<;9Z|nUPgjwUA@?$>^3PE+BS5`(xZJ_mhmTJHk0oQ+&*TwhGz`vexs>j4=Sprlg(c1HL)uJ-5>tDtoE2QdR{e6u0MP}zizSD zG@tR&;79O?=a-eyq;*BtPqd$b=L6|n>NOc30DSMG*b0w1qva*w+QlaXvDp?|DIenl zz==SxjqabWOr< zg6~0z=ZNQ&hS5|H6oQ4C4_7f;Iv?^HjI|eX?cxtT=8TS~K&b!xAT}h3HIg5Diuv@q zQ>H(3v^8CmRe*7(+0r=5i!yE=_!WEKW6o%KGSH~wxFU#M7Q~|a411vY%6t!_!`GU= z>V>WM6F<+ry+6LQ0>9$%=c~^_%VU8?>F*!JP7h)O<;Tu4Uwp6U^GnOUkUp)I z^#lJf^ZT*=)nm@+m~8r7|CAu6J+rhb_CesEZ@yFAS6W6-ThsJ{=U~5UzW>6}I;R-p z(dKvkFM5tMIwqPH*FVQ&Vq!}zUI0gXKlpC*#qX6cXLn=t_`Umk&BNBdS^FAkTn^&b zB;$#|wTt7|fcHR$uko(G#4!?o&b01;k5nFfjrsQa9!A3))6_$?7#|9@nJ-U1|HC)K z{C*7cJm!p!ai+!fm$=7?Jru;xR33J7^DXl_rRAwpr!EIEaI$jXR%Xi=e{Zzd(?Lw} z64!?2pkqv+Psi|){QieMDv0-#AG;RNeZ39T@VR?p`qu$Jg6~1JPlT@k(k4s@Yhb?? z#1#Ky7}uEow*o)+;?*F24KnukNX5olj^1Vbz3sHbn!B>;-_G=W07pIGk>-=WAz?1| zyFpCx>0w-Bbc_I@e%+@B_&mnv1o6iL|6KDAaNnMo{x_JOCw#6nnNRvIbH5n-^B|^p zd~Ni3Xc!jg({bp!s2#+c2J!g4fp4_=cRDAYo5=K^V|qq<3_IU^(ieYkWLz1n3u21j z?|IH>@coSc2HI;L7Q_$1)^)DGS-j{K8 zuo)=k_=Crt(QuvVaQ)gFGz#L{^Xr;YT*pyYF}M-XyG)7S%kvT$4b{LhAe{{rhiic! zfb?yV?Rkt323vt^7svMoK9Bz4{prVWipRywSq?m=&;RmO13E7KCed?2{@wl2U*~if zsH%BzW8nJMFs|(RjE@33R*#FbJ?>2J9>BFZcksBFcwR84tHz8B-@Spx5^E#=3xb&Izag<7+BzlCU*elH@u9(-1&KAvYO}Zb z9oVcr4q8Wrb+Ef9(O=^ErupdV7-;kBr^J0i{8F2v^=GFwAnd!hW3)E}&!9E_-l!Vb z{q4A-b8q9Fo|WinZ`xeDxWsb;`wXxcwAx#JrJ0X5JsYZrbFps$e%(0t3Fl~xrYsO@ z*Z9$J9=4tV(Q_;G@6R#X?@FS-XJSuuh41Ko9M2}st7seTQ<7XiS0?H}e@o!Hofjs~ zt7sejPb4}2CDwImLiG;^{2d@Mry^{$>mA3}9p`fsd!sWWiT+LaO8s7#SaV<4Xm1Ff2SvegoRwG` zorfpr{~PvxS?3db@5x5Do(q?NFYFki?+0NXTI-vBT{Hbbg|73VmR*g}UK8Yi7KwAv zTN_LVhbG3#W5;3}C&pqM(qgfd*~Oe+%tiUxqvhX`pPeNx%wLotUYoz@VDb3;MU}*3 z5_nSnqH6Nj$;Jq^cDwBSh}#F8u_3Ln zeRkeL<3-{{*?GmBnwO7VkPX)^=9O?E_R1OPyAzJ>h8L&ieX01G)Vwv~SZZGJ`P!MI z^F}<8i|1$O7xR~k#mDpGWrDU~U;lqvTt|AhiT}SQg9i^D4dUn1Fw4% zdd~(wf?@94*G#|YJrVYIj+ea$eP@6eh`vw4Wqzmhn$Gmoca%p!w5Nw31$rJl?{nyv zYyG3|>x}z>r@(M|7MeC_Md|OldRuz>)+Ds?r;w<)903!>G3wuJ7jO`*HXER-#7bluSNX{)^DAB zj1Mz=6xQ@DYK;J;_0Q$Y7Z({HYvuAoO>gQO$Lbwu01>3+(P|e2ie^>Xs zT`~1rfC8ZBpT7C&eoNJScmt50T+gTe?Lfc35M6WdDzH#<;EzCOpT8%jb|3JD=D~jl zt8A?Ab=!gZPxd<0z7=@?!{x_b48F4QlZri_b@cyUEkA0u{n!vgr zOLYxW->yv7Rt(nqqkhr9Rl%Li zmM{JdoVvY%pZ~tf#cpT5=vxNkB_OU@bCUg0Hy6xT%*N`~&g`og`|(HTM1JaCWxb>! z^25iO??s#Q2zE4DA)U~H?)>kVIuK>Ch4l+CZx1K>>gSuUTpZ^B~e*u22iCPcOvN^l_R!yIlK*!b` zNXvFm;Pn{a4gCB^zq4Z0?QFHBVUEvd{Gs{v3_QffJH12ud}?0@wgY`9KMttZhd~@O z-v77mr|x-HTm9p|G2;d1kFFoaYe9)`gI+^SZC!gG+qk3kTHtfA=bBHtqTfg{YId+b z>i?F{XFS9F*V?>SuwU|cB2%*oxL$r(>!13}^m&XIm{0!bK39yIzqUT=A3tA=$C*FJ z=Jmmj)<>_oE2jQE*6R+RgRN(gdJA3MubS3J{iA1&VvPHn|4E-)TBg45v-*1uzE7>U z`p2KA^zi+T`hVy18T&r$9ru-%sjq#Hp7rrHlkwNUkNs}yEx11(c@SU_HXF1 zeZ}=CiLIwJ-@s<=pFuBopeO|Vb!Jg;R*fQm$zSHKK;V~&qDp1`5b!J zPw0QK$MzM|PuJfy!0&-3UYp)^tp7$>&$%>@?Q5ogI+zUN*BJc{1bPRK-VyeuXKd?? z;!icpCd6Xt<6}kXjjKT)vG71`ut1WD5Fs_SZRfC+W|Lzr` z(du3~5q9*-$tuR!tfF>fN5}N}ClP!iIv%lgKqe^dcM6VO>w&KcL#Iuf)^*^(ffsQ6 z+H>kzuWOQuJO2f_+RF;BlHZg3OUZcyXf6Ad@`dovabn}80hB)gTn(c0z&y`aZ|zgm zU-@gu??}F$!CwRQ*Iu(9(C?x5QP0)BCL8nv4};cVJ^3BTSKn_zdoU5`KGO5M7VvzX zJAKC-0mcKJzXI~xlHZDX8$c&8%8(6fZT9>&%)b@r-^Q*7oxvvZ+mPR!dD<^t0j>l0 zgB!uw!1Hyy%F(g+09S&|)2B~Ao&1xTr~6-fjElfrpx;#I#q+g>)CBXvIiN52j{H;l z_wRoq^VDBGTZ7j?T@al={fNvJ^bXt=WPqE2`Zp)PF>`hNcYq^6H&6w{ub-fX*U~xM zME*(S>wQ7z{{iJVN+g>>j^}HSw1NC4{{imfFlqn* literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..0b53191 --- /dev/null +++ b/index.html @@ -0,0 +1,123 @@ + + + + + + {{TITLE}} + + + + + + + + + + +
+ + + + + +

{{TITLE}}

+ + + +

{{SUBTEXT}}

+ + +
+ + 📧 {{EMAIL}} + + + + 📞 {{PHONE}} + +
+
+ + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..2a97592 --- /dev/null +++ b/manifest.json @@ -0,0 +1,4 @@ +{ + "version": "2.2.24", + "author": "Ivan Carlos" +} diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..c2a49f4 --- /dev/null +++ b/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / diff --git a/startup.sh b/startup.sh new file mode 100644 index 0000000..19c27f8 --- /dev/null +++ b/startup.sh @@ -0,0 +1,177 @@ +#!/bin/sh + +HTML_FILE="/usr/share/nginx/html/index.html" + +echo "Starting environment variable replacement in $HTML_FILE..." + +replace_placeholder() { + placeholder=$1 + value=$2 + + # Escape slashes and ampersands for sed + escaped_value=$(printf '%s\n' "$value" | sed -e 's/[\/&]/\\&/g') + + sed -i "s|{{${placeholder}}}|${escaped_value}|g" "$HTML_FILE" +} + +remove_block() { + block_name=$1 + sed -i "//,//d" "$HTML_FILE" +} + +is_true() { + case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in + true) return 0 ;; + *) return 1 ;; + esac +} + +# Load environment variables or defaults +LOGO_URL="${LOGO_URL:-}" +TITLE="${TITLE:-Parking Page}" +SHOW_TITLE="${SHOW_TITLE:-true}" +SUBTEXT="${SUBTEXT:-}" + +EMAIL="${EMAIL:-}" +LINK_EMAIL="${LINK_EMAIL:-}" + +PHONE="${PHONE:-}" +LINK_PHONE="${LINK_PHONE:-}" + +CREDIT_LOGO_URL="${CREDIT_LOGO_URL:-https://s3.sa-east-1.amazonaws.com/envio.icc.gg/logo_256x256-7ds3h.png}" +CREDIT_LINK="${CREDIT_LINK:-https://ivancarlos.com.br/}" + +FAVICON_PNG_URL="${FAVICON_PNG_URL:-/favicon-96x96.png}" +FAVICON_SVG_URL="${FAVICON_SVG_URL:-/favicon.svg}" +FAVICON_ICO_URL="${FAVICON_ICO_URL:-/favicon.ico}" +APPLE_TOUCH_ICON_URL="${APPLE_TOUCH_ICON_URL:-/apple-touch-icon.png}" + +# HTML placeholders replacement and conditional blocks + +if [ -z "$LOGO_URL" ]; then + remove_block "LOGO" +else + replace_placeholder "LOGO_URL" "$LOGO_URL" +fi + +# Always replace and apple-mobile-web-app-title meta content +replace_placeholder "TITLE" "$TITLE" + +# Conditionally show/hide <h1>{{TITLE}}</h1> block +if is_true "$SHOW_TITLE" && [ -n "$TITLE" ]; then + replace_placeholder "TITLE" "$TITLE" +else + remove_block "TITLE" +fi + +if [ -z "$SUBTEXT" ]; then + remove_block "SUBTEXT" +else + replace_placeholder "SUBTEXT" "$SUBTEXT" +fi + +if [ -z "$EMAIL" ]; then + remove_block "EMAIL" +else + if [ -z "$LINK_EMAIL" ]; then + LINK_EMAIL="mailto:$EMAIL" + fi + replace_placeholder "EMAIL" "$EMAIL" + replace_placeholder "LINK_EMAIL" "$LINK_EMAIL" +fi + +if [ -z "$PHONE" ] || [ -z "$LINK_PHONE" ]; then + remove_block "PHONE" +else + replace_placeholder "PHONE" "$PHONE" + replace_placeholder "LINK_PHONE" "$LINK_PHONE" +fi + +replace_placeholder "CREDIT_LOGO_URL" "$CREDIT_LOGO_URL" +replace_placeholder "CREDIT_LINK" "$CREDIT_LINK" + +replace_placeholder "FAVICON_PNG_URL" "$FAVICON_PNG_URL" +replace_placeholder "FAVICON_SVG_URL" "$FAVICON_SVG_URL" +replace_placeholder "FAVICON_ICO_URL" "$FAVICON_ICO_URL" +replace_placeholder "APPLE_TOUCH_ICON_URL" "$APPLE_TOUCH_ICON_URL" + +# ----------------------------- +# Generate security.txt from template +# ----------------------------- + +generate_security_txt() { + TEMPLATE_FILE="/usr/share/nginx/html/.well-known/security.txt.template" + OUTPUT_FILE="/usr/share/nginx/html/.well-known/security.txt" + + CONTACT_LINK1="${CONTACT_LINK1:-}" + CONTACT_LINK2="${CONTACT_LINK2:-}" + CONTACT_LINK3="${CONTACT_LINK3:-}" + LANG="${LANG:-}" + POLICY="${POLICY:-}" + EXPIREDATE_ISO="${EXPIREDATE_ISO:-}" + + # Check required vars + if [ -z "$EXPIREDATE_ISO" ]; then + echo "EXPIREDATE_ISO not set. Skipping security.txt generation." + rm -f "$TEMPLATE_FILE" + return + fi + + if [ -z "$CONTACT_LINK1" ] && [ -z "$CONTACT_LINK2" ] && [ -z "$CONTACT_LINK3" ]; then + echo "No CONTACT_LINK variables set. Skipping security.txt generation." + rm -f "$TEMPLATE_FILE" + return + fi + + if [ ! -f "$TEMPLATE_FILE" ]; then + echo "Template file $TEMPLATE_FILE not found. Skipping security.txt generation." + return + fi + + cp "$TEMPLATE_FILE" "$OUTPUT_FILE" + + replace_in_file() { + local placeholder=$1 + local value=$2 + local file=$3 + local escaped + escaped=$(printf '%s\n' "$value" | sed -e 's/[\/&]/\\&/g') + sed -i "s|{{${placeholder}}}|${escaped}|g" "$file" + } + + for i in 1 2 3; do + val=$(eval echo \${CONTACT_LINK$i}) + if [ -z "$val" ]; then + sed -i "/{{CONTACT_LINK${i}}}/d" "$OUTPUT_FILE" + else + replace_in_file "CONTACT_LINK${i}" "$val" "$OUTPUT_FILE" + fi + done + + if [ -z "$LANG" ]; then + sed -i "/{{LANG}}/d" "$OUTPUT_FILE" + else + replace_in_file "LANG" "$LANG" "$OUTPUT_FILE" + fi + + if [ -z "$POLICY" ]; then + sed -i "/{{POLICY}}/d" "$OUTPUT_FILE" + else + replace_in_file "POLICY" "$POLICY" "$OUTPUT_FILE" + fi + + replace_in_file "EXPIREDATE_ISO" "$EXPIREDATE_ISO" "$OUTPUT_FILE" + + echo "security.txt generated at $OUTPUT_FILE" + + # Delete template after processing + rm -f "$TEMPLATE_FILE" +} + +generate_security_txt + +echo "Replacement done." + +echo "Starting nginx..." + +exec nginx -g 'daemon off;'