Compare commits
2 Commits
f2786e116a
...
ec39b8d774
| Author | SHA1 | Date | |
|---|---|---|---|
| ec39b8d774 | |||
| 04379a4cec |
@@ -7,6 +7,8 @@ node_modules
|
||||
|
||||
# Docker specific files (if any, other than Dockerfile itself)
|
||||
# .dockerignore (to avoid including itself if context changes)
|
||||
docker
|
||||
systemd
|
||||
|
||||
# Local development environment files
|
||||
.env
|
||||
|
||||
76
README.md
76
README.md
@@ -125,7 +125,11 @@ For an enhanced tactile experience, Nexus Timer supports Smart Buttons based on
|
||||
}
|
||||
```
|
||||
## Building for the production
|
||||
Clone the repo
|
||||
Navigate to your project directory on the server
|
||||
```bash
|
||||
cd /virt
|
||||
```
|
||||
Clone the repository
|
||||
```bash
|
||||
git clone --depth 1 https://gitea.virtonline.eu/2HoursProject/nexus-timer.git
|
||||
cd nexus-timer
|
||||
@@ -134,76 +138,40 @@ Build the docker image
|
||||
```bash
|
||||
docker build -t virt-nexus-timer .
|
||||
```
|
||||
Do some sanity check first: Run the app in the container
|
||||
## Exposing the App Behind Traefik (Reverse Proxy)
|
||||
### Review the provided docker labels and systemd service file
|
||||
|
||||
Copy the example label file to its destination
|
||||
```bash
|
||||
docker run --rm -p 8080:80 virt-nexus-timer
|
||||
cp docker/traefik.labels labels
|
||||
```
|
||||
Test the web app
|
||||
View the example service definition:
|
||||
```bash
|
||||
curl http://localhost:8080/
|
||||
cat systemd/virt-nexus-timer.service
|
||||
```
|
||||
## Expose the app on Internet behind the reverse proxy (Traefik)
|
||||
Create a 'labels' file for Traefik
|
||||
```bash
|
||||
sudo tee labels <<EOF
|
||||
traefik.enable=true
|
||||
traefik.docker.network=traefik
|
||||
traefik.http.routers.virt-nexus-timer.rule=Host("nexus-timer.virtonline.eu")
|
||||
traefik.http.routers.virt-nexus-timer.service=virt-nexus-timer
|
||||
traefik.http.routers.virt-nexus-timer.tls=true
|
||||
traefik.http.routers.virt-nexus-timer.tls.certResolver=default
|
||||
traefik.http.routers.virt-nexus-timer.entrypoints=web-secure
|
||||
traefik.http.services.virt-nexus-timer.loadbalancer.server.port=80
|
||||
EOF
|
||||
```
|
||||
Create the systemd service file
|
||||
### Create the systemd service
|
||||
Use the editor to create or overwrite the service:
|
||||
```bash
|
||||
sudo systemctl edit --force --full virt-nexus-timer.service
|
||||
```
|
||||
File editor will open. Insert the service definition bellow then save and exit.
|
||||
```bash
|
||||
[Unit]
|
||||
Description=nexus-timer (virt-nexus-timer)
|
||||
Requires=docker.service
|
||||
After=docker.service
|
||||
DefaultDependencies=no
|
||||
Paste the contents from virt-nexus-timer.service, then save and exit.
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="HOME=/root"
|
||||
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-nexus-timer 2>/dev/null || true'
|
||||
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true'
|
||||
|
||||
ExecStart=/usr/bin/env docker run \
|
||||
--rm \
|
||||
--name=virt-nexus-timer \
|
||||
--network=traefik-net \
|
||||
--label-file /opt/nexus-timer/labels \
|
||||
virt-nexus-timer
|
||||
|
||||
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-nexus-timer 2>/dev/null || true'
|
||||
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true'
|
||||
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
SyslogIdentifier=virt-nexus-timer
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
Enable the app to start when the server boots and start it now
|
||||
Enable on system boot and start the service
|
||||
```bash
|
||||
sudo systemctl enable --now virt-nexus-timer.service
|
||||
```
|
||||
See the service status
|
||||
Check the service status
|
||||
```bash
|
||||
systemctl status virt-nexus-timer.service
|
||||
```
|
||||
See the logs
|
||||
View real-time logs
|
||||
```bash
|
||||
journalctl -fu virt-nexus-timer.service
|
||||
```
|
||||
Finally test the web app
|
||||
# Test the web application
|
||||
Verify that the application is accessible via HTTPS:
|
||||
```bash
|
||||
curl https://nexus-timer.virtonline.eu
|
||||
```
|
||||
Or open it in your browser:
|
||||
[https://nexus-timer.virtonline.eu](https://nexus-timer.virtonline.eu)
|
||||
8
docker/traefik.labels
Normal file
8
docker/traefik.labels
Normal file
@@ -0,0 +1,8 @@
|
||||
traefik.enable=true
|
||||
traefik.docker.network=traefik
|
||||
traefik.http.routers.virt-nexus-timer.rule=Host("nexus-timer.virtonline.eu")
|
||||
traefik.http.routers.virt-nexus-timer.service=virt-nexus-timer
|
||||
traefik.http.routers.virt-nexus-timer.tls=true
|
||||
traefik.http.routers.virt-nexus-timer.tls.certResolver=default
|
||||
traefik.http.routers.virt-nexus-timer.entrypoints=web-secure
|
||||
traefik.http.services.virt-nexus-timer.loadbalancer.server.port=80
|
||||
8
labels
Normal file
8
labels
Normal file
@@ -0,0 +1,8 @@
|
||||
traefik.enable=true
|
||||
traefik.docker.network=traefik
|
||||
traefik.http.routers.virt-nexus-timer.rule=Host("nexus-timer.virtonline.eu")
|
||||
traefik.http.routers.virt-nexus-timer.service=virt-nexus-timer
|
||||
traefik.http.routers.virt-nexus-timer.tls=true
|
||||
traefik.http.routers.virt-nexus-timer.tls.certResolver=default
|
||||
traefik.http.routers.virt-nexus-timer.entrypoints=web-secure
|
||||
traefik.http.services.virt-nexus-timer.loadbalancer.server.port=80
|
||||
@@ -1,4 +1,4 @@
|
||||
const CACHE_VERSION = 'nexus-timer-cache-v3.3';
|
||||
const CACHE_VERSION = 'nexus-timer-cache-v3.4';
|
||||
const APP_SHELL_URLS = [
|
||||
// '/', // Let NetworkFirst handle '/'
|
||||
'/manifest.json',
|
||||
|
||||
@@ -7,6 +7,17 @@ body {
|
||||
overscroll-behavior-y: contain; /* Prevents pull-to-refresh on mobile */
|
||||
}
|
||||
|
||||
/* Safe area insets for mobile devices (status bar, home indicator) */
|
||||
.safe-area-padding {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
/* padding-bottom: env(safe-area-inset-bottom); */
|
||||
}
|
||||
|
||||
.safe-area-height {
|
||||
height: calc(100dvh - env(safe-area-inset-top));
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* Basic button styling */
|
||||
.btn {
|
||||
@apply px-4 py-2 rounded font-semibold focus:outline-none focus:ring-2 focus:ring-opacity-50;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Player Name -->
|
||||
<h2 class="font-semibold mb-6 md:mb-6 text-5xl sm:text-2xl md:text-3xl lg:text-5xl">
|
||||
<h2 class="font-semibold mb-4 md:mb-6 text-5xl sm:text-2xl md:text-3xl lg:text-5xl">
|
||||
{{ player.name }}
|
||||
</h2>
|
||||
<TimerDisplay
|
||||
@@ -42,7 +42,6 @@
|
||||
class="text-4xl sm:text-5xl md:text-6xl lg:text-6xl xl:text-5xl"
|
||||
/>
|
||||
<p v-if="player.isSkipped" class="text-red-500 dark:text-red-400 mt-1 md:mt-2 font-semibold text-sm md:text-base lg:text-lg">SKIPPED</p>
|
||||
<p v-if="isNextPlayerArea && !player.isSkipped" class="mt-1 md:mt-2 text-xs md:text-sm text-gray-600 dark:text-gray-400">(Swipe up to pass turn)</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -109,9 +108,9 @@ const calculateAvatarSize = () => {
|
||||
const availableHeight = screenHeight / 2;
|
||||
let size = Math.min(availableHeight * 0.5, screenWidth * 0.4, 175);
|
||||
|
||||
if (screenWidth < 960) {
|
||||
size = Math.min(availableHeight * 0.7, screenWidth * 0.6, 250);
|
||||
} else if (screenWidth < 1024) {
|
||||
if (screenWidth < 768) { // Mobile
|
||||
size = Math.min(availableHeight * 0.7, screenWidth * 0.6, 230);
|
||||
} else if (screenWidth < 1024) { // Tablet
|
||||
size = Math.min(availableHeight * 0.55, screenWidth * 0.45, 180);
|
||||
}
|
||||
size = Math.max(size, 100);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-screen overflow-hidden" :class="{'dark': theme === 'dark'}">
|
||||
<div class="flex flex-col safe-area-height safe-area-padding overflow-hidden" :class="{'dark': theme === 'dark'}">
|
||||
<header class="p-3 bg-gray-100 dark:bg-gray-800 shadow-md flex justify-between items-center shrink-0">
|
||||
<!-- ... header content ... -->
|
||||
<div class="flex items-center space-x-2">
|
||||
|
||||
29
systemd/virt-nexus-timer.service
Normal file
29
systemd/virt-nexus-timer.service
Normal file
@@ -0,0 +1,29 @@
|
||||
[Unit]
|
||||
Description=nexus-timer (virt-nexus-timer)
|
||||
Requires=docker.service
|
||||
After=docker.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="HOME=/root"
|
||||
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-nexus-timer 2>/dev/null || true'
|
||||
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true'
|
||||
|
||||
ExecStart=/usr/bin/env docker run \
|
||||
--rm \
|
||||
--name=virt-nexus-timer \
|
||||
--log-driver=none \
|
||||
--network=traefik \
|
||||
--label-file /virt/nexus-timer/labels \
|
||||
virt-nexus-timer
|
||||
|
||||
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-nexus-timer 2>/dev/null || true'
|
||||
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true'
|
||||
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
SyslogIdentifier=virt-nexus-timer
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user