├── .nvmrc ├── .gitattributes ├── .husky ├── .gitignore └── commit-msg ├── compose ├── docker-vols │ ├── .keep │ └── public │ │ └── .keep ├── traefik │ ├── example.env │ └── docker-compose.yml ├── docker-compose.apache.dev.yml ├── docker-compose.apache.cli.yml ├── docker-compose.apache.prod.yml ├── docker-compose.fpm.prod.yml └── docker-compose.fpm.dev.yml ├── .commitlintrc.json ├── .gitignore ├── .github ├── dependabot.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── stale.yml ├── FUNDING.yml └── workflows │ ├── test-images.yml │ ├── kimai-release.yml │ ├── build-default.yml │ └── build-multiarch.yml ├── .idea ├── codeStyles │ └── codeStyleConfig.xml ├── vcs.xml ├── .gitignore ├── dockers.iml └── modules.xml ├── docs ├── index.md ├── examples.md ├── runtime-args.md ├── updating.md ├── troubleshooting.md ├── build.md └── helm.md ├── assets ├── test-lite.sh ├── 000-default.conf ├── test-kimai-version.sh ├── self-test.sh ├── monolog.yaml ├── service.sh ├── dbtest.php └── startup.sh ├── .versionrc.json ├── README.md ├── package.json ├── CONTRIBUTING.md ├── LICENSE ├── docker-compose.yml ├── README.orig.md ├── Makefile ├── CHANGELOG.md └── Dockerfile /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * eol=lf -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /compose/docker-vols/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /compose/docker-vols/public/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | 5 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build-tree.png 2 | *.swp 3 | node_modules/ 4 | yarn.lock 5 | .env 6 | compose/docker-vols/public/ 7 | *.secrets 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "docker" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Kimai Dockers 2 | 3 | The documentation was moved to the official docs page. 4 | 5 | See [https://www.kimai.org/documentation/docker.html](https://www.kimai.org/documentation/docker.html) 6 | -------------------------------------------------------------------------------- /docs/examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | The documentation was moved to the official docs page. 4 | 5 | See [https://www.kimai.org/documentation/docker-compose.html](https://www.kimai.org/documentation/docker-compose.html) 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /docs/runtime-args.md: -------------------------------------------------------------------------------- 1 | # Runtime Arguments 2 | 3 | The documentation was moved to the official docs page. 4 | 5 | See [https://www.kimai.org/documentation/docker.html](https://www.kimai.org/documentation/docker.html#runtime-arguments) 6 | -------------------------------------------------------------------------------- /docs/updating.md: -------------------------------------------------------------------------------- 1 | # Upgrading Kimai docker 2 | 3 | The documentation was moved to the official docs page. 4 | 5 | See [https://www.kimai.org/documentation/docker-updates.html](https://www.kimai.org/documentation/docker-updates.html) 6 | 7 | -------------------------------------------------------------------------------- /docs/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | The documentation was moved to the official docs page. 4 | 5 | See [https://www.kimai.org/documentation/docker-troubleshooting.html](https://www.kimai.org/documentation/docker-troubleshooting.html) 6 | -------------------------------------------------------------------------------- /docs/build.md: -------------------------------------------------------------------------------- 1 | # Building the Kimai Docker images 2 | 3 | The documentation was moved to the official docs page. 4 | 5 | See [https://www.kimai.org/documentation/building-docker.html](https://www.kimai.org/documentation/building-docker.html) 6 | 7 | 8 | -------------------------------------------------------------------------------- /compose/traefik/example.env: -------------------------------------------------------------------------------- 1 | HOST=mysite.com 2 | 3 | KIMAI_ADMIN_MAIL=admin@testsite.com 4 | KIMAI_ADMIN_PASS=changemeplease 5 | 6 | SQL_DB_NAME=kimai 7 | SQL_ROOT_PASS=changemeplease 8 | 9 | SQL_USER_NAME=kimaiuser 10 | SQL_USER_PASS=kimaipassword 11 | -------------------------------------------------------------------------------- /docs/helm.md: -------------------------------------------------------------------------------- 1 | # Helm and Kubernetes 2 | 3 | We used to keep a helm chart in this repo, but it is now managed in an external repo. 4 | 5 | The documentation was moved to the official docs page. 6 | 7 | See [https://www.kimai.org/documentation/kubernetes.html](https://www.kimai.org/documentation/kubernetes.html) 8 | -------------------------------------------------------------------------------- /.idea/dockers.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assets/test-lite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Test PHP/Kimai 4 | /opt/kimai/bin/console kimai:version 5 | if [ $? != 0 ]; then 6 | echo "PHP/Kimai not responding" 7 | exit 1 8 | fi 9 | 10 | # Test FPM CGI 11 | if [ -f /use_fpm ]; then 12 | echo Testing FPM 13 | php-fpm -t 14 | fi 15 | 16 | # Test Apache/httpd 17 | if [ -f /use_apache ]; then 18 | echo Testing Apache 19 | apache2ctl -t 20 | fi 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assets/000-default.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerAdmin webmaster@localhost 3 | DocumentRoot /opt/kimai/public 4 | 5 | PassEnv DATABASE_PREFIX 6 | PassEnv MAILER_FROM 7 | PassEnv APP_ENV 8 | PassEnv APP_SECRET 9 | PassEnv DATABASE_URL 10 | PassEnv MAILER_URL 11 | PassEnv TRUSTED_PROXIES 12 | PassEnv TRUSTED_HOSTS 13 | 14 | 15 | Require all granted 16 | DirectoryIndex index.php 17 | AllowOverride All 18 | 19 | 20 | 21 | 22 | ServerName localhost 23 | -------------------------------------------------------------------------------- /.versionrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "types": [ 3 | {"type": "feat", "section": "Features"}, 4 | {"type": "fix", "section": "Bug Fixes"}, 5 | {"type": "chore", "hidden": true}, 6 | {"type": "docs", "hidden": true}, 7 | {"type": "style", "hidden": true}, 8 | {"type": "refactor", "hidden": true}, 9 | {"type": "perf", "hidden": true}, 10 | {"type": "test", "hidden": true} 11 | ], 12 | "commitUrlFormat": "https://github.com/tobybatch/kimai2/commits/{{hash}}", 13 | "compareUrlFormat": "https://github.com/tobybatch/kimai2/compare/{{previousTag}}...{{currentTag}}" 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kimai Dockers 2 | 3 | After 6 years of maintaining a separate repo for this project we have, as of Jan 8th 2024 officially folded the docker files into the main [Kimai](https://github.com/kimai/kimai) repo. 4 | 5 | The built images are still pushed to [docker hub](https://hub.docker.com/r/kimai/kimai2) 6 | 7 | Documentation is available as part of the core [Kimai docker documentation](https://github.com/kimai/kimai/issues) 8 | 9 | Issues can now be raised on the [issues page](https://www.kimai.org/documentation/docker.html) of the main Kimai repo. 10 | 11 | The old README is [here](./README.orig.md) just in case you wanted it. 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "prepare": "husky install", 4 | "test": "make test", 5 | "release-patch": "standard-version --release-as patch", 6 | "release-minor": "standard-version --release-as minor", 7 | "release-major": "standard-version --release-as major" 8 | }, 9 | "devDependencies": { 10 | "@commitlint/cli": "^12.1.1", 11 | "@commitlint/config-conventional": "^12.1.1", 12 | "husky": "^6.0.0", 13 | "standard-version": "^9.2.0" 14 | }, 15 | "husky": { 16 | "hooks": { 17 | "pre-commit": "echo git hooks are awesome!", 18 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 19 | } 20 | }, 21 | "version": "2.3.1" 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 21 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | - bug 10 | # Label to use when marking an issue as stale 11 | staleLabel: wontfix 12 | # Comment to post when marking an issue as stale. Set to `false` to disable 13 | markComment: > 14 | This issue has been automatically marked as stale because it has not had 15 | recent activity. It will be closed if no further activity occurs. Thank you 16 | for your contributions. 17 | # Comment to post when closing a stale issue. Set to `false` to disable 18 | closeComment: false 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | 2 | # These are supported funding model platforms 3 | 4 | github: [tobybatch] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 5 | patreon: # Replace with a single Patreon username 6 | open_collective: # Replace with a single Open Collective username 7 | ko_fi: # Replace with a single Ko-fi username 8 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 9 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 10 | liberapay: # Replace with a single Liberapay username 11 | issuehunt: # Replace with a single IssueHunt username 12 | otechie: # Replace with a single Otechie username 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /assets/test-kimai-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # An reg wizard can probably do this without the cut command 4 | VER=$(echo $KIMAI | sed 's/[^0-9]//g' | cut -c1-3) 5 | 6 | if test "${VER}" -lt 111 7 | then 8 | echo "+--------------------------------------------------------------------------+" 9 | echo "| Kimai versions older than 1.11 require composer 1.x |" 10 | echo "| To build older versions you'll need to use a tagged version of this repo |" 11 | echo "| https://github.com/tobybatch/kimai2/releases/tag/EOL-composer-1.x |" 12 | echo "| |" 13 | echo "| See https://github.com/tobybatch/kimai2/issues/180 |" 14 | echo "+--------------------------------------------------------------------------+" 15 | return 1 16 | fi 17 | 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] " 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behaviour: 15 | 1. Start the container '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Desktop (please complete the following information):** 21 | - OS: [e.g. iOS] 22 | - Docker version: [e.g. 19.03.2] 23 | - Docker compose version: [e.g. 1.21.0] 24 | 25 | **Command used to run the container** 26 | - [e.g. docker run -v ....] 27 | 28 | **Docker compose file (with passwords redacted)** 29 | 30 | ```yaml 31 | version: '3.5' 32 | services: 33 | image: ... 34 | ``` 35 | 36 | **Additional context** 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /compose/docker-compose.apache.dev.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | 4 | sqldb: 5 | image: mysql:5.7 6 | environment: 7 | - MYSQL_DATABASE=kimai 8 | - MYSQL_USER=kimaiuser 9 | - MYSQL_PASSWORD=kimaipassword 10 | - MYSQL_ROOT_PASSWORD=changemeplease 11 | command: --default-storage-engine innodb 12 | restart: unless-stopped 13 | healthcheck: 14 | test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost 15 | interval: 20s 16 | start_period: 10s 17 | timeout: 10s 18 | retries: 3 19 | 20 | kimai: 21 | image: kimai/kimai2:apache-dev 22 | ports: 23 | - 8001:8001 24 | environment: 25 | - ADMINMAIL=admin@kimai.local 26 | - ADMINPASS=changemeplease 27 | - "DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8&serverVersion=5.7" 28 | - TRUSTED_HOSTS=nginx,localhost,127.0.0.1 29 | restart: unless-stopped 30 | 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This is an open source project we welcome any support that you want to give. Just fork the repo and raise a PR. 4 | 5 | ## Pull request rules 6 | 7 | We use the [conventional-changelog](https://github.com/conventional-changelog/commitlint) package to generate the changelog. This uses commit lint rules. To enforce these rules for you run the following: 8 | 9 | * Install nvm[...](https://duckduckgo.com/?q=nodejs+install+nvm&t=canonical&ia=web) 10 | * `nvm use` 11 | * `npm install` 12 | 13 | This should install the git hooks to check your commits are in the correct format. 14 | 15 | ## Manual build 16 | 17 | You can build the Image for local testing like this: 18 | 19 | ```bash 20 | docker build --tag kimai2 \ 21 | --no-cache \ 22 | --build-arg PHP_VER=8.1 \ 23 | --build-arg COMPOSER_VER=latest \ 24 | --build-arg KIMAI=main \ 25 | --build-arg TIMEZONE=Europe/Berlin \ 26 | --build-arg BASE=fpm . 27 | ``` 28 | -------------------------------------------------------------------------------- /compose/docker-compose.apache.cli.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | 4 | sqldb: 5 | image: mysql:5.7 6 | environment: 7 | - MYSQL_DATABASE=kimai 8 | - MYSQL_USER=kimaiuser 9 | - MYSQL_PASSWORD=kimaipassword 10 | - MYSQL_ROOT_PASSWORD=changemeplease 11 | command: --default-storage-engine innodb 12 | restart: unless-stopped 13 | healthcheck: 14 | test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost 15 | interval: 20s 16 | start_period: 10s 17 | timeout: 10s 18 | retries: 3 19 | 20 | kimai: 21 | image: kimai/kimai2:apache-dev 22 | ports: 23 | - 8001:8001 24 | environment: 25 | - ADMINMAIL=admin@kimai.local 26 | - ADMINPASS=changemeplease 27 | - "DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8&serverVersion=5.7" 28 | - TRUSTED_HOSTS=nginx,localhost,127.0.0.1 29 | restart: unless-stopped 30 | entrypoint: sh 31 | stdin_open: true # docker run -i 32 | tty: true # docker run -t 33 | 34 | -------------------------------------------------------------------------------- /compose/docker-compose.apache.prod.yml: -------------------------------------------------------------------------------- 1 | 2 | version: '3.5' 3 | services: 4 | 5 | sqldb: 6 | image: mysql:5.7 7 | volumes: 8 | - kimai-mysql:/var/lib/mysql 9 | environment: 10 | - MYSQL_DATABASE=kimai 11 | - MYSQL_USER=kimaiuser 12 | - MYSQL_PASSWORD=kimaipassword 13 | - MYSQL_ROOT_PASSWORD=changemeplease 14 | command: --default-storage-engine innodb 15 | restart: unless-stopped 16 | healthcheck: 17 | test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost 18 | interval: 20s 19 | start_period: 10s 20 | timeout: 10s 21 | retries: 3 22 | 23 | kimai: 24 | image: kimai/kimai2:apache 25 | volumes: 26 | - kimai-var:/opt/kimai/var 27 | ports: 28 | - 8001:8001 29 | environment: 30 | - ADMINMAIL=admin@kimai.local 31 | - ADMINPASS=changemeplease 32 | - "DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8&serverVersion=5.7" 33 | - TRUSTED_HOSTS=nginx,localhost,127.0.0.1 34 | restart: unless-stopped 35 | 36 | volumes: 37 | kimai-var: 38 | kimai-mysql: 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Toby Batch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/self-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | /startup.sh 2>&1 4 | echo $$ > /tmp/startup.pid 5 | echo "Waiting for kimai to install" 6 | while [ ! -f /opt/kimai/var/installed ]; do 7 | echo -n ". " 8 | sleep 5 9 | done 10 | echo 11 | 12 | # Test FPM CGI 13 | if [ -f /use_fpm ]; then 14 | 15 | export SCRIPT_NAME=/opt/kimai/public/index.php 16 | export SCRIPT_FILENAME=/opt/kimai/public/index.php 17 | export REQUEST_METHOD=GET 18 | export SERVER_ADDR=localhost 19 | 20 | COUNT=0 21 | until cgi-fcgi -bind -connect 127.0.0.1:9000 &> /dev/null 22 | do 23 | COUNT=$((COUNT+1)) 24 | echo "Waiting for FPM Server to start (${COUNT})" 25 | sleep 3 26 | if [ "$COUNT" -gt 5 ]; then 27 | echo "FPM Failed to start." 28 | exit 1 29 | fi 30 | done 31 | 32 | fi 33 | 34 | # Test Apache/httpd 35 | if [ -f /use_apache ]; then 36 | 37 | COUNT=0 38 | until curl -s -o /dev/null http://localhost:8001 39 | do 40 | COUNT=$((COUNT+1)) 41 | echo "Waiting for Apache/HTTP to start (${COUNT})" &> /dev/null 42 | sleep 3 43 | if [ "$COUNT" -gt 5 ]; then 44 | echo "Apache/HTTP failed to start." 45 | exit 1 46 | fi 47 | done 48 | 49 | fi 50 | 51 | # Test PHP/Kimai 52 | /opt/kimai/bin/console kimai:version 53 | if [ $? != 0 ]; then 54 | echo "PHP/Kimai not responding" 55 | exit 1 56 | fi 57 | kill $(cat /tmp/startup.pid) 58 | 59 | 60 | -------------------------------------------------------------------------------- /compose/docker-compose.fpm.prod.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | 4 | sqldb: 5 | image: mysql:5.7 6 | environment: 7 | - MYSQL_DATABASE=kimai 8 | - MYSQL_USER=kimaiuser 9 | - MYSQL_PASSWORD=kimaipassword 10 | - MYSQL_ROOT_PASSWORD=changemeplease 11 | command: --default-storage-engine innodb 12 | restart: unless-stopped 13 | healthcheck: 14 | test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost 15 | interval: 20s 16 | start_period: 10s 17 | timeout: 10s 18 | retries: 3 19 | 20 | nginx: 21 | image: tobybatch/nginx-fpm-reverse-proxy 22 | ports: 23 | - 8001:80 24 | volumes: 25 | - public:/opt/kimai/public:ro 26 | restart: unless-stopped 27 | depends_on: 28 | - kimai 29 | healthcheck: 30 | test: wget --spider http://nginx/health || exit 1 31 | interval: 20s 32 | start_period: 10s 33 | timeout: 10s 34 | retries: 3 35 | 36 | kimai: # This is the latest FPM image of kimai 37 | image: kimai/kimai2:latest 38 | environment: 39 | - ADMINMAIL=admin@kimai.local 40 | - ADMINPASS=changemeplease 41 | - "DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8&serverVersion=5.7" 42 | - TRUSTED_HOSTS=nginx,localhost,127.0.0.1 43 | volumes: 44 | - public:/opt/kimai/public 45 | # - var:/opt/kimai/var 46 | # - ./ldap.conf:/etc/openldap/ldap.conf:z 47 | # - ./ROOT-CA.pem:/etc/ssl/certs/ROOT-CA.pem:z 48 | restart: unless-stopped 49 | 50 | volumes: 51 | var: 52 | public: 53 | -------------------------------------------------------------------------------- /compose/docker-compose.fpm.dev.yml: -------------------------------------------------------------------------------- 1 | 2 | 3 | version: '3.5' 4 | services: 5 | 6 | sqldb: 7 | image: mysql:5.7 8 | environment: 9 | - MYSQL_DATABASE=kimai 10 | - MYSQL_USER=kimaiuser 11 | - MYSQL_PASSWORD=kimaipassword 12 | - MYSQL_ROOT_PASSWORD=changemeplease 13 | command: --default-storage-engine innodb 14 | restart: unless-stopped 15 | healthcheck: 16 | test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost 17 | interval: 20s 18 | start_period: 10s 19 | timeout: 10s 20 | retries: 3 21 | 22 | nginx: 23 | image: tobybatch/nginx-fpm-reverse-proxy 24 | ports: 25 | - 8001:80 26 | volumes: 27 | - public:/opt/kimai/public:ro 28 | restart: unless-stopped 29 | depends_on: 30 | - kimai 31 | healthcheck: 32 | test: wget --spider http://nginx/health || exit 1 33 | interval: 20s 34 | start_period: 10s 35 | timeout: 10s 36 | retries: 3 37 | 38 | kimai: # This is the latest FPM image of kimai 39 | image: kimai/kimai2:fpm-dev 40 | environment: 41 | - ADMINMAIL=admin@kimai.local 42 | - ADMINPASS=changemeplease 43 | - "DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8&serverVersion=5.7" 44 | - TRUSTED_HOSTS=nginx,localhost,127.0.0.1 45 | volumes: 46 | - public:/opt/kimai/public 47 | # - var:/opt/kimai/var 48 | # - ./ldap.conf:/etc/openldap/ldap.conf:z 49 | # - ./ROOT-CA.pem:/etc/ssl/certs/ROOT-CA.pem:z 50 | restart: unless-stopped 51 | 52 | volumes: 53 | var: 54 | public: 55 | -------------------------------------------------------------------------------- /.github/workflows/test-images.yml: -------------------------------------------------------------------------------- 1 | # act -j test -W ./.github/workflows/test.yml --secret-file .dockerhub.secrets 2 | name: 'Test images' 3 | 4 | on: 5 | workflow_dispatch: 6 | # repository_dispatch: 7 | # types: [kimai_release] 8 | 9 | jobs: 10 | test: 11 | strategy: 12 | matrix: 13 | type: [dev,prod] 14 | server: [fpm,apache] 15 | runs-on: ubuntu-latest 16 | 17 | env: 18 | DB_USER: root 19 | DB_PASSWORD: 'root' 20 | DB_HOST: localhost 21 | 22 | steps: 23 | - run: | 24 | sudo /etc/init.d/mysql start 25 | mysql -e 'CREATE DATABASE kimai;' -uroot -proot 26 | mysql -e 'SHOW DATABASES;' -uroot -proot 27 | 28 | - name: Pull images 29 | run: | 30 | docker pull tobybatch/kimai2:fpm-prod 31 | docker pull tobybatch/kimai2:fpm-dev 32 | docker pull tobybatch/kimai2:apache-prod 33 | docker pull tobybatch/kimai2:apache-dev 34 | 35 | - name: Test fpm 36 | run: docker run --rm -ti -e DATABASE_URL=mysql://root:root@localhost:3306/kimai --entrypoint /self-test.sh kimai/kimai2:fpm-prod 37 | 38 | - name: Test fpm-dev 39 | run: docker run --rm -ti -e DATABASE_URL=mysql://root:root@localhost:3306/kimai --entrypoint /self-test.sh kimai/kimai2:fpm-dev 40 | 41 | - name: Test apache 42 | run: docker run --rm -ti -e DATABASE_URL=mysql://root:root@localhost:3306/kimai --entrypoint /self-test.sh kimai/kimai2:apache-prod 43 | 44 | - name: Test apache-dev 45 | run: docker run --rm -ti -e DATABASE_URL=mysql://root:root@localhost:3306/kimai --entrypoint /self-test.sh kimai/kimai2:apache-dev 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /assets/monolog.yaml: -------------------------------------------------------------------------------- 1 | when@prod: 2 | monolog: 3 | channels: ["deprecation"] 4 | handlers: 5 | main: 6 | type: fingers_crossed 7 | action_level: error 8 | handler: nested 9 | excluded_http_codes: [403, 404] 10 | nested: 11 | type: stream 12 | level: info 13 | path: "php://stderr" 14 | console: 15 | type: console 16 | process_psr_3_messages: false 17 | channels: ["!event", "!doctrine"] 18 | deprecation: 19 | type: stream 20 | channels: ["deprecation"] 21 | path: "php://stderr" 22 | 23 | when@dev: 24 | monolog: 25 | channels: ["deprecation"] 26 | handlers: 27 | main: 28 | type: stream 29 | path: "php://stderr" 30 | level: info 31 | channels: ["!event"] 32 | # uncomment to get logging in your browser 33 | # you may have to allow bigger header sizes in your Web server configuration 34 | #firephp: 35 | # type: firephp 36 | # level: info 37 | #chromephp: 38 | # type: chromephp 39 | # level: info 40 | console: 41 | type: console 42 | process_psr_3_messages: false 43 | channels: ["!event", "!doctrine", "!console"] 44 | deprecation: 45 | type: stream 46 | channels: ["deprecation"] 47 | path: "php://stderr" 48 | 49 | when@test: 50 | monolog: 51 | handlers: 52 | main: 53 | type: stream 54 | path: "php://stderr" 55 | level: info 56 | channels: ["!event"] 57 | -------------------------------------------------------------------------------- /assets/service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | function waitForDB() { 4 | # Parse sql connection data 5 | if [ ! -z "$DATABASE_URL" ]; then 6 | DB_TYPE=$(awk -F '[/:@]' '{print $1}' <<< "$DATABASE_URL") 7 | DB_USER=$(awk -F '[/:@]' '{print $4}' <<< "$DATABASE_URL") 8 | DB_PASS=$(awk -F '[/:@]' '{print $5}' <<< "$DATABASE_URL") 9 | DB_HOST=$(awk -F '[/:@]' '{print $6}' <<< "$DATABASE_URL") 10 | DB_PORT=$(awk -F '[/:@]' '{print $7}' <<< "$DATABASE_URL") 11 | DB_BASE=$(awk -F '[/?]' '{print $4}' <<< "$DATABASE_URL") 12 | else 13 | DB_TYPE=${DB_TYPE:mysql} 14 | if [ "$DB_TYPE" == "mysql" ]; then 15 | export DATABASE_URL="${DB_TYPE}://${DB_USER:=kimai}:${DB_PASS:=kimai}@${DB_HOST:=sqldb}:${DB_PORT:=3306}/${DB_BASE:=kimai}" 16 | else 17 | echo "Unknown database type, cannot proceed. Only 'mysql' is supported, received: [$DB_TYPE]" 18 | exit 1 19 | fi 20 | fi 21 | 22 | re='^[0-9]+$' 23 | if ! [[ $DB_PORT =~ $re ]] ; then 24 | DB_PORT=3306 25 | fi 26 | 27 | echo "Wait for MySQL DB connection ..." 28 | until php /dbtest.php $DB_HOST $DB_BASE $DB_PORT $DB_USER $DB_PASS; do 29 | echo Checking DB: $? 30 | sleep 3 31 | done 32 | echo "Connection established" 33 | } 34 | 35 | function handleStartup() { 36 | # These are idempotent, run them anyway 37 | /opt/kimai/bin/console -n kimai:install 38 | /opt/kimai/bin/console -n kimai:update 39 | if [ ! -z "$ADMINPASS" ] && [ ! -a "$ADMINMAIL" ]; then 40 | /opt/kimai/bin/console kimai:user:create superadmin "$ADMINMAIL" ROLE_SUPER_ADMIN "$ADMINPASS" 41 | fi 42 | echo "$KIMAI" > /opt/kimai/var/installed 43 | echo "Kimai2 ready" 44 | } 45 | 46 | function runServer() { 47 | # Just while I'm fixing things 48 | /opt/kimai/bin/console kimai:reload --env="$APP_ENV" 49 | chown -R $USER_ID:$GROUP_ID /opt/kimai/var 50 | if [ -e /use_apache ]; then 51 | exec /usr/sbin/apache2 -D FOREGROUND 52 | elif [ -e /use_fpm ]; then 53 | exec php-fpm 54 | else 55 | echo "Error, unknown server type" 56 | fi 57 | } 58 | 59 | waitForDB 60 | handleStartup 61 | runServer 62 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | 4 | sqldb: 5 | image: mysql:5.7 6 | environment: 7 | - MYSQL_DATABASE=kimai 8 | - MYSQL_USER=kimaiuser 9 | - MYSQL_PASSWORD=kimaipassword 10 | - MYSQL_ROOT_PASSWORD=changemeplease 11 | #ports: 12 | # - 3336:3306 13 | volumes: 14 | - mysql:/var/lib/mysql 15 | command: --default-storage-engine innodb 16 | restart: unless-stopped 17 | healthcheck: 18 | test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost 19 | interval: 20s 20 | start_period: 10s 21 | timeout: 10s 22 | retries: 3 23 | 24 | nginx: 25 | image: tobybatch/nginx-fpm-reverse-proxy 26 | ports: 27 | - 8001:80 28 | volumes: 29 | - public:/opt/kimai/public:ro 30 | restart: unless-stopped 31 | depends_on: 32 | - kimai 33 | healthcheck: 34 | test: wget --spider http://nginx/health || exit 1 35 | interval: 20s 36 | start_period: 10s 37 | timeout: 10s 38 | retries: 3 39 | 40 | kimai: # This is the latest FPM image of kimai 41 | image: kimai/kimai2:fpm-dev 42 | environment: 43 | - ADMINMAIL=admin@kimai.local 44 | - ADMINPASS=changemeplease 45 | - DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai?charset=utf8&serverVersion=5.7 46 | - TRUSTED_HOSTS=nginx,localhost,127.0.0.1 47 | - MAILER_URL=smtp://mailer:1025 48 | - MAILER_FROM=kimai@example.com 49 | volumes: 50 | - public:/opt/kimai/public 51 | # - var:/opt/kimai/var 52 | # - ./ldap.conf:/etc/openldap/ldap.conf:z 53 | # - ./ROOT-CA.pem:/etc/ssl/certs/ROOT-CA.pem:z 54 | restart: unless-stopped 55 | 56 | phpmyadmin: 57 | image: phpmyadmin 58 | restart: always 59 | ports: 60 | - 8081:80 61 | environment: 62 | - PMA_ARBITRARY=1 63 | 64 | swagger: 65 | image: swaggerapi/swagger-ui 66 | ports: 67 | - 8080:8080 68 | volumes: 69 | - ./swagger.json:/swagger.json 70 | environment: 71 | - SWAGGER_JSON=/swagger.json 72 | 73 | mailer: 74 | image: schickling/mailcatcher 75 | ports: 76 | - "${MAILER_SMTP_PORT:-1025}:1025" 77 | - "${MAILER_ADMIN_PORT:-1080}:1080" 78 | 79 | 80 | volumes: 81 | var: 82 | public: 83 | mysql: 84 | -------------------------------------------------------------------------------- /assets/dbtest.php: -------------------------------------------------------------------------------- 1 | \PDO::ERRMODE_EXCEPTION ]);"; 11 | echo "*"; 12 | 13 | try { 14 | $pdo = new \PDO("mysql:host=$DB_HOST;dbname=$DB_BASE;port=$DB_PORT", "$DB_USER", "$DB_PASS", [ 15 | \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION 16 | ]); 17 | } catch(\Exception $ex) { 18 | switch ($ex->getCode()) { 19 | // we can immediately stop startup here and show the error message 20 | case 1045: 21 | echo 'Access denied (1045)'; 22 | die(1); 23 | // we can immediately stop startup here and show the error message 24 | case 1049: 25 | echo 'Unknown database (1049)'; 26 | die(2); 27 | // a lot of errors share the same meaningless error code zero 28 | case 0: 29 | // this error includes the database name, so we can only search for the static part of the error message 30 | if (stripos($ex->getMessage(), 'SQLSTATE[HY000] [1049] Unknown database') !== false) { 31 | echo 'Unknown database (0-1049)'; 32 | die(3); 33 | } 34 | switch ($ex->getMessage()) { 35 | // eg. no response (fw) - the startup script should retry it a couple of times 36 | case 'SQLSTATE[HY000] [2002] Operation timed out': 37 | echo 'Operation timed out (0-2002)'; 38 | die(4); 39 | // special case "localhost" with a stopped db server (should not happen in docker compose setup) 40 | case 'SQLSTATE[HY000] [2002] No such file or directory': 41 | echo 'Connection could not be established (0-2002)'; 42 | die(5); 43 | // using IP with stopped db server - the startup script should retry it a couple of times 44 | case 'SQLSTATE[HY000] [2002] Connection refused': 45 | echo 'Connection refused (0-2002)'; 46 | die(5); 47 | } 48 | echo $ex->getMessage() . " (0)"; 49 | die(7); 50 | default: 51 | // unknown error 52 | echo $ex->getMessage() . " (?)"; 53 | die(10); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /README.orig.md: -------------------------------------------------------------------------------- 1 | # Kimai Dockers 2 | 3 | We provide a set of docker images for the [Kimai](https://github.com/kimai/kimai) project. 4 | 5 | The built images are available from [Kimai](https://hub.docker.com/r/kimai/kimai2) at Docker Hub. 6 | 7 | ## Deving and Contributing 8 | 9 | We use commit linting to generate commits that we can auto generate changelogs from. To set these up, you will need node/nvm installed: 10 | 11 | ```bash 12 | nvm use 13 | npm install 14 | ``` 15 | 16 | See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. 17 | 18 | ## Quick start 19 | 20 | Run the latest production build: 21 | 22 | 1. Start a DB 23 | 24 | ```bash 25 | docker run --rm --name kimai-mysql-testing \ 26 | -e MYSQL_DATABASE=kimai \ 27 | -e MYSQL_USER=kimai \ 28 | -e MYSQL_PASSWORD=kimai \ 29 | -e MYSQL_ROOT_PASSWORD=kimai \ 30 | -p 3399:3306 -d mysql 31 | ``` 32 | 33 | 2. Start Kimai 34 | 35 | ```bash 36 | docker run --rm --name kimai-test \ 37 | -ti \ 38 | -p 8001:8001 \ 39 | -e DATABASE_URL=mysql://kimai:kimai@host.docker.internal:3399/kimai?charset=utf8&serverVersion=5.7 \ 40 | --add-host=host.docker.internal:host-gateway \ 41 | kimai/kimai2:apache 42 | ``` 43 | 44 | 3. Add a user using the terminal 45 | 46 | ```bash 47 | docker exec -ti kimai-test \ 48 | /opt/kimai/bin/console \ 49 | kimai:user:create admin admin@example.com ROLE_SUPER_ADMIN 50 | ``` 51 | 52 | Now, you can access the Kimai instance at . 53 | 54 | __Note:__ 55 | If you're using Docker for Windows or Docker for Mac, and you're getting "Connection refused" or other errors, you might need to change `${HOSTNAME}` to `host.docker.internal`. 56 | This is because the Kimai Docker container can only communicate within its network boundaries. Alternatively, you can start the container with the flag `--network="host"`. 57 | See [here](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) for more information. 58 | 59 | Keep in mind that this Docker setup is transient and the data will disappear when you remove the containers. 60 | 61 | ```bash 62 | docker stop kimai-mysql-testing kimai-test 63 | docker rm kimai-mysql-testing kimai-test 64 | ``` 65 | 66 | ## Using docker-compose 67 | 68 | See [https://www.kimai.org/documentation/docker-compose.html](https://www.kimai.org/documentation/docker-compose.html) 69 | 70 | ## Documentation 71 | 72 | [https://www.kimai.org/documentation/docker.html](https://www.kimai.org/documentation/docker.html) 73 | -------------------------------------------------------------------------------- /compose/traefik/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | # Example setup for "Traefik" V2 reverse proxy. 4 | # Copy the "example.env" to ".env" and modify the values to your needs. 5 | # Then run "docker compose up -d" and you're done. 6 | 7 | networks: 8 | # we assume this is where your "traefik" instance is located. 9 | # Should be created manually, not via compose. 10 | web: 11 | external: true 12 | name: traefik 13 | # internal database network 14 | kimai_net: 15 | driver: bridge 16 | internal: true 17 | name: kimai_net 18 | 19 | services: 20 | kimai_db: 21 | hostname: kimai_db 22 | container_name: kimai_db 23 | image: mysql:latest 24 | restart: unless-stopped 25 | networks: 26 | - kimai_net 27 | environment: 28 | MYSQL_DATABASE: ${SQL_DB_NAME} 29 | MYSQL_USER: ${SQL_USER_NAME} 30 | MYSQL_PASSWORD: ${SQL_USER_PASS} 31 | MYSQL_ROOT_PASSWORD: ${SQL_ROOT_PASS} 32 | volumes: 33 | - ./kimai/database:/var/lib/mysql 34 | 35 | kimai: 36 | hostname: kimai 37 | container_name: kimai 38 | image: kimai/kimai2:apache-latest 39 | restart: unless-stopped 40 | networks: 41 | - kimai_net 42 | - web 43 | depends_on: 44 | - kimai_db 45 | environment: 46 | APP_ENV: prod 47 | ADMINMAIL: ${KIMAI_ADMIN_MAIL} 48 | ADMINPASS: ${KIMAI_ADMIN_PASS} 49 | DATABASE_URL: mysql://${SQL_USER_NAME}:${SQL_USER_PASS}@kimai_db/${SQL_DB_NAME} 50 | TRUSTED_HOSTS: nginx,localhost,127.0.0.1,traefik,kimai.${HOST} 51 | TRUSTED_PROXIES: nginx,localhost,127.0.0.1,traefik,kimai.${HOST} 52 | memory_limit: 2048 53 | labels: 54 | traefik.enable: true 55 | # HTTP -> HTTPS redirect middleware 56 | traefik.http.routers.kimai-redirect.entrypoints: web 57 | traefik.http.routers.kimai-redirect.rule: Host(`kimai.${HOST}`) 58 | traefik.http.routers.kimai-redirect.middlewares: httpsredirect 59 | traefik.http.middlewares.httpsredirect.redirectscheme.scheme: https 60 | # HTTPS -> Service router 61 | traefik.http.routers.kimai.entrypoints: websecure 62 | traefik.http.routers.kimai.rule: Host(`kimai.${HOST}`) 63 | traefik.http.routers.kimai.tls: true 64 | traefik.http.routers.kimai.tls.certresolver: cfresolver 65 | traefik.http.routers.kimai.service: kimai 66 | #traefik.http.routers.kimai.middlewares: error-pages@docker 67 | # Service 68 | traefik.http.services.kimai.loadbalancer.server.port: 8001 69 | traefik.http.services.kimai.loadbalancer.server.scheme: http 70 | traefik.http.services.kimai.loadbalancer.passHostHeader: true 71 | #volumes: 72 | # - ./kimai/apache2.conf:/etc/apache2/onlySaml.conf 73 | # - ./kimai/local.yaml:/opt/kimai/config/packages/local.yaml -------------------------------------------------------------------------------- /assets/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | KIMAI=$(cat /opt/kimai/version.txt) 4 | echo $KIMAI 5 | 6 | 7 | function config() { 8 | # set mem limits and copy in custom logger config 9 | if [ -z "$memory_limit" ]; then 10 | memory_limit=256M 11 | fi 12 | 13 | 14 | # Parse sql connection data 15 | if [ ! -z "$DATABASE_URL" ]; then 16 | DB_TYPE=$(awk -F '[/:@]' '{print $1}' <<< "$DATABASE_URL") 17 | DB_USER=$(awk -F '[/:@]' '{print $4}' <<< "$DATABASE_URL") 18 | DB_PASS=$(awk -F '[/:@]' '{print $5}' <<< "$DATABASE_URL") 19 | DB_HOST=$(awk -F '[/:@]' '{print $6}' <<< "$DATABASE_URL") 20 | DB_PORT=$(awk -F '[/:@]' '{print $7}' <<< "$DATABASE_URL") 21 | DB_BASE=$(awk -F '[/?]' '{print $4}' <<< "$DATABASE_URL") 22 | else 23 | DB_TYPE=${DB_TYPE:mysql} 24 | if [ "$DB_TYPE" == "mysql" ]; then 25 | export DATABASE_URL="${DB_TYPE}://${DB_USER:=kimai}:${DB_PASS:=kimai}@${DB_HOST:=sqldb}:${DB_PORT:=3306}/${DB_BASE:=kimai}" 26 | else 27 | echo "Unknown database type, cannot proceed. Only 'mysql' is supported, received: [$DB_TYPE]" 28 | exit 1 29 | fi 30 | fi 31 | 32 | re='^[0-9]+$' 33 | if ! [[ $DB_PORT =~ $re ]] ; then 34 | DB_PORT=3306 35 | fi 36 | 37 | echo "Wait for MySQL DB connection ..." 38 | until php /dbtest.php $DB_HOST $DB_BASE $DB_PORT $DB_USER $DB_PASS; do 39 | echo Checking DB: $? 40 | sleep 3 41 | done 42 | echo "Connection established" 43 | } 44 | 45 | function handleStartup() { 46 | # set mem limits and copy in custom logger config 47 | sed -i "s/memory_limit.*/memory_limit=$memory_limit/g" /usr/local/etc/php/php.ini 48 | cp /assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml 49 | 50 | tar -zx -C /opt/kimai -f /var/tmp/public.tgz 51 | 52 | if [ -z "$USER_ID" ]; then 53 | USER_ID=$(id -u www-data) 54 | fi 55 | if [ -z "$GROUP_ID" ]; then 56 | GROUP_ID=$(id -g www-data) 57 | fi 58 | 59 | # if group doesn't exist 60 | if grep -w "$GROUP_ID" /etc/group &>/dev/null; then 61 | echo Group already exists 62 | else 63 | echo www-kimai:x:"$GROUP_ID": >> /etc/group 64 | grpconv 65 | fi 66 | 67 | # if user doesn't exist 68 | if id "$USER_ID" &>/dev/null; then 69 | echo User already exists 70 | else 71 | echo www-kimai:x:"$USER_ID":"$GROUP_ID":www-kimai:/var/www:/usr/sbin/nologin >> /etc/passwd 72 | pwconv 73 | fi 74 | 75 | if [ -e /use_apache ]; then 76 | export APACHE_RUN_USER=$(id -nu "$USER_ID") 77 | # This doesn't _exactly_ run as the specified GID, it runs as the GID of the specified user but WTF 78 | export APACHE_RUN_GROUP=$(id -ng "$USER_ID") 79 | export APACHE_PID_FILE=/var/run/apache2/apache2.pid 80 | export APACHE_RUN_DIR=/var/run/apache2 81 | export APACHE_LOCK_DIR=/var/lock/apache2 82 | export APACHE_LOG_DIR=/var/log/apache2 83 | export LANG=C 84 | elif [ -e /use_fpm ]; then 85 | sed -i "s/user = .*/user = $USER_ID/g" /usr/local/etc/php-fpm.d/www.conf 86 | sed -i "s/group = .*/group = $GROUP_ID/g" /usr/local/etc/php-fpm.d/www.conf 87 | echo "Setting fpm to run as ${USER_ID}:${GROUP_ID}" 88 | else 89 | echo "Error, unknown server type" 90 | fi 91 | } 92 | 93 | config 94 | handleStartup 95 | 96 | exec /service.sh 97 | -------------------------------------------------------------------------------- /.github/workflows/kimai-release.yml: -------------------------------------------------------------------------------- 1 | name: '[Deprecated] Build release' 2 | 3 | on: 4 | workflow_dispatch: 5 | repository_dispatch: 6 | types: [kimai_release] 7 | 8 | jobs: 9 | build: 10 | strategy: 11 | matrix: 12 | type: [ dev, prod ] 13 | server: [ fpm, apache ] 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | 18 | - name: Checkout code 19 | uses: actions/checkout@v3 20 | 21 | - name: Install buildx 22 | uses: docker/setup-buildx-action@v2 23 | 24 | - name: Install lastversion 25 | run: sudo apt-get update -y; sudo apt-get install --no-install-recommends -y python3 python3-pip; pip install lastversion 26 | 27 | - name: Login to DockerHub 28 | uses: docker/login-action@v2 29 | with: 30 | username: ${{secrets.DOCKERHUB_USERNAME}} 31 | password: ${{secrets.DOCKERHUB_PASSWORD}} 32 | 33 | - name: get lastest version 34 | id: remote_version 35 | run: echo "::set-output name=version::$(lastversion https://github.com/kimai/kimai)" 36 | 37 | - name: Build 38 | uses: docker/build-push-action@v4 39 | with: 40 | context: . 41 | build-args: | 42 | KIMAI=${{steps.remote_version.outputs.version}} 43 | TIMEZONE=Europe/London 44 | BASE=${{ matrix.server }} 45 | target: ${{ matrix.type }} 46 | platforms: linux/amd64,linux/arm64 #,linux/arm/v8,linux/arm/v7,linux/arm/v6 47 | tags: | 48 | kimai/kimai2:${{ matrix.server }}-${{ matrix.type }} 49 | kimai/kimai2:${{ matrix.server }}-${{steps.remote_version.outputs.version}}-${{ matrix.type }} 50 | push: true 51 | 52 | - name: Test Lite 53 | run: docker run --rm --entrypoint /assets/test-lite.sh kimai/kimai2:${{ matrix.server }}-${{ matrix.type }} 54 | 55 | tag: 56 | needs: build 57 | runs-on: ubuntu-latest 58 | steps: 59 | 60 | - name: Login to DockerHub 61 | uses: docker/login-action@v2 62 | with: 63 | username: ${{secrets.DOCKERHUB_USERNAME}} 64 | password: ${{secrets.DOCKERHUB_PASSWORD}} 65 | 66 | - name: Pull images 67 | run: | 68 | docker pull kimai/kimai2:fpm-prod 69 | docker pull kimai/kimai2:fpm-dev 70 | docker pull kimai/kimai2:apache-prod 71 | docker pull kimai/kimai2:apache-dev 72 | 73 | - name: Tag fpm 74 | run: | 75 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:fpm 76 | docker push kimai/kimai2:fpm 77 | 78 | - name: Tag fpm latest 79 | run: | 80 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:fpm-latest 81 | docker push kimai/kimai2:fpm-latest 82 | 83 | - name: Tag latest 84 | run: | 85 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:latest 86 | docker push kimai/kimai2:latest 87 | 88 | - name: Tag prod 89 | run: | 90 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:prod 91 | docker push kimai/kimai2:prod 92 | 93 | - name: Tag apache 94 | run: | 95 | docker tag kimai/kimai2:apache-prod kimai/kimai2:apache 96 | docker push kimai/kimai2:apache 97 | 98 | - name: Tag apache latest 99 | run: | 100 | docker tag kimai/kimai2:apache-prod kimai/kimai2:apache-latest 101 | docker push kimai/kimai2:apache-latest 102 | 103 | - name: Tag dev 104 | run: | 105 | docker tag kimai/kimai2:apache-dev kimai/kimai2:dev 106 | docker push kimai/kimai2:dev 107 | -------------------------------------------------------------------------------- /.github/workflows/build-default.yml: -------------------------------------------------------------------------------- 1 | # act -j build -W ./.github/workflows/build-multiarch.yml --secret-file .dockerhub.secrets 2 | name: 'Build default' 3 | 4 | on: 5 | workflow_dispatch: 6 | # repository_dispatch: 7 | # types: [kimai_release] 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | type: [ dev, prod ] 14 | server: [ fpm, apache ] 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | 19 | - name: Checkout code 20 | uses: actions/checkout@v3 21 | 22 | - name: Install buildx 23 | uses: docker/setup-buildx-action@v2 24 | 25 | - name: Install lastversion 26 | run: sudo apt-get update -y; sudo apt-get install --no-install-recommends -y python3 python3-pip; pip install lastversion 27 | 28 | - name: Login to DockerHub 29 | uses: docker/login-action@v2 30 | with: 31 | username: ${{secrets.DOCKERHUB_USERNAME}} 32 | password: ${{secrets.DOCKERHUB_PASSWORD}} 33 | 34 | - name: get lastest version 35 | id: remote_version 36 | run: echo "::set-output name=version::$(lastversion https://github.com/kimai/kimai)" 37 | 38 | - name: Build 39 | uses: docker/build-push-action@v4 40 | with: 41 | context: . 42 | build-args: | 43 | KIMAI=${{steps.remote_version.outputs.version}} 44 | TIMEZONE=Europe/London 45 | BASE=${{ matrix.server }} 46 | target: ${{ matrix.type }} 47 | platforms: linux/amd64,linux/arm64 48 | tags: | 49 | kimai/kimai2:${{ matrix.server }}-${{ matrix.type }} 50 | kimai/kimai2:${{ matrix.server }}-${{steps.remote_version.outputs.version}}-${{ matrix.type }} 51 | push: true 52 | 53 | - name: Test Lite 54 | run: docker run --rm --entrypoint /assets/test-lite.sh kimai/kimai2:${{ matrix.server }}-${{ matrix.type }} 55 | 56 | tag: 57 | needs: build 58 | runs-on: ubuntu-latest 59 | steps: 60 | 61 | - name: Login to DockerHub 62 | uses: docker/login-action@v2 63 | with: 64 | username: ${{secrets.DOCKERHUB_USERNAME}} 65 | password: ${{secrets.DOCKERHUB_PASSWORD}} 66 | 67 | - name: Pull images 68 | run: | 69 | docker pull kimai/kimai2:fpm-prod 70 | docker pull kimai/kimai2:fpm-dev 71 | docker pull kimai/kimai2:apache-prod 72 | docker pull kimai/kimai2:apache-dev 73 | 74 | - name: Tag fpm 75 | run: | 76 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:fpm 77 | docker push kimai/kimai2:fpm 78 | 79 | - name: Tag fpm latest 80 | run: | 81 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:fpm-latest 82 | docker push kimai/kimai2:fpm-latest 83 | 84 | - name: Tag latest 85 | run: | 86 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:latest 87 | docker push kimai/kimai2:latest 88 | 89 | - name: Tag prod 90 | run: | 91 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:prod 92 | docker push kimai/kimai2:prod 93 | 94 | - name: Tag apache 95 | run: | 96 | docker tag kimai/kimai2:apache-prod kimai/kimai2:apache 97 | docker push kimai/kimai2:apache 98 | 99 | - name: Tag apache latest 100 | run: | 101 | docker tag kimai/kimai2:apache-prod kimai/kimai2:apache-latest 102 | docker push kimai/kimai2:apache-latest 103 | 104 | - name: Tag dev 105 | run: | 106 | docker tag kimai/kimai2:apache-dev kimai/kimai2:dev 107 | docker push kimai/kimai2:dev 108 | -------------------------------------------------------------------------------- /.github/workflows/build-multiarch.yml: -------------------------------------------------------------------------------- 1 | # act -j build -W ./.github/workflows/build-multiarch.yml --secret-file .dockerhub.secrets 2 | name: 'Build multiarch' 3 | 4 | on: 5 | workflow_dispatch: 6 | # repository_dispatch: 7 | # types: [kimai_release] 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | type: [ dev, prod ] 14 | server: [ fpm, apache ] 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | 19 | - name: Checkout code 20 | uses: actions/checkout@v3 21 | 22 | - name: Install buildx 23 | uses: docker/setup-buildx-action@v2 24 | 25 | - name: Install lastversion 26 | run: sudo apt-get update -y; sudo apt-get install --no-install-recommends -y python3 python3-pip; pip install lastversion 27 | 28 | - name: Login to DockerHub 29 | uses: docker/login-action@v2 30 | with: 31 | username: ${{secrets.DOCKERHUB_USERNAME}} 32 | password: ${{secrets.DOCKERHUB_PASSWORD}} 33 | 34 | - name: get lastest version 35 | id: remote_version 36 | run: echo "::set-output name=version::$(lastversion https://github.com/kimai/kimai)" 37 | 38 | - name: Build 39 | uses: docker/build-push-action@v4 40 | with: 41 | context: . 42 | build-args: | 43 | KIMAI=${{steps.remote_version.outputs.version}} 44 | TIMEZONE=Europe/London 45 | BASE=${{ matrix.server }} 46 | target: ${{ matrix.type }} 47 | platforms: linux/amd64,linux/arm64 #,linux/arm/v8,linux/arm/v7,linux/arm/v6 48 | tags: | 49 | kimai/kimai2:${{ matrix.server }}-${{ matrix.type }} 50 | kimai/kimai2:${{ matrix.server }}-${{steps.remote_version.outputs.version}}-${{ matrix.type }} 51 | push: true 52 | 53 | - name: Test Lite 54 | run: docker run --rm --entrypoint /assets/test-lite.sh kimai/kimai2:${{ matrix.server }}-${{ matrix.type }} 55 | 56 | tag: 57 | needs: build 58 | runs-on: ubuntu-latest 59 | steps: 60 | 61 | - name: Login to DockerHub 62 | uses: docker/login-action@v2 63 | with: 64 | username: ${{secrets.DOCKERHUB_USERNAME}} 65 | password: ${{secrets.DOCKERHUB_PASSWORD}} 66 | 67 | - name: Pull images 68 | run: | 69 | docker pull kimai/kimai2:fpm-prod 70 | docker pull kimai/kimai2:fpm-dev 71 | docker pull kimai/kimai2:apache-prod 72 | docker pull kimai/kimai2:apache-dev 73 | 74 | - name: Tag fpm 75 | run: | 76 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:fpm 77 | docker push kimai/kimai2:fpm 78 | 79 | - name: Tag fpm latest 80 | run: | 81 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:fpm-latest 82 | docker push kimai/kimai2:fpm-latest 83 | 84 | - name: Tag latest 85 | run: | 86 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:latest 87 | docker push kimai/kimai2:latest 88 | 89 | - name: Tag prod 90 | run: | 91 | docker tag kimai/kimai2:fpm-prod kimai/kimai2:prod 92 | docker push kimai/kimai2:prod 93 | 94 | - name: Tag apache 95 | run: | 96 | docker tag kimai/kimai2:apache-prod kimai/kimai2:apache 97 | docker push kimai/kimai2:apache 98 | 99 | - name: Tag apache latest 100 | run: | 101 | docker tag kimai/kimai2:apache-prod kimai/kimai2:apache-latest 102 | docker push kimai/kimai2:apache-latest 103 | 104 | - name: Tag dev 105 | run: | 106 | docker tag kimai/kimai2:apache-dev kimai/kimai2:dev 107 | docker push kimai/kimai2:dev 108 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include .env 2 | 3 | ifndef TIMEZONE 4 | TIMEZONE := Europe/London 5 | endif 6 | 7 | ifndef KIMAI_VERSION 8 | KIMAI_VERSION := main 9 | endif 10 | 11 | ZAP := $(shell echo $(KIMAI_VERSION) | egrep -q "[0-9].[0-9]+" && echo matched) 12 | 13 | build: 14 | docker build -t kimai/kimai2:fpm-${KIMAI_VERSION}-dev --build-arg KIMAI=${KIMAI_VERSION} --build-arg BASE=fpm --build-arg TZ=${TIMEZONE} --target=dev . 15 | docker build -t kimai/kimai2:fpm-${KIMAI_VERSION}-prod --build-arg KIMAI=${KIMAI_VERSION} --build-arg BASE=fpm --build-arg TZ=${TIMEZONE} --target=prod . 16 | docker build -t kimai/kimai2:apache-${KIMAI_VERSION}-dev --build-arg KIMAI=${KIMAI_VERSION} --build-arg BASE=apache --build-arg TZ=${TIMEZONE} --target=dev . 17 | docker build -t kimai/kimai2:apache-${KIMAI_VERSION}-prod --build-arg KIMAI=${KIMAI_VERSION} --build-arg BASE=apache --build-arg TZ=${TIMEZONE} --target=prod . 18 | 19 | tag: 20 | ifeq (${ZAP}, matched) 21 | docker tag kimai/kimai2:fpm-${KIMAI_VERSION}-prod kimai/kimai2:fpm 22 | docker tag kimai/kimai2:fpm-${KIMAI_VERSION}-dev kimai/kimai2:fpm-dev 23 | docker tag kimai/kimai2:apache-${KIMAI_VERSION}-prod kimai/kimai2:apache 24 | docker tag kimai/kimai2:apache-${KIMAI_VERSION}-dev kimai/kimai2:apache-dev 25 | docker tag kimai/kimai2:fpm-${KIMAI_VERSION}-prod kimai/kimai2:latest 26 | docker tag kimai/kimai2:apache-${KIMAI_VERSION}-dev kimai/kimai2:latest-dev 27 | else 28 | $(error ${KIMAI_VERSION} does not look like a release, x.y or x.y.z. Not tagging) 29 | endif 30 | 31 | push: 32 | docker push kimai/kimai2:fpm-${KIMAI_VERSION}-dev 33 | docker push kimai/kimai2:fpm-${KIMAI_VERSION}-prod 34 | docker push kimai/kimai2:apache-${KIMAI_VERSION}-dev 35 | docker push kimai/kimai2:apache-${KIMAI_VERSION}-prod 36 | ifeq (${ZAP}, matched) 37 | docker push kimai/kimai2:fpm 38 | docker push kimai/kimai2:fpm-dev 39 | docker push kimai/kimai2:apache 40 | docker push kimai/kimai2:apache-dev 41 | docker push kimai/kimai2:latest 42 | docker push kimai/kimai2:latest-dev 43 | endif 44 | 45 | clean-test: 46 | docker stop kimai-mysql-testing || true 47 | docker stop kimai-test-fpm-${KIMAI_VERSION}-prod || true 48 | docker stop kimai-test-fpm-${KIMAI_VERSION}-dev || true 49 | docker stop kimai-test-apache-${KIMAI_VERSION}-prod || true 50 | docker stop kimai-test-apache-${KIMAI_VERSION}-dev || true 51 | docker network rm kimai-test || true 52 | 53 | test: clean-test 54 | docker network create --driver bridge kimai-test 55 | docker run --rm --network kimai-test --name kimai-mysql-testing -e MYSQL_DATABASE=kimai -e MYSQL_USER=kimai -e MYSQL_PASSWORD=kimai -e MYSQL_ROOT_PASSWORD=kimai -p 3399:3306 -d mysql 56 | docker run --rm --network kimai-test --name kimai-test-fpm-${KIMAI_VERSION}-prod -ti -e DATABASE_URL=mysql://kimai:kimai@kimai-mysql-testing:3306/kimai --entrypoint /self-test.sh kimai/kimai2:fpm-${KIMAI_VERSION}-prod 57 | docker run --rm --network kimai-test --name kimai-test-fpm-${KIMAI_VERSION}-dev -ti -e DATABASE_URL=mysql://kimai:kimai@kimai-mysql-testing:3306/kimai --entrypoint /self-test.sh kimai/kimai2:fpm-${KIMAI_VERSION}-dev 58 | docker run --rm --network kimai-test --name kimai-test-apache-${KIMAI_VERSION}-prod -ti -e DATABASE_URL=mysql://kimai:kimai@kimai-mysql-testing:3306/kimai --entrypoint /self-test.sh kimai/kimai2:apache-${KIMAI_VERSION}-prod 59 | docker run --rm --network kimai-test --name kimai-test-apache-${KIMAI_VERSION}-dev -ti -e DATABASE_URL=mysql://kimai:kimai@kimai-mysql-testing:3306/kimai --entrypoint /self-test.sh kimai/kimai2:apache-${KIMAI_VERSION}-dev 60 | 61 | pull: 62 | docker pull kimai/kimai2:fpm-dev 63 | docker pull kimai/kimai2:apache-dev 64 | docker pull kimai/kimai2:apache-latest 65 | docker pull kimai/kimai2:fpm-prod 66 | 67 | show-versions: pull 68 | docker run --entrypoint cat kimai/kimai2:apache-dev /opt/kimai/version.txt 69 | docker run --entrypoint cat kimai/kimai2:apache-prod /opt/kimai/version.txt 70 | docker run --entrypoint cat kimai/kimai2:fpm-dev /opt/kimai/version.txt 71 | docker run --entrypoint cat kimai/kimai2:fpm-prod /opt/kimai/version.txt 72 | 73 | changelog_patch: 74 | # npx standard-version --release-as 1.1.0 75 | npx standard-version --release-as patch 76 | 77 | changelog_minor: 78 | npx standard-version --release-as minor 79 | 80 | changelog_major: 81 | npx standard-version --release-as major 82 | 83 | build-version: build test push 84 | 85 | release: build test tag push 86 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [2.3.1](https://github.com/tobybatch/kimai2/compare/v2.3.0...v2.3.1) (2023-06-22) 6 | 7 | 8 | ### Features 9 | 10 | * re-enable workflows ([b046420](https://github.com/tobybatch/kimai2/commits/b046420ce5e15d57bfb50e1950311708bf773c37)) 11 | 12 | ## [2.3.0](https://github.com/tobybatch/kimai2/compare/v2.2.1...v2.3.0) (2023-05-25) 13 | 14 | 15 | ### Features 16 | 17 | * enable v2 builds ([d6d11ad](https://github.com/tobybatch/kimai2/commits/d6d11ad40f7987b2e2a4e9147a3c47b4116c5a5f)) 18 | * enables opcache ([#452](https://github.com/tobybatch/kimai2/issues/452)) ([a6e14b4](https://github.com/tobybatch/kimai2/commits/a6e14b45270ade88974ba46a2cba759fb09a3e9f)), closes [#451](https://github.com/tobybatch/kimai2/issues/451) 19 | * traefik compose example ([#479](https://github.com/tobybatch/kimai2/issues/479)) ([aaec0e5](https://github.com/tobybatch/kimai2/commits/aaec0e57dd1120b8f3b2a4528e4abc9c2d93abbc)) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * small tweaks for v2 ([c2d6e3b](https://github.com/tobybatch/kimai2/commits/c2d6e3b5794cc9c680561d41789388fc32c072fc)) 25 | * **assets:** Change create user command for new version ([#505](https://github.com/tobybatch/kimai2/issues/505)) ([41731a1](https://github.com/tobybatch/kimai2/commits/41731a19a4b19cbf72474355a7ecccf1e14e2d26)) 26 | * [#462](https://github.com/tobybatch/kimai2/issues/462) ([7212829](https://github.com/tobybatch/kimai2/commits/7212829d3dc8a3d0451cc4f70d99e13b49cd551a)) 27 | * [#495](https://github.com/tobybatch/kimai2/issues/495) and [#488](https://github.com/tobybatch/kimai2/issues/488) ([#496](https://github.com/tobybatch/kimai2/issues/496)) ([0fae66b](https://github.com/tobybatch/kimai2/commits/0fae66bb4ca5e0e73b244733d5591a85cac8e19c)) 28 | * added ENV COMPOSER_ALLOW_SUPERUSER=1 to allow LDAP build ([81a0166](https://github.com/tobybatch/kimai2/commits/81a01668169c8fc1b4ad5e9f0ee53f4e83aa1569)) 29 | * added swagger and phpmyadmin ([80655ff](https://github.com/tobybatch/kimai2/commits/80655ff3553ba2d313170686b444b78fb6d92f6b)) 30 | * build arg passthrough; add PHP & composer ver ([#478](https://github.com/tobybatch/kimai2/issues/478)) ([2afc8cb](https://github.com/tobybatch/kimai2/commits/2afc8cbd31b4b9769009577d8fc380a302840423)) 31 | * bump node version to 18 ([3f32d05](https://github.com/tobybatch/kimai2/commits/3f32d059bef88d92a7352933938302ff8a22651d)) 32 | * capped the build version at 1.x ([1d4e8ba](https://github.com/tobybatch/kimai2/commits/1d4e8ba7fc5fb82c04b405a9af06f9241c06362b)) 33 | * disable auto build on push ([#472](https://github.com/tobybatch/kimai2/issues/472)) ([b871f0e](https://github.com/tobybatch/kimai2/commits/b871f0e59fec5a5798fe15d5e44fe88e09b6c396)) 34 | * moved back to docker buildx ([a9219bd](https://github.com/tobybatch/kimai2/commits/a9219bdac152c4aac907177a725319e14afd0c4b)) 35 | * moved back to docker buildx ([62f1838](https://github.com/tobybatch/kimai2/commits/62f18388f5fe6f6efa44f698a849b03d795b23a8)) 36 | * push after build ([1cfbe9b](https://github.com/tobybatch/kimai2/commits/1cfbe9b0ae74f5ee6fed785834e27a307bc833f7)) 37 | * ready for v2 ([993e98e](https://github.com/tobybatch/kimai2/commits/993e98e628c7c7f8d76f091682655870908f1421)) 38 | * remove symfont cli ([#471](https://github.com/tobybatch/kimai2/issues/471)) ([160d797](https://github.com/tobybatch/kimai2/commits/160d797bb6ea67d632c86615b3a1efa47708533c)) 39 | * removed multi arch ([8f513f6](https://github.com/tobybatch/kimai2/commits/8f513f6d090fd38b72abe3b5a04bf7aa6240df11)) 40 | * removed tagging from multiarch build ([98e88c5](https://github.com/tobybatch/kimai2/commits/98e88c58a275ea789665c63185102d91b7a05cc5)) 41 | * restored cli logging for monolog ([470ecf0](https://github.com/tobybatch/kimai2/commits/470ecf07b80396af106d688c5c09e01fb63dbe53)) 42 | * try a different containerd src ([e79fcbc](https://github.com/tobybatch/kimai2/commits/e79fcbc3c2bd712cd21b5566c69b74b879872aa1)) 43 | * try a different containerd src ([e191dae](https://github.com/tobybatch/kimai2/commits/e191dae917cd7e5531e465c722c5b8dcef787213)) 44 | * wait to tag after building ([bdde499](https://github.com/tobybatch/kimai2/commits/bdde4992cdf672f0f394ad8f092e2ca6cce9980b)) 45 | 46 | ### [2.2.1](https://github.com/tobybatch/kimai2/compare/v2.0.4...v2.2.1) (2022-10-20) 47 | 48 | ### [2.0.4](https://github.com/tobybatch/kimai2/compare/v2.2.0...v2.0.4) (2022-10-20) 49 | 50 | ### Features 51 | 52 | * allow memory_limit to be set at runtime ([6934c36](https://github.com/tobybatch/kimai2/commits/6934c36588664a8d7659a225d399a1f3b14a7ebb)) 53 | * update docker action ([8bfcb69](https://github.com/tobybatch/kimai2/commits/8bfcb6918fb9c5dbedf4491c0d9c2c454edfd870)) 54 | 55 | ### Bug Fixes 56 | 57 | * added tags ([#326](https://github.com/tobybatch/kimai2/issues/326)) ([2d24f66](https://github.com/tobybatch/kimai2/commits/2d24f667a987cbd7459913ff327ebe5d757e73b1)) 58 | * apache base name ([150747d](https://github.com/tobybatch/kimai2/commits/150747da7445666c7537ff5e633cac4f3675e147)) 59 | * bad links in the examples file ([6e0ea6b](https://github.com/tobybatch/kimai2/commits/6e0ea6ba8078bdf2680a06b6a5d0decf0d9db798)) 60 | * corrected docs on build page ([9352609](https://github.com/tobybatch/kimai2/commits/935260940a4e08b7b4f937efb3bda8ada1d289bd)) 61 | * Docker Hub link in README ([26acc94](https://github.com/tobybatch/kimai2/commits/26acc945e1e0329cfcbf675754d0820364d10058)) 62 | * Docker Hub link in README ([c5fa08f](https://github.com/tobybatch/kimai2/commits/c5fa08fdab084fca7322472ee9f5d145b2f0bddb)) 63 | * Don't expose PHP version in response headers (prod only) ([#346](https://github.com/tobybatch/kimai2/issues/346)) ([1820d8e](https://github.com/tobybatch/kimai2/commits/1820d8e59dde3922f2899dc6ed141a55cc2bd2b7)) 64 | * roll up apache version ([acdb746](https://github.com/tobybatch/kimai2/commits/acdb74697cb75370422bfaf1df4b80b43e799e1f)) 65 | * target param corrected ([#353](https://github.com/tobybatch/kimai2/issues/353)) ([1806772](https://github.com/tobybatch/kimai2/commits/1806772f3fa16ce901255891ff574faa23836990)) 66 | * workflow ([#350](https://github.com/tobybatch/kimai2/issues/350)) ([25e5b5a](https://github.com/tobybatch/kimai2/commits/25e5b5ab8754f6133820c6e7c90cd27c2b1eb4ce)) 67 | 68 | ### [2.0.3](https://github.com/tobybatch/kimai2/compare/v2.2.0...v2.0.3) (2021-09-30) 69 | 70 | ### Features 71 | 72 | * add tzdata ([af9c60c](https://github.com/tobybatch/kimai2/commits/af9c60c27423668ab939da13a003aae891fa75d7)) 73 | 74 | ### [2.0.2](https://github.com/tobybatch/kimai2/compare/v2.0.1...v2.0.2) (2021-05-14) 75 | 76 | ### 2.0.1 (2021-04-30) 77 | 78 | ### Features 79 | 80 | * allow ingress annotations ([#244](https://github.com/tobybatch/kimai2/issues/244)) ([18751ac](https://github.com/tobybatch/kimai2/commits/18751acebf03b4ee56d631cebc587ab8b7bef997)) 81 | 82 | ### Bug Fixes 83 | 84 | * reinstated file marker ([625dbd7](https://github.com/tobybatch/kimai2/commits/625dbd7a26dba0c0d3005ca142be91b08a9c2a23)) 85 | * updated tag names in readme ([#243](https://github.com/tobybatch/kimai2/issues/243)) ([f6a6cac](https://github.com/tobybatch/kimai2/commits/f6a6cac3554d4ecd5fb1e2a1a30fec02ae1cd649)) 86 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # _ ___ _ ____ 2 | # | |/ (_)_ __ ___ __ _(_)___ \ 3 | # | ' /| | '_ ` _ \ / _` | | __) | 4 | # | . \| | | | | | | (_| | |/ __/ 5 | # |_|\_\_|_| |_| |_|\__,_|_|_____| 6 | # 7 | 8 | # Source base [fpm/apache] 9 | ARG BASE="fpm" 10 | ARG PHP_VER="8.1" 11 | ARG COMPOSER_VER="latest" 12 | # Branch name 13 | ARG KIMAI="main" 14 | # Timezone for images 15 | ARG TIMEZONE="Europe/Berlin" 16 | 17 | ########################### 18 | # Shared tools 19 | ########################### 20 | 21 | # full kimai source 22 | FROM alpine:latest AS git-dev 23 | # pass-through Arguments in every stage. See: https://benkyriakou.com/posts/docker-args-empty 24 | ARG KIMAI 25 | ARG TIMEZONE 26 | # I need to do this check somewhere, we discard all but the checkout so doing here doesn't hurt 27 | ADD assets/test-kimai-version.sh /test-kimai-version.sh 28 | RUN /test-kimai-version.sh 29 | RUN apk add --no-cache git && \ 30 | git clone --depth 1 --branch ${KIMAI} https://github.com/kimai/kimai.git /opt/kimai 31 | 32 | # production kimai source 33 | FROM git-dev AS git-prod 34 | 35 | WORKDIR /opt/kimai 36 | RUN rm -r tests 37 | 38 | # composer base image 39 | FROM composer:${COMPOSER_VER} AS composer 40 | 41 | ########################### 42 | # PHP extensions 43 | ########################### 44 | 45 | #fpm alpine php extension base 46 | FROM php:${PHP_VER}-fpm-alpine AS fpm-php-ext-base 47 | RUN apk add --no-cache \ 48 | # build-tools 49 | autoconf \ 50 | dpkg \ 51 | dpkg-dev \ 52 | file \ 53 | g++ \ 54 | gcc \ 55 | icu-dev \ 56 | libatomic \ 57 | libc-dev \ 58 | libgomp \ 59 | libmagic \ 60 | m4 \ 61 | make \ 62 | mpc1 \ 63 | mpfr4 \ 64 | musl-dev \ 65 | perl \ 66 | re2c \ 67 | # gd 68 | freetype-dev \ 69 | libpng-dev \ 70 | # icu 71 | icu-dev \ 72 | icu-data-full \ 73 | # ldap 74 | openldap-dev \ 75 | libldap \ 76 | # zip 77 | libzip-dev \ 78 | # xsl 79 | libxslt-dev 80 | 81 | 82 | # apache debian php extension base 83 | FROM php:${PHP_VER}-apache-buster AS apache-php-ext-base 84 | RUN apt-get update 85 | RUN apt-get install -y \ 86 | libldap2-dev \ 87 | libicu-dev \ 88 | libpng-dev \ 89 | libzip-dev \ 90 | libxslt1-dev \ 91 | libfreetype6-dev 92 | 93 | 94 | # php extension gd - 13.86s 95 | FROM ${BASE}-php-ext-base AS php-ext-gd 96 | RUN docker-php-ext-configure gd \ 97 | --with-freetype && \ 98 | docker-php-ext-install -j$(nproc) gd 99 | 100 | # php extension intl : 15.26s 101 | FROM ${BASE}-php-ext-base AS php-ext-intl 102 | RUN docker-php-ext-install -j$(nproc) intl 103 | 104 | # php extension ldap : 8.45s 105 | FROM ${BASE}-php-ext-base AS php-ext-ldap 106 | RUN docker-php-ext-configure ldap && \ 107 | docker-php-ext-install -j$(nproc) ldap 108 | 109 | # php extension pdo_mysql : 6.14s 110 | FROM ${BASE}-php-ext-base AS php-ext-pdo_mysql 111 | RUN docker-php-ext-install -j$(nproc) pdo_mysql 112 | 113 | # php extension zip : 8.18s 114 | FROM ${BASE}-php-ext-base AS php-ext-zip 115 | RUN docker-php-ext-install -j$(nproc) zip 116 | 117 | # php extension xsl : ?.?? s 118 | FROM ${BASE}-php-ext-base AS php-ext-xsl 119 | RUN docker-php-ext-install -j$(nproc) xsl 120 | 121 | # php extension redis 122 | FROM ${BASE}-php-ext-base AS php-ext-redis 123 | RUN yes no | pecl install redis && \ 124 | docker-php-ext-enable redis 125 | 126 | # php extension opcache 127 | FROM ${BASE}-php-ext-base AS php-ext-opcache 128 | RUN docker-php-ext-install -j$(nproc) opcache 129 | 130 | ########################### 131 | # fpm base build 132 | ########################### 133 | 134 | # fpm base build 135 | FROM php:${PHP_VER}-fpm-alpine AS fpm-base 136 | ARG KIMAI 137 | ARG TIMEZONE 138 | RUN apk add --no-cache \ 139 | bash \ 140 | coreutils \ 141 | freetype \ 142 | haveged \ 143 | icu \ 144 | icu-data-full \ 145 | libldap \ 146 | libpng \ 147 | libzip \ 148 | libxslt-dev \ 149 | fcgi \ 150 | tzdata && \ 151 | touch /use_fpm 152 | 153 | EXPOSE 9000 154 | 155 | HEALTHCHECK --interval=20s --timeout=10s --retries=3 \ 156 | CMD \ 157 | SCRIPT_NAME=/ping \ 158 | SCRIPT_FILENAME=/ping \ 159 | REQUEST_METHOD=GET \ 160 | cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1 161 | 162 | 163 | 164 | ########################### 165 | # apache base build 166 | ########################### 167 | 168 | FROM php:${PHP_VER}-apache-buster AS apache-base 169 | ARG KIMAI 170 | ARG TIMEZONE 171 | COPY assets/000-default.conf /etc/apache2/sites-available/000-default.conf 172 | RUN apt-get update && \ 173 | apt-get install -y \ 174 | bash \ 175 | haveged \ 176 | libicu63 \ 177 | libpng16-16 \ 178 | libzip4 \ 179 | libxslt1.1 \ 180 | libfreetype6 && \ 181 | echo "Listen 8001" > /etc/apache2/ports.conf && \ 182 | a2enmod rewrite && \ 183 | touch /use_apache 184 | 185 | EXPOSE 8001 186 | 187 | HEALTHCHECK --interval=20s --timeout=10s --retries=3 \ 188 | CMD curl -f http://127.0.0.1:8001 || exit 1 189 | 190 | 191 | 192 | ########################### 193 | # global base build 194 | ########################### 195 | 196 | FROM ${BASE}-base AS base 197 | ARG KIMAI 198 | ARG TIMEZONE 199 | 200 | LABEL maintainer="tobias@neontribe.co.uk" 201 | LABEL maintainer="bastian@schroll-software.de" 202 | 203 | ENV KIMAI=${KIMAI} 204 | ENV TIMEZONE=${TIMEZONE} 205 | RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone && \ 206 | # make composer home dir 207 | mkdir /composer && \ 208 | chown -R www-data:www-data /composer 209 | 210 | # copy startup script & DB checking script 211 | COPY assets/startup.sh /startup.sh 212 | COPY assets/service.sh /service.sh 213 | COPY assets/self-test.sh /self-test.sh 214 | COPY assets/dbtest.php /dbtest.php 215 | 216 | # copy composer 217 | COPY --from=composer /usr/bin/composer /usr/bin/composer 218 | 219 | # copy php extensions 220 | 221 | # PHP extension xsl 222 | COPY --from=php-ext-xsl /usr/local/etc/php/conf.d/docker-php-ext-xsl.ini /usr/local/etc/php/conf.d/docker-php-ext-xsl.ini 223 | COPY --from=php-ext-xsl /usr/local/lib/php/extensions/no-debug-non-zts-20210902/xsl.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/xsl.so 224 | # PHP extension pdo_mysql 225 | COPY --from=php-ext-pdo_mysql /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini 226 | COPY --from=php-ext-pdo_mysql /usr/local/lib/php/extensions/no-debug-non-zts-20210902/pdo_mysql.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/pdo_mysql.so 227 | # PHP extension zip 228 | COPY --from=php-ext-zip /usr/local/etc/php/conf.d/docker-php-ext-zip.ini /usr/local/etc/php/conf.d/docker-php-ext-zip.ini 229 | COPY --from=php-ext-zip /usr/local/lib/php/extensions/no-debug-non-zts-20210902/zip.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/zip.so 230 | # PHP extension ldap 231 | COPY --from=php-ext-ldap /usr/local/etc/php/conf.d/docker-php-ext-ldap.ini /usr/local/etc/php/conf.d/docker-php-ext-ldap.ini 232 | COPY --from=php-ext-ldap /usr/local/lib/php/extensions/no-debug-non-zts-20210902/ldap.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/ldap.so 233 | # PHP extension gd 234 | COPY --from=php-ext-gd /usr/local/etc/php/conf.d/docker-php-ext-gd.ini /usr/local/etc/php/conf.d/docker-php-ext-gd.ini 235 | COPY --from=php-ext-gd /usr/local/lib/php/extensions/no-debug-non-zts-20210902/gd.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/gd.so 236 | # PHP extension intl 237 | COPY --from=php-ext-intl /usr/local/etc/php/conf.d/docker-php-ext-intl.ini /usr/local/etc/php/conf.d/docker-php-ext-intl.ini 238 | COPY --from=php-ext-intl /usr/local/lib/php/extensions/no-debug-non-zts-20210902/intl.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/intl.so 239 | # PHP extension redis 240 | COPY --from=php-ext-redis /usr/local/etc/php/conf.d/docker-php-ext-redis.ini /usr/local/etc/php/conf.d/docker-php-ext-redis.ini 241 | COPY --from=php-ext-redis /usr/local/lib/php/extensions/no-debug-non-zts-20210902/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/redis.so 242 | COPY --from=php-ext-opcache /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini 243 | 244 | ENV DATABASE_URL=sqlite:///%kernel.project_dir%/var/data/kimai.sqlite 245 | ENV APP_SECRET=change_this_to_something_unique 246 | # The default container name for nginx is nginx 247 | ENV TRUSTED_PROXIES=nginx,localhost,127.0.0.1 248 | ENV TRUSTED_HOSTS=nginx,localhost,127.0.0.1 249 | ENV MAILER_FROM=kimai@example.com 250 | ENV MAILER_URL=null://localhost 251 | ENV ADMINPASS= 252 | ENV ADMINMAIL= 253 | ENV DB_TYPE= 254 | ENV DB_USER= 255 | ENV DB_PASS= 256 | ENV DB_HOST= 257 | ENV DB_PORT= 258 | ENV DB_BASE= 259 | ENV COMPOSER_MEMORY_LIMIT=-1 260 | # If this set then the image will start, run a self test and then exit. It's used for the release process 261 | ENV TEST_AND_EXIT= 262 | ENV COMPOSER_ALLOW_SUPERUSER=1 263 | ENV USER_ID= 264 | ENV GROUP_ID= 265 | 266 | VOLUME [ "/opt/kimai/var" ] 267 | 268 | CMD [ "/startup.sh" ] 269 | 270 | 271 | 272 | ########################### 273 | # final builds 274 | ########################### 275 | 276 | # developement build 277 | FROM base AS dev 278 | # copy kimai develop source 279 | COPY --from=git-dev --chown=www-data:www-data /opt/kimai /opt/kimai 280 | COPY assets /assets 281 | # do the composer deps installation 282 | RUN echo \$PATH 283 | RUN \ 284 | export COMPOSER_HOME=/composer && \ 285 | composer --no-ansi install --working-dir=/opt/kimai --optimize-autoloader && \ 286 | composer --no-ansi clearcache && \ 287 | composer --no-ansi require --working-dir=/opt/kimai laminas/laminas-ldap && \ 288 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini && \ 289 | chown -R www-data:www-data /opt/kimai /usr/local/etc/php/php.ini && \ 290 | mkdir -p /opt/kimai/var/logs && chmod 777 /opt/kimai/var/logs && \ 291 | sed "s/128M/-1/g" /usr/local/etc/php/php.ini-development > /opt/kimai/php-cli.ini && \ 292 | sed -i "s/env php/env -S php -c \/opt\/kimai\/php-cli.ini/g" /opt/kimai/bin/console && \ 293 | tar -C /opt/kimai -zcvf /var/tmp/public.tgz public && \ 294 | /opt/kimai/bin/console kimai:version | awk '{print $2}' > /opt/kimai/version.txt 295 | ENV APP_ENV=dev 296 | ENV DATABASE_URL= 297 | ENV memory_limit=256M 298 | 299 | # production build 300 | FROM base AS prod 301 | # copy kimai production source 302 | COPY --from=git-prod --chown=www-data:www-data /opt/kimai /opt/kimai 303 | COPY assets /assets 304 | # do the composer deps installation 305 | RUN \ 306 | export COMPOSER_HOME=/composer && \ 307 | composer --no-ansi install --working-dir=/opt/kimai --no-dev --optimize-autoloader && \ 308 | composer --no-ansi clearcache && \ 309 | composer --no-ansi require --working-dir=/opt/kimai laminas/laminas-ldap && \ 310 | cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini && \ 311 | sed -i "s/expose_php = On/expose_php = Off/g" /usr/local/etc/php/php.ini && \ 312 | sed -i "s/;opcache.enable=1/opcache.enable=1/g" /usr/local/etc/php/php.ini && \ 313 | sed -i "s/;opcache.memory_consumption=128/opcache.memory_consumption=256/g" /usr/local/etc/php/php.ini && \ 314 | sed -i "s/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=24/g" /usr/local/etc/php/php.ini && \ 315 | sed -i "s/;opcache.max_accelerated_files=10000/opcache.max_accelerated_files=100000/g" /usr/local/etc/php/php.ini && \ 316 | sed -i "s/opcache.validate_timestamps=1/opcache.validate_timestamps=0/g" /usr/local/etc/php/php.ini && \ 317 | sed -i "s/session.gc_maxlifetime = 1440/session.gc_maxlifetime = 604800/g" /usr/local/etc/php/php.ini && \ 318 | mkdir -p /opt/kimai/var/logs && chmod 777 /opt/kimai/var/logs && \ 319 | sed "s/128M/-1/g" /usr/local/etc/php/php.ini-development > /opt/kimai/php-cli.ini && \ 320 | chown -R www-data:www-data /opt/kimai /usr/local/etc/php/php.ini && \ 321 | tar -C /opt/kimai -zcvf /var/tmp/public.tgz public && \ 322 | /opt/kimai/bin/console kimai:version | awk '{print $2}' > /opt/kimai/version.txt 323 | ENV APP_ENV=prod 324 | ENV DATABASE_URL= 325 | ENV memory_limit=256M 326 | --------------------------------------------------------------------------------