🐳 solidtime

Modern open-source time-tracking app

Docker Ready 8 Services 8,522 stars
1. Pull Image docker pull sail-8.3/app
2. 1-Click Launch Command docker run -d --name solidtime sail-8.3/app
3. Compose Deployment docker compose up -d
docker-compose.yml
Download .yml
services:
    laravel.test:
        build:
            context: ./docker/local/8.3
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.3/app
        labels:
            - "traefik.enable=true"
            - "traefik.docker.network=${NETWORK_NAME}"
            - "traefik.http.services.solidtime-dev.loadbalancer.server.port=80"
            - "traefik.http.routers.solidtime-dev.rule=Host(`${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev.entrypoints=web"
            - "traefik.http.routers.solidtime-dev.service=solidtime-dev"
            - "traefik.http.routers.solidtime-dev-https.rule=Host(`${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-https.service=solidtime-dev"
            - "traefik.http.routers.solidtime-dev-https.entrypoints=websecure"
            - "traefik.http.routers.solidtime-dev-https.tls=true"
            # vite
            - "traefik.http.services.solidtime-dev-vite.loadbalancer.server.port=5173"
            # http
            - "traefik.http.routers.solidtime-dev-vite.rule=Host(`${VITE_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-vite.service=solidtime-dev-vite"
            - "traefik.http.routers.solidtime-dev-vite.entrypoints=web"
        extra_hosts:
            - "host.docker.internal:host-gateway"
            - "storage.${NGINX_HOST_NAME}:${REVERSE_PROXY_IP:-10.100.100.10}"
        environment:
            XDG_CONFIG_HOME: /var/www/html/config
            XDG_DATA_HOME: /var/www/html/data
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
            IGNITION_LOCAL_SITES_PATH: '${PWD}'
            VITE_HOST_NAME: '${VITE_HOST_NAME}'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
            - reverse-proxy
        depends_on:
            - pgsql
    pgsql:
        image: 'postgres:15'
        ports:
            - '${FORWARD_DB_PORT:-5432}:5432'
        environment:
            PGPASSWORD: '${DB_PASSWORD:-secret}'
            POSTGRES_DB: '${DB_DATABASE}'
            POSTGRES_USER: '${DB_USERNAME}'
            POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
        volumes:
            - 'sail-pgsql:/var/lib/postgresql/data'
            - './docker/local/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
        networks:
            - sail
        healthcheck:
            test:
                - CMD
                - pg_isready
                - '-q'
                - '-d'
                - '${DB_DATABASE}'
                - '-U'
                - '${DB_USERNAME}'
            retries: 3
            timeout: 5s
    pgsql_test:
        image: 'postgres:15'
        environment:
            PGPASSWORD: '${DB_PASSWORD:-secret}'
            POSTGRES_DB: '${DB_DATABASE}'
            POSTGRES_USER: '${DB_USERNAME}'
            POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
        volumes:
            - 'sail-pgsql-test:/var/lib/postgresql/data'
            - './docker/local/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
        networks:
            - sail
        healthcheck:
            test:
                - CMD
                - pg_isready
                - '-q'
                - '-d'
                - '${DB_DATABASE}'
                - '-U'
                - '${DB_USERNAME}'
            retries: 3
            timeout: 5s
    mailpit:
        image: 'axllent/mailpit:latest'
        labels:
            - "traefik.enable=true"
            - "traefik.docker.network=${NETWORK_NAME}"
            - "traefik.http.services.solidtime-dev-mailpit.loadbalancer.server.port=8025"
            - "traefik.http.routers.solidtime-dev-mailpit.rule=Host(`mail.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-mailpit.entrypoints=web"
            - "traefik.http.routers.solidtime-dev-mailpit.service=solidtime-dev-mailpit"
            - "traefik.http.routers.solidtime-dev-mailpit-https.rule=Host(`mail.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-mailpit-https.service=solidtime-dev-mailpit"
            - "traefik.http.routers.solidtime-dev-mailpit-https.entrypoints=websecure"
            - "traefik.http.routers.solidtime-dev-mailpit-https.tls=true"
        networks:
            - sail
            - reverse-proxy
    playwright:
        image: mcr.microsoft.com/playwright:v1.60.0-jammy
        command: ['npx', 'playwright', 'test', '--ui-port=8080', '--ui-host=0.0.0.0']
        working_dir: /src
        extra_hosts:
            - "${NGINX_HOST_NAME}:${REVERSE_PROXY_IP:-10.100.100.10}"
            - "${VITE_HOST_NAME}:${REVERSE_PROXY_IP:-10.100.100.10}"
        labels:
            - "traefik.enable=true"
            - "traefik.docker.network=${NETWORK_NAME}"
            - "traefik.http.services.solidtime-dev-playwright.loadbalancer.server.port=8080"
            - "traefik.http.routers.solidtime-dev-playwright.rule=Host(`playwright.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-playwright.entrypoints=web"
            - "traefik.http.routers.solidtime-dev-playwright-https.rule=Host(`playwright.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-playwright-https.entrypoints=websecure"
            - "traefik.http.routers.solidtime-dev-playwright-https.tls=true"
        networks:
            - sail
            - reverse-proxy
        volumes:
            - '.:/src'
    minio:
        image: 'minio/minio:latest'
        environment:
            MINIO_BROWSER_REDIRECT_URL: 'https://storage-management.${NGINX_HOST_NAME}'
            MINIO_ROOT_USER: 'sail'
            MINIO_ROOT_PASSWORD: 'password'
        volumes:
            - 'sail-minio:/data/minio'
        networks:
            - reverse-proxy
            - sail
        command: minio server /data/minio --console-address ":8900"
        healthcheck:
            test: [ "CMD", "mc", "ready", "local" ]
            interval: 5s
            timeout: 5s
            retries: 5
        labels:
            - "traefik.enable=true"
            - "traefik.docker.network=${NETWORK_NAME}"
            # Storage Frontend
            - "traefik.http.services.solidtime-dev-storage-frontend.loadbalancer.server.port=9000"
            # http
            - "traefik.http.routers.solidtime-dev-storage-frontend.rule=Host(`storage.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-storage-frontend.service=solidtime-dev-storage-frontend"
            - "traefik.http.routers.solidtime-dev-storage-frontend.entrypoints=web"
            # https
            - "traefik.http.routers.solidtime-dev-storage-frontend-https.rule=Host(`storage.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-storage-frontend-https.service=solidtime-dev-storage-frontend"
            - "traefik.http.routers.solidtime-dev-storage-frontend-https.entrypoints=websecure"
            - "traefik.http.routers.solidtime-dev-storage-frontend-https.tls=true"
            # Storage Management
            - "traefik.http.services.solidtime-dev-storage-management.loadbalancer.server.port=8900"
            # http
            - "traefik.http.routers.solidtime-dev-storage-management.rule=Host(`storage-management.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-storage-management.service=solidtime-dev-storage-management"
            - "traefik.http.routers.solidtime-dev-storage-management.entrypoints=web"
            # https
            - "traefik.http.routers.solidtime-dev-storage-management-https.rule=Host(`storage-management.${NGINX_HOST_NAME}`)"
            - "traefik.http.routers.solidtime-dev-storage-management-https.service=solidtime-dev-storage-management"
            - "traefik.http.routers.solidtime-dev-storage-management-https.entrypoints=websecure"
            - "traefik.http.routers.solidtime-dev-storage-management-https.tls=true"

    minio-create-bucket:
        image: minio/mc:latest
        depends_on:
            - minio
        environment:
            S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID}
            S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY}
            S3_BUCKET: ${S3_BUCKET}
            S3_ENDPOINT: ${S3_ENDPOINT}
        volumes:
            - './docker/local/minio:/etc/minio'
        networks:
            - sail
            - reverse-proxy
        entrypoint: /etc/minio/create_bucket.sh
        extra_hosts:
            - "storage.${NGINX_HOST_NAME}:${REVERSE_PROXY_IP:-10.100.100.10}"

    gotenberg:
        image: gotenberg/gotenberg:8
        networks:
            - sail
        healthcheck:
            test: ["CMD", "curl", "--silent", "--fail", "http://localhost:3000/health"]
networks:
    reverse-proxy:
        name: "${NETWORK_NAME}"
        external: true
    sail:
        driver: bridge
volumes:
    sail-pgsql:
        driver: local
    sail-pgsql-test:
        driver: local
    sail-minio:
        driver: local