mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-04 19:40:04 -05:00
Cleanup docker, only publish one image.
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
name: Build and Publish TimeTracker Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: [ 'v*' ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
release:
|
||||
types: [ published ]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: drytrix/timetracker-externaldb
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: amd64
|
||||
platform: linux/amd64
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Container Registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Check files and create combined Dockerfile
|
||||
run: |
|
||||
echo "--- Checking available files ---"
|
||||
pwd
|
||||
ls -la
|
||||
echo "--- Checking if requirements.txt exists ---"
|
||||
if [ -f requirements.txt ]; then
|
||||
echo "requirements.txt found:"
|
||||
cat requirements.txt
|
||||
else
|
||||
echo "requirements.txt NOT found!"
|
||||
echo "Available .txt files:"
|
||||
find . -name "*.txt" -type f
|
||||
fi
|
||||
|
||||
echo "--- Creating combined Dockerfile ---"
|
||||
cp Dockerfile Dockerfile.final
|
||||
# Ensure port 8080 is exposed in the final Dockerfile
|
||||
if ! grep -q "^EXPOSE 8080" Dockerfile.final; then
|
||||
echo "\n# Ensure required port is exposed" >> Dockerfile.final
|
||||
echo "EXPOSE 8080" >> Dockerfile.final
|
||||
fi
|
||||
echo "Combined Dockerfile created successfully"
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
IMAGE_ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
# Extract version from ref
|
||||
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
elif [[ "${GITHUB_REF}" == refs/heads/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/heads/}
|
||||
else
|
||||
VERSION=unknown
|
||||
fi
|
||||
|
||||
# Replace any slashes with dashes (for feature branches etc.)
|
||||
VERSION=${VERSION//\//-}
|
||||
|
||||
echo "Image ID: $IMAGE_ID"
|
||||
echo "Version: $VERSION"
|
||||
|
||||
# Build the Docker image
|
||||
docker build -f Dockerfile.final \
|
||||
--label "org.opencontainers.image.exposedPorts=8080" \
|
||||
-t $IMAGE_ID:$VERSION .
|
||||
|
||||
# Always push versioned tag on releases/tags
|
||||
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||
echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
|
||||
# If this is a release or tag push, also push as latest
|
||||
if [ "${{ github.event_name }}" == "release" ] || [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
||||
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:latest
|
||||
docker push $IMAGE_ID:latest
|
||||
fi
|
||||
fi
|
||||
@@ -1,103 +0,0 @@
|
||||
name: Build and Publish TimeTracker Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: [ 'v*' ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
release:
|
||||
types: [ published ]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: drytrix/timetracker-internaldb
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: amd64
|
||||
platform: linux/amd64
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Container Registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Check files and create combined Dockerfile
|
||||
run: |
|
||||
echo "--- Checking available files ---"
|
||||
pwd
|
||||
ls -la
|
||||
echo "--- Checking if requirements.txt exists ---"
|
||||
if [ -f requirements.txt ]; then
|
||||
echo "requirements.txt found:"
|
||||
cat requirements.txt
|
||||
else
|
||||
echo "requirements.txt NOT found!"
|
||||
echo "Available .txt files:"
|
||||
find . -name "*.txt" -type f
|
||||
fi
|
||||
|
||||
echo "--- Creating combined Dockerfile ---"
|
||||
cp Dockerfile.simple Dockerfile.final
|
||||
# Ensure port 8080 is exposed in the final Dockerfile
|
||||
if ! grep -q "^EXPOSE 8080" Dockerfile.final; then
|
||||
echo "\n# Ensure required port is exposed" >> Dockerfile.final
|
||||
echo "EXPOSE 8080" >> Dockerfile.final
|
||||
fi
|
||||
echo "Combined Dockerfile created successfully"
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
IMAGE_ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
# Extract version from ref
|
||||
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
elif [[ "${GITHUB_REF}" == refs/heads/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/heads/}
|
||||
else
|
||||
VERSION=unknown
|
||||
fi
|
||||
|
||||
# Replace any slashes with dashes (for feature branches etc.)
|
||||
VERSION=${VERSION//\//-}
|
||||
|
||||
echo "Image ID: $IMAGE_ID"
|
||||
echo "Version: $VERSION"
|
||||
|
||||
# Build the Docker image
|
||||
docker build -f Dockerfile.final \
|
||||
--label "org.opencontainers.image.exposedPorts=8080" \
|
||||
-t $IMAGE_ID:$VERSION .
|
||||
|
||||
# Always push versioned tag on releases/tags
|
||||
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||
echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
|
||||
# If this is a release or tag push, also push as latest
|
||||
if [ "${{ github.event_name }}" == "release" ] || [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
||||
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:latest
|
||||
docker push $IMAGE_ID:latest
|
||||
fi
|
||||
fi
|
||||
@@ -144,15 +144,15 @@ jobs:
|
||||
-t $IMAGE_ID:$VERSION \
|
||||
.
|
||||
|
||||
# Tag with additional labels based on version source
|
||||
if [[ "${{ steps.version.outputs.version_source }}" == "release" ]] || [[ "${{ steps.version.outputs.version_source }}" == "git_tag" ]]; then
|
||||
# For releases and tags, also create a 'latest' tag
|
||||
# Determine publish tags
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
# Release: publish version and latest
|
||||
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:latest
|
||||
echo "Tagged as latest (release/tag)"
|
||||
elif [[ "${{ steps.version.outputs.version_source }}" == "branch_build" ]] && [[ "${{ steps.version.outputs.branch_name }}" == "main" ]]; then
|
||||
# For main branch builds, create a 'main' tag
|
||||
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:main
|
||||
echo "Tagged as main (main branch build)"
|
||||
echo "Release build: will push tags [$VERSION, latest]"
|
||||
else
|
||||
# Non-release: publish development
|
||||
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:development
|
||||
echo "Non-release build: will push tag [development]"
|
||||
fi
|
||||
|
||||
- name: Push Docker image
|
||||
@@ -165,16 +165,13 @@ jobs:
|
||||
echo "Image ID: $IMAGE_ID"
|
||||
echo "Version: $VERSION"
|
||||
|
||||
# Push the versioned tag
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
|
||||
# Push additional tags if they exist
|
||||
if [[ "${{ steps.version.outputs.version_source }}" == "release" ]] || [[ "${{ steps.version.outputs.version_source }}" == "git_tag" ]]; then
|
||||
if [[ "${{ github.event_name }}" == "release" ]]; then
|
||||
# Push version and latest
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
docker push $IMAGE_ID:latest
|
||||
echo "Pushed latest tag"
|
||||
elif [[ "${{ steps.version.outputs.version_source }}" == "branch_build" ]] && [[ "${{ steps.version.outputs.branch_name }}" == "main" ]]; then
|
||||
docker push $IMAGE_ID:main
|
||||
echo "Pushed main tag"
|
||||
else
|
||||
# Push only development
|
||||
docker push $IMAGE_ID:development
|
||||
fi
|
||||
|
||||
- name: Generate build summary
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV FLASK_APP=app
|
||||
ENV FLASK_ENV=production
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
tzdata \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Set default timezone
|
||||
ENV TZ=Europe/Rome
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy project
|
||||
COPY . .
|
||||
|
||||
# Create data and logs directories with proper permissions
|
||||
RUN mkdir -p /data /app/logs && chmod 755 /data && chmod 755 /app/logs
|
||||
|
||||
# Copy and fix the startup script
|
||||
COPY docker/start-simple.sh /app/start.sh
|
||||
|
||||
# Ensure proper line endings and make executable
|
||||
RUN sed -i 's/\r$//' /app/start.sh && \
|
||||
chmod +x /app/start.sh
|
||||
|
||||
# Make other scripts executable
|
||||
RUN chmod +x /app/docker/init-database.py /app/docker/init-database-sql.py /app/docker/test-db.py
|
||||
|
||||
# Create non-root user
|
||||
RUN useradd -m -u 1000 timetracker && \
|
||||
chown -R timetracker:timetracker /app /data /app/logs
|
||||
|
||||
# Verify startup script exists and is accessible
|
||||
RUN ls -la /app/start.sh && \
|
||||
head -1 /app/start.sh && \
|
||||
cat /app/start.sh
|
||||
|
||||
USER timetracker
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/_health || exit 1
|
||||
|
||||
# Run the application
|
||||
CMD ["/app/start.sh"]
|
||||
@@ -1,37 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV FLASK_APP=app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy project
|
||||
COPY . .
|
||||
|
||||
# Copy the minimal startup script
|
||||
COPY docker/start-minimal.sh /app/start.sh
|
||||
|
||||
# Make executable
|
||||
RUN chmod +x /app/start.sh
|
||||
|
||||
# Verify startup script exists
|
||||
RUN ls -la /app/start.sh && \
|
||||
head -1 /app/start.sh
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Run the application
|
||||
CMD ["/app/start.sh"]
|
||||
@@ -1,79 +0,0 @@
|
||||
FROM python:3.11-slim-bullseye
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV FLASK_APP=app
|
||||
ENV FLASK_ENV=production
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
tzdata \
|
||||
# WeasyPrint dependencies (Debian Bullseye package names)
|
||||
libgdk-pixbuf2.0-0 \
|
||||
libpango-1.0-0 \
|
||||
libcairo2 \
|
||||
libpangocairo-1.0-0 \
|
||||
libffi-dev \
|
||||
shared-mime-info \
|
||||
# Additional fonts and rendering support
|
||||
fonts-liberation \
|
||||
fonts-dejavu-core \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Set default timezone
|
||||
ENV TZ=Europe/Rome
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy project
|
||||
COPY . .
|
||||
|
||||
# Create all necessary directories with proper permissions BEFORE creating user
|
||||
RUN mkdir -p /data /app/logs && \
|
||||
mkdir -p /app/app/static/uploads/logos && \
|
||||
mkdir -p /app/static/uploads/logos && \
|
||||
mkdir -p /app/app/static/uploads/temp && \
|
||||
mkdir -p /app/static/uploads/temp
|
||||
|
||||
# Set proper permissions on directories
|
||||
RUN chmod -R 755 /data && \
|
||||
chmod -R 755 /app/logs && \
|
||||
chmod -R 755 /app/app/static/uploads && \
|
||||
chmod -R 755 /app/static/uploads
|
||||
|
||||
# Copy the startup script and ensure it's executable
|
||||
COPY docker/start-new.sh /app/start.sh
|
||||
|
||||
# Make startup scripts executable
|
||||
RUN chmod +x /app/start.sh /app/docker/init-database.py /app/docker/init-database-sql.py /app/docker/test-db.py /app/docker/test-routing.py
|
||||
|
||||
# Create non-root user with specific UID/GID
|
||||
RUN groupadd -g 1000 timetracker && \
|
||||
useradd -m -u 1000 -g 1000 timetracker
|
||||
|
||||
# Change ownership of ALL application files and directories to timetracker user
|
||||
RUN chown -R timetracker:timetracker /app /data /app/logs
|
||||
|
||||
# Verify startup script exists and is accessible
|
||||
RUN ls -la /app/start.sh && \
|
||||
head -1 /app/start.sh
|
||||
|
||||
# Switch to non-root user
|
||||
USER timetracker
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/_health || exit 1
|
||||
|
||||
# Run the application
|
||||
CMD ["/app/start.sh"]
|
||||
@@ -1,37 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV FLASK_APP=app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy project
|
||||
COPY . .
|
||||
|
||||
# Copy the Python startup script
|
||||
COPY docker/start.py /app/start.py
|
||||
|
||||
# Make executable
|
||||
RUN chmod +x /app/start.py
|
||||
|
||||
# Verify startup script exists
|
||||
RUN ls -la /app/start.py && \
|
||||
head -1 /app/start.py
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Run the application using Python
|
||||
CMD ["python", "/app/start.py"]
|
||||
@@ -1,65 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
postgresql \
|
||||
postgresql-contrib \
|
||||
curl \
|
||||
tzdata \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Set default timezone
|
||||
ENV TZ=Europe/Rome
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p /data /app/logs /var/lib/postgresql/data /var/run/postgresql
|
||||
|
||||
# Make startup scripts executable
|
||||
RUN chmod +x /app/docker/init-database.py /app/docker/test-db.py
|
||||
|
||||
# Create startup script directly in Dockerfile
|
||||
RUN echo '#!/bin/bash' > /app/start.sh && \
|
||||
echo 'set -e' >> /app/start.sh && \
|
||||
echo 'cd /app' >> /app/start.sh && \
|
||||
echo 'export FLASK_APP=app' >> /app/start.sh && \
|
||||
echo 'export DATABASE_URL=postgresql+psycopg2://timetracker@localhost:5432/timetracker' >> /app/start.sh && \
|
||||
echo 'echo "=== Starting TimeTracker ==="' >> /app/start.sh && \
|
||||
echo 'echo "Testing startup script..."' >> /app/start.sh && \
|
||||
echo 'ls -la /app/docker/' >> /app/start.sh && \
|
||||
echo 'echo "Starting database initialization..."' >> /app/start.sh && \
|
||||
echo 'python /app/docker/init-database-sql.py' >> /app/start.sh && \
|
||||
echo 'echo "Starting application..."' >> /app/start.sh && \
|
||||
echo 'exec gunicorn --bind 0.0.0.0:8080 --worker-class eventlet --workers 1 --timeout 120 "app:create_app()"' >> /app/start.sh
|
||||
|
||||
# Make startup scripts executable
|
||||
RUN chmod +x /app/start.sh /app/docker/init-database.py /app/docker/test-db.py
|
||||
|
||||
# Create timetracker user and ensure postgres user exists
|
||||
RUN useradd -m -u 1000 timetracker && \
|
||||
chown -R timetracker:timetracker /app /data /app/logs && \
|
||||
chown -R postgres:postgres /var/lib/postgresql/data /var/run/postgresql && \
|
||||
chmod +x /app/start.sh
|
||||
|
||||
# Verify startup script exists and is accessible
|
||||
RUN ls -la /app/start.sh && \
|
||||
head -1 /app/start.sh
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/_health || exit 1
|
||||
|
||||
# Start the application
|
||||
CMD ["/app/start.sh"]
|
||||
@@ -1,69 +0,0 @@
|
||||
FROM python:3.11-slim-bullseye
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV FLASK_APP=app
|
||||
ENV FLASK_ENV=production
|
||||
|
||||
# Install system dependencies for WeasyPrint
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
tzdata \
|
||||
# Core WeasyPrint dependencies
|
||||
libgdk-pixbuf2.0-0 \
|
||||
libpango-1.0-0 \
|
||||
libcairo2 \
|
||||
libpangocairo-1.0-0 \
|
||||
libffi-dev \
|
||||
shared-mime-info \
|
||||
# Font support
|
||||
fonts-liberation \
|
||||
fonts-dejavu-core \
|
||||
# Additional system libraries
|
||||
libglib2.0-0 \
|
||||
libgirepository1.0-1 \
|
||||
# Clean up
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Set default timezone
|
||||
ENV TZ=Europe/Rome
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy project
|
||||
COPY . .
|
||||
|
||||
# Create data and logs directories with proper permissions
|
||||
RUN mkdir -p /data /app/logs && chmod 755 /data && chmod 755 /app/logs
|
||||
|
||||
# Copy the startup script and ensure it's executable
|
||||
COPY docker/start-new.sh /app/start.sh
|
||||
|
||||
# Make startup scripts executable
|
||||
RUN chmod +x /app/start.sh /app/docker/init-database.py /app/docker/init-database-sql.py /app/docker/test-db.py /app/docker/test-routing.py
|
||||
|
||||
# Create non-root user
|
||||
RUN useradd -m -u 1000 timetracker && \
|
||||
chown -R timetracker:timetracker /app /data /app/logs
|
||||
|
||||
# Verify startup script exists and is accessible
|
||||
RUN ls -la /app/start.sh && \
|
||||
head -1 /app/start.sh
|
||||
|
||||
USER timetracker
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/_health || exit 1
|
||||
|
||||
# Run the application
|
||||
CMD ["/app/start.sh"]
|
||||
@@ -1,17 +0,0 @@
|
||||
# Docker Compose override for license server configuration
|
||||
# Use this file to override license server settings for different environments
|
||||
#
|
||||
# Usage:
|
||||
# docker-compose -f docker-compose.yml -f docker-compose.license-server.yml up
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
web:
|
||||
environment:
|
||||
# License server IP is hardcoded in code as 192.168.1.100:8081
|
||||
# Clients cannot change this - it's built into the application
|
||||
# All license server settings are now hardcoded and cannot be overridden
|
||||
|
||||
# Note: No environment variables needed for license server configuration
|
||||
# The application will automatically connect to the hardcoded IP address
|
||||
@@ -1,73 +0,0 @@
|
||||
services:
|
||||
app:
|
||||
image: ghcr.io/${GITHUB_REPOSITORY:-drytrix/timetracker}:latest
|
||||
container_name: timetracker-app
|
||||
environment:
|
||||
- TZ=${TZ:-Europe/Rome}
|
||||
- CURRENCY=${CURRENCY:-EUR}
|
||||
- ROUNDING_MINUTES=${ROUNDING_MINUTES:-1}
|
||||
- SINGLE_ACTIVE_TIMER=${SINGLE_ACTIVE_TIMER:-true}
|
||||
- ALLOW_SELF_REGISTER=${ALLOW_SELF_REGISTER:-true}
|
||||
- IDLE_TIMEOUT_MINUTES=${IDLE_TIMEOUT_MINUTES:-30}
|
||||
- ADMIN_USERNAMES=${ADMIN_USERNAMES:-admin}
|
||||
- SECRET_KEY=${SECRET_KEY:-your-secret-key-change-this}
|
||||
- DATABASE_URL=postgresql+psycopg2://timetracker:timetracker@db:5432/timetracker
|
||||
- LOG_FILE=/app/logs/timetracker.log
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- app_data:/data
|
||||
- ./logs:/app/logs
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/_health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
container_name: timetracker-db
|
||||
environment:
|
||||
- POSTGRES_DB=${POSTGRES_DB:-timetracker}
|
||||
- POSTGRES_USER=${POSTGRES_USER:-timetracker}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-timetracker}
|
||||
- TZ=${TZ:-Europe/Rome}
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: unless-stopped
|
||||
|
||||
# Optional reverse proxy for TLS on LAN
|
||||
proxy:
|
||||
image: caddy:2-alpine
|
||||
container_name: timetracker-proxy
|
||||
volumes:
|
||||
- ./docker/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
depends_on:
|
||||
- app
|
||||
restart: unless-stopped
|
||||
profiles:
|
||||
- tls
|
||||
|
||||
volumes:
|
||||
app_data:
|
||||
driver: local
|
||||
db_data:
|
||||
driver: local
|
||||
caddy_data:
|
||||
driver: local
|
||||
caddy_config:
|
||||
driver: local
|
||||
@@ -1,9 +1,7 @@
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.python
|
||||
container_name: timetracker-app-python
|
||||
image: ghcr.io/drytrix/timetracker:development
|
||||
container_name: timetracker-app-remote-dev
|
||||
environment:
|
||||
- TZ=${TZ:-Europe/Brussels}
|
||||
- CURRENCY=${CURRENCY:-EUR}
|
||||
@@ -15,26 +13,34 @@ services:
|
||||
- SECRET_KEY=${SECRET_KEY:-your-secret-key-change-this}
|
||||
- DATABASE_URL=postgresql+psycopg2://timetracker:timetracker@db:5432/timetracker
|
||||
- LOG_FILE=/app/logs/timetracker.log
|
||||
- SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}
|
||||
- REMEMBER_COOKIE_SECURE=${REMEMBER_COOKIE_SECURE:-true}
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- app_data:/data
|
||||
- app_data_remote_dev:/data
|
||||
- ./logs:/app/logs
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/_health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
container_name: timetracker-db-python
|
||||
container_name: timetracker-db-remote-dev
|
||||
environment:
|
||||
- POSTGRES_DB=${POSTGRES_DB:-timetracker}
|
||||
- POSTGRES_USER=${POSTGRES_USER:-timetracker}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-timetracker}
|
||||
- TZ=${TZ:-Europe/Brussels}
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
- db_data_remote_dev:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 10s
|
||||
@@ -44,7 +50,9 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
app_data:
|
||||
app_data_remote_dev:
|
||||
driver: local
|
||||
db_data:
|
||||
db_data_remote_dev:
|
||||
driver: local
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.fixed
|
||||
container_name: timetracker-app-fixed
|
||||
image: ghcr.io/drytrix/timetracker:latest
|
||||
container_name: timetracker-app-remote
|
||||
environment:
|
||||
- TZ=${TZ:-Europe/Brussels}
|
||||
- CURRENCY=${CURRENCY:-EUR}
|
||||
@@ -15,26 +13,34 @@ services:
|
||||
- SECRET_KEY=${SECRET_KEY:-your-secret-key-change-this}
|
||||
- DATABASE_URL=postgresql+psycopg2://timetracker:timetracker@db:5432/timetracker
|
||||
- LOG_FILE=/app/logs/timetracker.log
|
||||
- SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}
|
||||
- REMEMBER_COOKIE_SECURE=${REMEMBER_COOKIE_SECURE:-true}
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- app_data:/data
|
||||
- app_data_remote:/data
|
||||
- ./logs:/app/logs
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/_health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
container_name: timetracker-db-fixed
|
||||
container_name: timetracker-db-remote
|
||||
environment:
|
||||
- POSTGRES_DB=${POSTGRES_DB:-timetracker}
|
||||
- POSTGRES_USER=${POSTGRES_USER:-timetracker}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-timetracker}
|
||||
- TZ=${TZ:-Europe/Brussels}
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
- db_data_remote:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 10s
|
||||
@@ -44,7 +50,9 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
app_data:
|
||||
app_data_remote:
|
||||
driver: local
|
||||
db_data:
|
||||
db_data_remote:
|
||||
driver: local
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
timetracker:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.simple
|
||||
container_name: timetracker-simple
|
||||
environment:
|
||||
- TZ=${TZ:-Europe/Rome}
|
||||
- CURRENCY=${CURRENCY:-EUR}
|
||||
- ROUNDING_MINUTES=${ROUNDING_MINUTES:-1}
|
||||
- SINGLE_ACTIVE_TIMER=${SINGLE_ACTIVE_TIMER:-true}
|
||||
- ALLOW_SELF_REGISTER=${ALLOW_SELF_REGISTER:-true}
|
||||
- IDLE_TIMEOUT_MINUTES=${IDLE_TIMEOUT_MINUTES:-30}
|
||||
- ADMIN_USERNAMES=${ADMIN_USERNAMES:-admin}
|
||||
- SECRET_KEY=${SECRET_KEY:-your-secret-key-change-this}
|
||||
- FORCE_REINIT=${FORCE_REINIT:-false}
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- timetracker_data:/data
|
||||
- timetracker_logs:/app/logs
|
||||
- timetracker_db:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/_health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
volumes:
|
||||
timetracker_data:
|
||||
driver: local
|
||||
timetracker_logs:
|
||||
driver: local
|
||||
timetracker_db:
|
||||
driver: local
|
||||
@@ -1,32 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.weasyprint
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://timetracker:timetracker@db:5432/timetracker
|
||||
- FLASK_APP=app
|
||||
- FLASK_ENV=production
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./logs:/app/logs
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
image: postgres:15
|
||||
environment:
|
||||
- POSTGRES_DB=timetracker
|
||||
- POSTGRES_USER=timetracker
|
||||
- POSTGRES_PASSWORD=timetracker
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
Reference in New Issue
Block a user