├── .gitignore ├── 1-docker-with-database ├── logs │ └── .gitkeep ├── app-storage │ └── .gitkeep ├── .gitignore ├── .env.example ├── laravel.env.example ├── readme.md └── docker-compose.yml ├── 0-docker-traefik-with-database ├── logs │ └── .gitkeep ├── app-storage │ └── .gitkeep ├── .gitignore ├── .env.example ├── laravel.env.example ├── readme.md └── docker-compose.yml ├── readme.md └── license.md /.gitignore: -------------------------------------------------------------------------------- 1 | /.env 2 | /.idea 3 | -------------------------------------------------------------------------------- /1-docker-with-database/logs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /1-docker-with-database/app-storage/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/logs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/app-storage/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /1-docker-with-database/.gitignore: -------------------------------------------------------------------------------- 1 | /logs 2 | !/logs/.gitkeep 3 | /app-storage 4 | !/app-storage/.gitkeep 5 | /.env 6 | /laravel.env 7 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/.gitignore: -------------------------------------------------------------------------------- 1 | /logs 2 | !/logs/.gitkeep 3 | /app-storage 4 | !/app-storage/.gitkeep 5 | /.env 6 | /laravel.env 7 | -------------------------------------------------------------------------------- /1-docker-with-database/.env.example: -------------------------------------------------------------------------------- 1 | APP_DOMAIN=your-domain.com 2 | DB_DATABASE=solidtime 3 | DB_USERNAME=solidtime 4 | FORWARD_APP_PORT=8000 5 | FORWARD_DB_PORT=5432 6 | DB_PASSWORD=randompassword 7 | SOLIDTIME_IMAGE_TAG=latest 8 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/.env.example: -------------------------------------------------------------------------------- 1 | REVERSE_PROXY_NETWORK=reverse-proxy-docker-traefik_routing 2 | APP_DOMAIN=your-domain.com 3 | DB_DATABASE=solidtime 4 | DB_USERNAME=solidtime 5 | FORWARD_DB_PORT=5432 6 | DB_PASSWORD=randompassword 7 | SOLIDTIME_IMAGE_TAG=latest 8 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # solidtime | Self-hosting examples 2 | 3 | This repository contains examples for self-hosting [solidtime](https://www.solidtime.io/). The examples are meant to be used as a starting point for your own setup. 4 | See [the documentation](https://docs.solidtime.io/self-hosting/intro) for more information. 5 | 6 | Also, each example has its own README.md file with example specific instructions. 7 | It is important that you follow the instructions in the documentation first and only read the example readme when the documentation tells you to do so. 8 | 9 | ## License 10 | 11 | The self-hosting examples are licensed under the MIT License. See [license.md](license.md) for more information. 12 | This is NOT the license for the solidtime application itself. The solidtime application is licensed under the AGPL-3.0 License. See [LICENSE](https://github.com/solidtime-io/solidtime/blob/main/LICENSE.md). 13 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/laravel.env.example: -------------------------------------------------------------------------------- 1 | APP_ENV="production" 2 | APP_DEBUG="false" 3 | APP_URL="https://your-domain.com" 4 | APP_FORCE_HTTPS="true" 5 | TRUSTED_PROXIES="0.0.0.0/0,2000:0:0:0:0:0:0:0/3" 6 | 7 | # Authentication 8 | APP_KEY="" 9 | PASSPORT_PRIVATE_KEY="" 10 | PASSPORT_PUBLIC_KEY="" 11 | SUPER_ADMINS="" 12 | 13 | # Logging 14 | LOG_CHANNEL="stderr_daily" 15 | LOG_LEVEL="debug" 16 | 17 | # Database 18 | DB_CONNECTION="pgsql" 19 | DB_HOST="database" 20 | DB_PORT="5432" 21 | DB_SSLMODE="require" 22 | DB_DATABASE="solidtime" 23 | DB_USERNAME="solidtime" 24 | DB_PASSWORD="randompassword" 25 | 26 | # Mail 27 | MAIL_MAILER="smtp" 28 | MAIL_HOST="" 29 | MAIL_PORT="" 30 | MAIL_ENCRYPTION="tls" 31 | MAIL_FROM_ADDRESS="no-reply@your-domain.com" 32 | MAIL_FROM_NAME="solidtime" 33 | MAIL_USERNAME="" 34 | MAIL_PASSWORD="" 35 | 36 | # Queue 37 | QUEUE_CONNECTION="database" 38 | 39 | # File storage 40 | FILESYSTEM_DISK="local" 41 | PUBLIC_FILESYSTEM_DISK="public" 42 | 43 | # Services 44 | GOTENBERG_URL="http://gotenberg:3000" 45 | -------------------------------------------------------------------------------- /1-docker-with-database/laravel.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME="solidtime" 2 | VITE_APP_NAME="solidtime" 3 | APP_ENV="production" 4 | APP_DEBUG="false" 5 | APP_URL="https://your-domain.com" 6 | APP_FORCE_HTTPS="true" 7 | TRUSTED_PROXIES="0.0.0.0/0,2000:0:0:0:0:0:0:0/3" 8 | 9 | # Authentication 10 | APP_KEY="" 11 | PASSPORT_PRIVATE_KEY="" 12 | PASSPORT_PUBLIC_KEY="" 13 | SUPER_ADMINS="" 14 | 15 | # Logging 16 | LOG_CHANNEL="stderr_daily" 17 | LOG_LEVEL="debug" 18 | 19 | # Database 20 | DB_CONNECTION="pgsql" 21 | DB_HOST="database" 22 | DB_PORT="5432" 23 | DB_SSLMODE="require" 24 | DB_DATABASE="solidtime" 25 | DB_USERNAME="solidtime" 26 | DB_PASSWORD="randompassword" 27 | 28 | # Mail 29 | MAIL_MAILER="smtp" 30 | MAIL_HOST="" 31 | MAIL_PORT="" 32 | MAIL_ENCRYPTION="tls" 33 | MAIL_FROM_ADDRESS="no-reply@your-domain.com" 34 | MAIL_FROM_NAME="solidtime" 35 | MAIL_USERNAME="" 36 | MAIL_PASSWORD="" 37 | 38 | # Queue 39 | QUEUE_CONNECTION="database" 40 | 41 | # File storage 42 | FILESYSTEM_DISK="local" 43 | PUBLIC_FILESYSTEM_DISK="public" 44 | 45 | # Services 46 | GOTENBERG_URL="http://gotenberg:3000" 47 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © `2024` `Gregor Vostrak & Constantin Graf` 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /1-docker-with-database/readme.md: -------------------------------------------------------------------------------- 1 | # Example: Docker + Database 2 | 3 | This example shows how to run solidtime with Docker and with a database inside the same docker compose. 4 | 5 | ## Prerequisites 6 | 7 | - [Docker](https://docs.docker.com/engine/install/) 8 | - A reverse proxy like Nginx or Traefik OR you can use the solidtime image without a reverse proxy for local setups. 9 | 10 | The reverse proxy can be installed with or without Docker. 11 | The example only exposes the solidtime application on a port defined by a configuration. 12 | 13 | ## Installation 14 | 15 | 1. Copy the example files and adjust the environment variables to your needs 16 | 17 | ```bash 18 | cp laravel.env.example laravel.env 19 | cp .env.example .env 20 | ``` 21 | 22 | 2. (Only with Linux/Docker Engine) Correct the permissions of the `app-storage` and `logs` directories. 23 | 24 | ```bash 25 | chown -R 1000:1000 app-storage logs 26 | ``` 27 | 28 | Follow further instructions on [Self-Hosting Docs](https://docs.solidtime.io/self-hosting/guides/docker) 29 | 30 | 31 | ## Database access on the host machine 32 | 33 | If you want to be able to access the database from the host machine, you need to expose the database port in the `docker-compose.yml` file. 34 | 35 | > [!CAUTION] 36 | > Only do this if you are not exposing this port to the internet. You can block this for example via a security group in most cloud providers or via a firewall on your local machine. 37 | 38 | Uncomment the following lines in the `docker-compose.yml` file: 39 | 40 | ```yaml 41 | database: 42 | # ... other configuration 43 | ports: 44 | - '${FORWARD_DB_PORT:-5432}:5432' 45 | # ... other configuration 46 | ``` 47 | 48 | Set the `FORWARD_DB_PORT` environment variable to the port you want to use on the host machine 49 | 50 | ```dotenv 51 | FORWARD_DB_PORT=5432 52 | ``` 53 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/readme.md: -------------------------------------------------------------------------------- 1 | # Example: Docker + Traefik + Database 2 | 3 | This example shows how to run solidtime with Docker, Traefik, and with a database inside the same docker compose. 4 | 5 | ## Prerequisites 6 | 7 | - [Docker](https://docs.docker.com/engine/install/) 8 | - [Traefik V2 (Docker)](https://doc.traefik.io/traefik/getting-started/install-traefik/) with [Configuration Discovery](https://doc.traefik.io/traefik/providers/docker/) 9 | 10 | If you don't know how to set up Traefik with automatic configuration discovery via labels, you can use [this guide](https://github.com/korridor/reverse-proxy-docker-traefik). 11 | 12 | ## Installation 13 | 14 | 1. Copy the example files and adjust the environment variables to your needs 15 | 16 | ```bash 17 | cp laravel.env.example laravel.env 18 | cp .env.example .env 19 | ``` 20 | 21 | 2. (Only with Linux/Docker Engine) Correct the permissions of the `app-storage` and `logs` directories. 22 | 23 | ```bash 24 | chown -R 1000:1000 app-storage logs 25 | ``` 26 | 27 | Follow further instructions on [Self-Hosting Docs](https://docs.solidtime.io/self-hosting/guides/docker) 28 | 29 | ## Database access on the host machine 30 | 31 | If you want to be able to access the database from the host machine, you need to expose the database port in the `docker-compose.yml` file. 32 | 33 | > [!CAUTION] 34 | > Only do this if you are not exposing this port to the internet. You can block this for example via a security group in most cloud providers or via a firewall on your local machine. 35 | 36 | Uncomment the following lines in the `docker-compose.yml` file: 37 | 38 | ```yaml 39 | database: 40 | # ... other configuration 41 | ports: 42 | - '${FORWARD_DB_PORT:-5432}:5432' 43 | # ... other configuration 44 | ``` 45 | 46 | Set the `FORWARD_DB_PORT` environment variable to the port you want to use on the host machine 47 | 48 | ```dotenv 49 | FORWARD_DB_PORT=5432 50 | ``` 51 | -------------------------------------------------------------------------------- /1-docker-with-database/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | app: 3 | restart: always 4 | image: "solidtime/solidtime:${SOLIDTIME_IMAGE_TAG:-latest}" 5 | user: "1000:1000" 6 | ports: 7 | - '${FORWARD_APP_PORT:-8000}:8000' 8 | networks: 9 | - internal 10 | volumes: 11 | - "app-storage:/var/www/html/storage" 12 | - "./logs:/var/www/html/storage/logs" 13 | - "./app-storage:/var/www/html/storage/app" 14 | environment: 15 | CONTAINER_MODE: http 16 | healthcheck: 17 | test: [ "CMD", "curl", "--fail", "http://localhost:8000/health-check/up" ] 18 | env_file: 19 | - laravel.env 20 | depends_on: 21 | - database 22 | scheduler: 23 | restart: always 24 | image: "solidtime/solidtime:${SOLIDTIME_IMAGE_TAG:-latest}" 25 | user: "1000:1000" 26 | networks: 27 | - internal 28 | volumes: 29 | - "app-storage:/var/www/html/storage" 30 | - "./logs:/var/www/html/storage/logs" 31 | - "./app-storage:/var/www/html/storage/app" 32 | environment: 33 | CONTAINER_MODE: scheduler 34 | healthcheck: 35 | test: [ "CMD", "healthcheck" ] 36 | env_file: 37 | - laravel.env 38 | depends_on: 39 | - database 40 | queue: 41 | restart: always 42 | image: "solidtime/solidtime:${SOLIDTIME_IMAGE_TAG:-latest}" 43 | user: "1000:1000" 44 | networks: 45 | - internal 46 | volumes: 47 | - "app-storage:/var/www/html/storage" 48 | - "./logs:/var/www/html/storage/logs" 49 | - "./app-storage:/var/www/html/storage/app" 50 | environment: 51 | CONTAINER_MODE: worker 52 | WORKER_COMMAND: "php /var/www/html/artisan queue:work" 53 | healthcheck: 54 | test: [ "CMD", "healthcheck" ] 55 | env_file: 56 | - laravel.env 57 | depends_on: 58 | - database 59 | database: 60 | restart: always 61 | image: 'postgres:15' 62 | # ports: 63 | # - '${FORWARD_DB_PORT:-5432}:5432' 64 | environment: 65 | PGPASSWORD: '${DB_PASSWORD:-secret}' 66 | POSTGRES_DB: '${DB_DATABASE}' 67 | POSTGRES_USER: '${DB_USERNAME}' 68 | POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' 69 | volumes: 70 | - 'database-storage:/var/lib/postgresql/data' 71 | networks: 72 | - internal 73 | healthcheck: 74 | test: 75 | - CMD 76 | - pg_isready 77 | - '-q' 78 | - '-d' 79 | - '${DB_DATABASE}' 80 | - '-U' 81 | - '${DB_USERNAME}' 82 | retries: 3 83 | timeout: 5s 84 | gotenberg: 85 | image: gotenberg/gotenberg:8 86 | networks: 87 | - internal 88 | healthcheck: 89 | test: [ "CMD", "curl", "--silent", "--fail", "http://localhost:3000/health" ] 90 | networks: 91 | internal: 92 | volumes: 93 | database-storage: 94 | app-storage: 95 | -------------------------------------------------------------------------------- /0-docker-traefik-with-database/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | app: 3 | restart: always 4 | image: "solidtime/solidtime:${SOLIDTIME_IMAGE_TAG:-latest}" 5 | user: "1000:1000" 6 | labels: 7 | - "traefik.enable=true" 8 | - "traefik.docker.network=${REVERSE_PROXY_NETWORK}" 9 | - "traefik.http.services.solidtime.loadbalancer.server.port=8000" 10 | # http 11 | - "traefik.http.routers.solidtime.rule=Host(`${APP_DOMAIN}`)" 12 | - "traefik.http.routers.solidtime.entrypoints=web" 13 | - "traefik.http.routers.solidtime.middlewares=redirect-to-https@file" 14 | # https 15 | - "traefik.http.routers.solidtime-https.rule=Host(`${APP_DOMAIN}`)" 16 | - "traefik.http.routers.solidtime-https.entrypoints=websecure" 17 | - "traefik.http.routers.solidtime-https.tls.certresolver=letsencrypt" 18 | - "traefik.http.routers.solidtime-https.tls=true" 19 | networks: 20 | - frontend 21 | - internal 22 | volumes: 23 | - "app-storage:/var/www/html/storage" 24 | - "./logs:/var/www/html/storage/logs" 25 | - "./app-storage:/var/www/html/storage/app" 26 | environment: 27 | CONTAINER_MODE: http 28 | healthcheck: 29 | test: [ "CMD", "curl", "--fail", "http://localhost:8000/health-check/up" ] 30 | env_file: 31 | - laravel.env 32 | depends_on: 33 | - database 34 | scheduler: 35 | restart: always 36 | image: "solidtime/solidtime:${SOLIDTIME_IMAGE_TAG:-latest}" 37 | user: "1000:1000" 38 | networks: 39 | - internal 40 | volumes: 41 | - "app-storage:/var/www/html/storage" 42 | - "./logs:/var/www/html/storage/logs" 43 | - "./app-storage:/var/www/html/storage/app" 44 | environment: 45 | CONTAINER_MODE: scheduler 46 | healthcheck: 47 | test: [ "CMD", "healthcheck" ] 48 | env_file: 49 | - laravel.env 50 | depends_on: 51 | - database 52 | queue: 53 | restart: always 54 | image: "solidtime/solidtime:${SOLIDTIME_IMAGE_TAG:-latest}" 55 | user: "1000:1000" 56 | networks: 57 | - internal 58 | volumes: 59 | - "app-storage:/var/www/html/storage" 60 | - "./logs:/var/www/html/storage/logs" 61 | - "./app-storage:/var/www/html/storage/app" 62 | environment: 63 | CONTAINER_MODE: worker 64 | WORKER_COMMAND: "php /var/www/html/artisan queue:work" 65 | healthcheck: 66 | test: [ "CMD", "healthcheck" ] 67 | env_file: 68 | - laravel.env 69 | depends_on: 70 | - database 71 | database: 72 | restart: always 73 | image: 'postgres:15' 74 | # ports: 75 | # - '${FORWARD_DB_PORT:-5432}:5432' 76 | environment: 77 | PGPASSWORD: '${DB_PASSWORD:-secret}' 78 | POSTGRES_DB: '${DB_DATABASE}' 79 | POSTGRES_USER: '${DB_USERNAME}' 80 | POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' 81 | volumes: 82 | - 'database-storage:/var/lib/postgresql/data' 83 | networks: 84 | - internal 85 | healthcheck: 86 | test: 87 | - CMD 88 | - pg_isready 89 | - '-q' 90 | - '-d' 91 | - '${DB_DATABASE}' 92 | - '-U' 93 | - '${DB_USERNAME}' 94 | retries: 3 95 | timeout: 5s 96 | gotenberg: 97 | image: gotenberg/gotenberg:8 98 | networks: 99 | - internal 100 | healthcheck: 101 | test: [ "CMD", "curl", "--silent", "--fail", "http://localhost:3000/health" ] 102 | networks: 103 | frontend: 104 | name: ${REVERSE_PROXY_NETWORK} 105 | external: true 106 | internal: 107 | volumes: 108 | database-storage: 109 | app-storage: 110 | --------------------------------------------------------------------------------