first load
Some checks failed
Build, Push, Publish / Build & Release (push) Failing after 2s

This commit is contained in:
2025-12-16 04:45:03 -03:00
parent 17bb0e28e9
commit ce6e465910
15 changed files with 861 additions and 1 deletions

8
.dockerignore Normal file
View File

@@ -0,0 +1,8 @@
.git/
.github/
docker/
.dockerignore
CNAME
Dockerfile
README.md
LICENSE

240
.github/workflows/release_build.yml vendored Normal file
View File

@@ -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<<EOF" >> "$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<<EOF" >> "$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<<EOF" >> "$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

78
.github/workflows/update_readme.yml vendored Normal file
View File

@@ -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 '/<!-- buttons -->/{flag=1;next}/<!-- endbuttons -->/{flag=0}flag' source_readme/README.md)
BUTTONS_UPDATED=$(echo "$BUTTONS" | sed "s/\.github/${REPO_NAME}/g")
# --- Extract footer block from source (everything from <!-- footer --> onward) ---
FOOTER=$(awk '/<!-- footer -->/{flag=1}flag' source_readme/README.md)
# --- Replace buttons section in README.md ---
UPDATED=$(awk -v buttons="$BUTTONS_UPDATED" '
BEGIN { skip=0 }
/<!-- buttons -->/ {
print
print buttons
skip=1
next
}
/<!-- endbuttons -->/ && skip {
print
skip=0
next
}
!skip { print }
' README.md)
# --- Replace everything after <!-- footer --> with FOOTER ---
echo "$UPDATED" | awk -v footer="$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 }}

View File

@@ -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}}

42
Dockerfile Normal file
View File

@@ -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"]

21
LICENSE Normal file
View File

@@ -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.

View File

@@ -1,2 +1,68 @@
# parkingpage
# Parking Page
Dynamic HTML to put on parking domains
<!-- buttons -->
[![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]
<!-- endbuttons -->
## 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
```
<!-- footer -->
---
## 🧑‍💻 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

29
docker/.env Normal file
View File

@@ -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

View File

@@ -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

15
docker/docker-compose.yml Normal file
View File

@@ -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

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

123
index.html Normal file
View File

@@ -0,0 +1,123 @@
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>{{TITLE}}</title>
<link rel="icon" type="image/png" href="{{FAVICON_PNG_URL}}" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="{{FAVICON_SVG_URL}}" />
<link rel="shortcut icon" href="{{FAVICON_ICO_URL}}" />
<link rel="apple-touch-icon" sizes="180x180" href="{{APPLE_TOUCH_ICON_URL}}" />
<meta name="apple-mobile-web-app-title" content="{{TITLE}}" />
<style>
body {
margin: 0;
font-family: 'Segoe UI', sans-serif;
background-color: #121212;
color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
position: relative;
}
.container {
max-width: 600px;
width: 90%;
background-color: #1e1e1e;
border-radius: 12px;
padding: 2rem;
text-align: center;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
}
.logo {
width: 300px;
height: 200px;
margin: 0 auto 1.5rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
border-radius: 8px;
}
h1 {
margin: 0.5rem 0;
font-size: 2rem;
color: #ffffff;
}
p {
margin: 0.5rem 0 1.5rem;
color: #bbbbbb;
font-size: 1rem;
}
.contact {
font-size: 1.1rem;
color: #dddddd;
}
.contact a {
color: #dddddd;
text-decoration: none;
}
.contact a:hover {
text-decoration: underline;
}
.contact span {
display: block;
margin-bottom: 0.5rem;
}
.credit-logo {
position: fixed;
bottom: 10px;
right: 10px;
}
.credit-logo img {
width: 16px;
height: 16px;
opacity: 0.6;
transition: opacity 0.2s;
}
.credit-logo img:hover {
opacity: 1;
}
@media (max-width: 480px) {
.logo {
width: 100%;
height: 150px;
}
h1 {
font-size: 1.5rem;
}
}
</style>
</head>
<body>
<div class="container">
<!-- LOGO_BLOCK_START -->
<div class="logo" style="background-image: url('{{LOGO_URL}}');"></div>
<!-- LOGO_BLOCK_END -->
<!-- TITLE_BLOCK_START -->
<h1>{{TITLE}}</h1>
<!-- TITLE_BLOCK_END -->
<!-- SUBTEXT_BLOCK_START -->
<p>{{SUBTEXT}}</p>
<!-- SUBTEXT_BLOCK_END -->
<div class="contact">
<!-- EMAIL_BLOCK_START -->
<span>📧 <a href="{{LINK_EMAIL}}">{{EMAIL}}</a></span>
<!-- EMAIL_BLOCK_END -->
<!-- PHONE_BLOCK_START -->
<span>📞 <a href="{{LINK_PHONE}}" target="_blank" rel="noopener noreferrer">{{PHONE}}</a></span>
<!-- PHONE_BLOCK_END -->
</div>
</div>
<a href="{{CREDIT_LINK}}" target="_blank" class="credit-logo" aria-label="Site de Ivan Carlos" rel="noopener noreferrer">
<img src="{{CREDIT_LOGO_URL}}" alt="Ivan Carlos Logo" />
</a>
</body>
</html>

4
manifest.json Normal file
View File

@@ -0,0 +1,4 @@
{
"version": "2.2.24",
"author": "Ivan Carlos"
}

2
robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Allow: /

177
startup.sh Normal file
View File

@@ -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 "/<!-- ${block_name}_BLOCK_START -->/,/<!-- ${block_name}_BLOCK_END -->/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 <title> 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;'