├── .travis.yml ├── .gitignore ├── netlify.toml ├── pictures ├── doka.jpg ├── iam.jpg ├── VM@2x.png ├── garold.jpg ├── gitlab.png ├── intro.png ├── trends.png ├── beginner.jpg ├── compose.png ├── dockerhub.png ├── fcconf_bg.png ├── iamdone.png ├── kitematic.png ├── docker-boat.jpg ├── frameworks.png ├── life-stack.png ├── start-life.png ├── wordpress-1.png ├── Container@2x.png ├── dockerhub-node.png ├── fcconf_title.png ├── life-services.png ├── requirements.png ├── what-are-you.jpg ├── docker-app-drag.png ├── dockerhub-docker.png ├── dockerhub-nginx.png ├── dockerhub-python.png ├── dockerhub-sentry.png ├── dockerhub-ubuntu.png ├── sa-character-img.png ├── wordpress-files.png ├── backend-frameworks.png ├── dockerhub-minecraft.png ├── dockerhub-registry.png ├── dockerhub-sonarqube.png ├── dockerhub-wordpress.png ├── Geek-T-Shirt.jpg_q50.webp ├── container-on-machine.jpg ├── dockerhub-hello-world.png ├── winXPwin7_1527919170.jpg ├── dockerhub-google-lighthouse.png └── horizontal-logo-monochromatic-white.png ├── docs ├── images │ ├── logitech.png │ ├── ribbon-canvas.png │ ├── material-canvas.png │ ├── ribbon-printing.png │ └── material-printing.png ├── shortcuts.md ├── logitech.md ├── pdf.md └── features.md ├── .editorconfig ├── README.md ├── asciinema ├── 272875.cast ├── cashbox-api.cast └── lighthouse.cast ├── package.json ├── CONTRIBUTING.md ├── LICENSE.md └── index.html /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | prepared 3 | archive.zip 4 | presentation.pdf 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "prepared" 3 | command = "npm run prepare" 4 | 5 | -------------------------------------------------------------------------------- /pictures/doka.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/doka.jpg -------------------------------------------------------------------------------- /pictures/iam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/iam.jpg -------------------------------------------------------------------------------- /pictures/VM@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/VM@2x.png -------------------------------------------------------------------------------- /pictures/garold.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/garold.jpg -------------------------------------------------------------------------------- /pictures/gitlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/gitlab.png -------------------------------------------------------------------------------- /pictures/intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/intro.png -------------------------------------------------------------------------------- /pictures/trends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/trends.png -------------------------------------------------------------------------------- /pictures/beginner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/beginner.jpg -------------------------------------------------------------------------------- /pictures/compose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/compose.png -------------------------------------------------------------------------------- /pictures/dockerhub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub.png -------------------------------------------------------------------------------- /pictures/fcconf_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/fcconf_bg.png -------------------------------------------------------------------------------- /pictures/iamdone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/iamdone.png -------------------------------------------------------------------------------- /pictures/kitematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/kitematic.png -------------------------------------------------------------------------------- /docs/images/logitech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/docs/images/logitech.png -------------------------------------------------------------------------------- /pictures/docker-boat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/docker-boat.jpg -------------------------------------------------------------------------------- /pictures/frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/frameworks.png -------------------------------------------------------------------------------- /pictures/life-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/life-stack.png -------------------------------------------------------------------------------- /pictures/start-life.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/start-life.png -------------------------------------------------------------------------------- /pictures/wordpress-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/wordpress-1.png -------------------------------------------------------------------------------- /pictures/Container@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/Container@2x.png -------------------------------------------------------------------------------- /pictures/dockerhub-node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-node.png -------------------------------------------------------------------------------- /pictures/fcconf_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/fcconf_title.png -------------------------------------------------------------------------------- /pictures/life-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/life-services.png -------------------------------------------------------------------------------- /pictures/requirements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/requirements.png -------------------------------------------------------------------------------- /pictures/what-are-you.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/what-are-you.jpg -------------------------------------------------------------------------------- /docs/images/ribbon-canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/docs/images/ribbon-canvas.png -------------------------------------------------------------------------------- /pictures/docker-app-drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/docker-app-drag.png -------------------------------------------------------------------------------- /pictures/dockerhub-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-docker.png -------------------------------------------------------------------------------- /pictures/dockerhub-nginx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-nginx.png -------------------------------------------------------------------------------- /pictures/dockerhub-python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-python.png -------------------------------------------------------------------------------- /pictures/dockerhub-sentry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-sentry.png -------------------------------------------------------------------------------- /pictures/dockerhub-ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-ubuntu.png -------------------------------------------------------------------------------- /pictures/sa-character-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/sa-character-img.png -------------------------------------------------------------------------------- /pictures/wordpress-files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/wordpress-files.png -------------------------------------------------------------------------------- /docs/images/material-canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/docs/images/material-canvas.png -------------------------------------------------------------------------------- /docs/images/ribbon-printing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/docs/images/ribbon-printing.png -------------------------------------------------------------------------------- /pictures/backend-frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/backend-frameworks.png -------------------------------------------------------------------------------- /pictures/dockerhub-minecraft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-minecraft.png -------------------------------------------------------------------------------- /pictures/dockerhub-registry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-registry.png -------------------------------------------------------------------------------- /pictures/dockerhub-sonarqube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-sonarqube.png -------------------------------------------------------------------------------- /pictures/dockerhub-wordpress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-wordpress.png -------------------------------------------------------------------------------- /docs/images/material-printing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/docs/images/material-printing.png -------------------------------------------------------------------------------- /pictures/Geek-T-Shirt.jpg_q50.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/Geek-T-Shirt.jpg_q50.webp -------------------------------------------------------------------------------- /pictures/container-on-machine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/container-on-machine.jpg -------------------------------------------------------------------------------- /pictures/dockerhub-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-hello-world.png -------------------------------------------------------------------------------- /pictures/winXPwin7_1527919170.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/winXPwin7_1527919170.jpg -------------------------------------------------------------------------------- /pictures/dockerhub-google-lighthouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/dockerhub-google-lighthouse.png -------------------------------------------------------------------------------- /pictures/horizontal-logo-monochromatic-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avdeev/docker-for-front-end-developers/HEAD/pictures/horizontal-logo-monochromatic-white.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | charset = utf-8 10 | max_line_length = 100 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker для фронтендера 2 | 3 | Слайды для доклада на конференцию FrontendConf 2019 4 | 5 | [Доклад в программе FrontendConf 2019](https://frontendconf.ru/moscow/2019/abstracts/5593) 6 | 7 | [Слайды](https://alexey-avdeev.com/docker-for-front-end-developers/) 8 | 9 | ## Тезисы 10 | 11 | * Docker - это не только для админов. 12 | * Чем Docker похож на уже привычные нам инструменты. 13 | * Почему именно фронтенд-разработчик, а не кто-то другой, должен уметь собирать своё приложение в контейнер. 14 | * Кейсы использования Docker для фронтенд-разработчика. 15 | * Почему добавление новых людей в команду гораздо проще, если вы используете Docker. 16 | 17 | ## Целевая аудитория 18 | 19 | Начинающие разработчики, которые ещё не сталкивались в Docker. 20 | 21 | Продолжающие разработчики, которые хотят послушать о чужом опыте, похоливарить и, возможно, узнать что-то новое. 22 | 23 | ## Благодарности 24 | 25 | Сделано в [Shower](https://github.com/shower/shower) 26 | -------------------------------------------------------------------------------- /docs/shortcuts.md: -------------------------------------------------------------------------------- 1 | # Keyboard Shortcuts 2 | 3 | You can navigate between slides, start and stop presentation using keyboard shortcuts. 4 | 5 | - [Start and Stop](#start-and-stop) 6 | - [Forward](#forward) 7 | - [Backward](#backward) 8 | - [First and Last](#first-and-last) 9 | 10 | ## Start and Stop 11 | 12 | - Start from the current slide: `Cmd Enter`, `Shift F5`, `Cmd Option P` 13 | - Start from the first slide `Cmd Shift Enter` 14 | - Stop: `Esc` key 15 | 16 | ## Forward 17 | 18 | - `Right` and `Down` arrows 19 | - `Page Down` key or `Fn Down` on Mac 20 | - `N` for “next”, `J` or `L` keys 21 | - `Enter` key 22 | - `Space` key during presentation 23 | 24 | ## Backward 25 | 26 | - `Left` and `Up` arrows 27 | - `Page Up` key or `Fn Up` on Mac 28 | - `P` for “previous”, `K` or `H` keys, like in vim 29 | - `Shift Enter` key 30 | - `Shift Space` key during presentation 31 | 32 | ## First and Last 33 | 34 | - First slide: `Home` key or `Fn Left` on Mac 35 | - Last slide: `End` key or `Fn Right` on Mac 36 | -------------------------------------------------------------------------------- /docs/logitech.md: -------------------------------------------------------------------------------- 1 | # Logitech Spotlight 2 | 3 | There’s a brand new [Logitech Spotlight](http://www.logitech.com/en-us/product/spotlight-presentation-remote) presentation remote, which is already fully compatible with Shower: you can switch between slides, hover and click your presentation. But you can make the most of it by enabling two additional shortcuts in Logitech Presentation application, available for macOS and Windows. 4 | 5 | 1. [Download](http://support.logitech.com/en_us/software/logi-presentation) and install an app. 6 | 2. Go to the main menu and locate additional shortcuts options. 7 | 3. Change _Hold Next Button_ to `Cmd Enter` for macOS or `Shift F5` for Windows (just press it). 8 | 4. Change _Hold Back Button_ to `Esc` (just press it). 9 | 10 | Logitech Presenter application 11 | 12 | You might have to enable accessibility access on macOS in order to use this features. App will ask you once it’s needed. 13 | 14 | Now when all is set you can: 15 | 16 | - Start your presentation by holding next button: from the first slide (if none selected) or from the current slide (if there’s one). 17 | - Exit full screen mode by holding back button. It might be useful when you need to find a certain slide and navigate the list. 18 | -------------------------------------------------------------------------------- /asciinema/272875.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 101, "height": 24, "timestamp": 1570460315, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} 2 | [0.010618, "o", "\u001b[?1034hbash-3.2$ "] 3 | [3.157667, "o", "d"] 4 | [3.485076, "o", "o"] 5 | [3.693614, "o", "c"] 6 | [3.781437, "o", "k"] 7 | [3.93334, "o", "e"] 8 | [4.005406, "o", "r"] 9 | [4.213545, "o", "-"] 10 | [4.549526, "o", "c"] 11 | [4.661506, "o", "o"] 12 | [4.869391, "o", "m"] 13 | [5.069491, "o", "p"] 14 | [5.149392, "o", "o"] 15 | [5.261532, "o", "s"] 16 | [5.421529, "o", "e"] 17 | [5.676563, "o", " "] 18 | [6.005386, "o", "u"] 19 | [6.069577, "o", "p"] 20 | [6.28554, "o", " "] 21 | [6.989348, "o", "-"] 22 | [7.133369, "o", "-"] 23 | [7.325312, "o", "d"] 24 | [7.557175, "o", "e"] 25 | [7.861315, "o", "t"] 26 | [7.925364, "o", "a"] 27 | [8.180383, "o", "c"] 28 | [8.269163, "o", "h"] 29 | [8.765524, "o", "\r\n"] 30 | [9.335378, "o", "Starting wordpress_db_1 ... \r\r\n"] 31 | [9.335771, "o", "Starting wordpress_wordpress_1 ... \r\r\n"] 32 | [10.123527, "o", "\u001b[1A\u001b[2K\rStarting wordpress_wordpress_1 ... \u001b[32mdone\u001b[0m\r\u001b[1B"] 33 | [10.156793, "o", "\u001b[2A\u001b[2K\rStarting wordpress_db_1 ... \u001b[32mdone\u001b[0m\r\u001b[2B"] 34 | [10.214313, "o", "bash-3.2$ "] 35 | [16.173093, "o", "exit\r\n"] 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shower", 3 | "description": "Shower HTML presentation engine", 4 | "version": "2.7.0", 5 | "author": { 6 | "name": "Vadim Makeev", 7 | "url": "https://pepelsbey.net/" 8 | }, 9 | "homepage": "https://github.com/shower/shower", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/shower/shower.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/shower/shower/issues" 16 | }, 17 | "license": "MIT", 18 | "keywords": [ 19 | "shower", 20 | "presentation", 21 | "template" 22 | ], 23 | "files": [ 24 | "pictures/**", 25 | "index.html", 26 | "LICENSE.md", 27 | "README.md" 28 | ], 29 | "dependencies": { 30 | "@shower/material": "^2.2.1", 31 | "@shower/ribbon": "^3.2.2", 32 | "shower-core": "^2.1.0" 33 | }, 34 | "devDependencies": { 35 | "path-exists-cli": "^1.0.0", 36 | "@shower/cli": "^0.2.6" 37 | }, 38 | "scripts": { 39 | "pdf": "shower pdf", 40 | "start": "shower serve", 41 | "prepare": "shower prepare --files '**' --files '!{docs,node_modules,prepared}{,/**}' --files '!*.{md,toml,json}'", 42 | "archive": "shower archive --files '**' --files '!{docs,node_modules,prepared}{,/**}' --files '!*.{md,toml,json}'", 43 | "publish": "shower publish --files '**' --files '!{docs,node_modules,prepared}{,/**}' --files '!*.{md,toml,json}'", 44 | "test": "npm run prepare && ls prepared && npm run archive && path-exists archive.zip" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Shower 2 | 3 | You’re always welcome to contribute! Before contributing to Shower, please read through unified [issues list](https://github.com/shower/shower/issues) to see open bugs and feature requests. If you have any feature to add to Shower or found a bug and want to fix it, please make sure you [file an issue](https://github.com/shower/shower/issues/new) first. 4 | 5 | ## Process 6 | 7 | Fork needed repository, create a branch for each feature or issue you’re dealing with and start making changes. Make sure you code doesn’t break tests if there are any. Once you’re finished, send pull request back to original repository: one feature or bug fix — one pull request, please don’t combine non-relevant changes into one pull request. Supply clear description of your changes and a link to existing issue. 8 | 9 | ## Code style 10 | 11 | Please preserve existing code style while contributing to Shower and be ready for code review by Shower maintainers. It’s strongly recommended to install [EditorConfig](http://editorconfig.org) extension to your editor and validate your JavaScript changes using [JSHint](http://jshint.com/). 12 | 13 | ## Language 14 | 15 | English is the main language for Shower project. All discussions and commit messages should be in English, no matter if it’s good or bad. The second language of Shower is Russian. Official Shower themes are always compatible with Cyrillic and Russian typography. All documentation to Shower is always localized to Russian. 16 | 17 | --- 18 | Licensed under [MIT License](LICENSE.md). 19 | -------------------------------------------------------------------------------- /docs/pdf.md: -------------------------------------------------------------------------------- 1 | # Export to PDF 2 | 3 | Though publising your HTML slides as they are is always a better idea, you can export your presentation to PDF to upload it to a service like [SlideShare](https://www.slideshare.net/) or [Notist](https://noti.st/). 4 | 5 | There are two ways of doing this: via browser print dialog or via console. Exporting via browser seems like the most convenient option, but in some cases it might take too much time or even freeze your browser if your slides are too heavy or there are too many of them. 6 | 7 | ## Browser 8 | 9 | To export your slides to PDF using a browser, you’ll need a browser that’s capable of reading page size from `@page` CSS rule. Chromium-based browsers such as Chrome, Opera, Yandex work the best. 10 | 11 | Open you presentation in a browser, make sure it’s in the list mode and send it to print: 12 | 13 | 1. Press `Cmd P` or `Ctrl P`. 14 | 2. Select PDF as a target instead of printer. 15 | 3. Save resulted file. 16 | 17 | ![Printing dialog](images/ribbon-printing.png) 18 | 19 | ## Console 20 | 21 | To export your slides to PDF via console, you’ll need [Node.js](https://nodejs.org/) with npm installed. Once you have it, you can install Shower CLI package that’ll take care of export: 22 | 23 | npm install -g @shower/cli 24 | 25 | Once it’s installed, it becomes globally available as `shower` command. Run it in your presentation’s folder like this to get your PDF: 26 | 27 | shower pdf 28 | 29 | Run `shower --help` for more options. But if it’s a one-time thing and you don’t want to install it globally, you can use built-in command coming with Shower main repository: 30 | 31 | npm install 32 | npm run pdf 33 | 34 | You’ll find your `slides.pdf` next to your presentation. 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright © 2010–2019 Vadim Makeev, http://pepelsbey.net/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | --- 12 | 13 | # Лицензия MIT 14 | 15 | Copyright © 2010–2019 Вадим Макеев, http://pepelsbey.net/ 16 | 17 | Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий: 18 | 19 | Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения. 20 | 21 | ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. 22 | -------------------------------------------------------------------------------- /asciinema/cashbox-api.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 101, "height": 24, "timestamp": 1570466408, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} 2 | [0.011883, "o", "\u001b[?1034hbash-3.2$ "] 3 | [1.518584, "o", "d"] 4 | [2.838599, "o", "o"] 5 | [2.99071, "o", "c"] 6 | [3.070532, "o", "k"] 7 | [3.246602, "o", "e"] 8 | [3.373732, "o", "r"] 9 | [3.782374, "o", "-"] 10 | [4.094289, "o", "c"] 11 | [4.254365, "o", "o"] 12 | [4.486572, "o", "m"] 13 | [4.718314, "o", "p"] 14 | [4.782358, "o", "o"] 15 | [4.886805, "o", "s"] 16 | [5.094406, "o", "e"] 17 | [5.502442, "o", " "] 18 | [5.934431, "o", "u"] 19 | [6.006317, "o", "p"] 20 | [6.142419, "o", " "] 21 | [6.670267, "o", "-"] 22 | [6.814347, "o", "-"] 23 | [7.046133, "o", "b"] 24 | [7.150146, "o", "u"] 25 | [7.341962, "o", "i"] 26 | [7.518353, "o", "l"] 27 | [7.582346, "o", "d"] 28 | [7.805795, "o", " "] 29 | [8.038381, "o", "-"] 30 | [8.182416, "o", "-"] 31 | [8.294406, "o", "d"] 32 | [8.453812, "o", "e"] 33 | [8.960069, "o", "t"] 34 | [9.062397, "o", "a"] 35 | [9.333314, "o", "c"] 36 | [9.486384, "o", "h"] 37 | [9.677299, "o", " "] 38 | [10.81422, "o", "c"] 39 | [10.886205, "o", "a"] 40 | [11.374077, "o", "s"] 41 | [11.462148, "o", "h"] 42 | [12.134253, "o", "b"] 43 | [12.374106, "o", "o"] 44 | [12.518189, "o", "x"] 45 | [12.805795, "o", "-"] 46 | [13.006183, "o", "a"] 47 | [13.174147, "o", "p"] 48 | [13.230103, "o", "i"] 49 | [13.982238, "o", "\r\n"] 50 | [14.606615, "o", "Building cashbox-api\r\n"] 51 | [14.994297, "o", "Step 1/9 : FROM gradle:jdk8 as builder\r\n"] 52 | [14.994603, "o", " ---> 87bca5ae2598\r\nStep 2/9 : COPY --chown=gradle:gradle . /home/gradle/src\r\n"] 53 | [15.009349, "o", " ---> Using cache\r\n ---> 1b2f5c144cbb\r\n"] 54 | [15.009573, "o", "Step 3/9 : WORKDIR /home/gradle/src\r\n"] 55 | [15.011146, "o", " ---> Using cache\r\n"] 56 | [15.011377, "o", " ---> 0df04482b79f\r\nStep 4/9 : RUN gradle build\r\n"] 57 | [15.013279, "o", " ---> Using cache\r\n"] 58 | [15.013472, "o", " ---> 2d2b8c661100\r\nStep 5/9 : RUN ls -la /home/gradle/src/build/libs/\r\n"] 59 | [15.015758, "o", " ---> Using cache\r\n"] 60 | [15.015945, "o", " ---> 5b0d31d030f2\r\nStep 6/9 : FROM tomcat:8.5\r\n"] 61 | [15.016908, "o", " ---> 168588387c68\r\nStep 7/9 : EXPOSE 8080"] 62 | [15.017048, "o", "\r\n"] 63 | [15.019067, "o", " ---> Using cache\r\n ---> a4fce60ed932\r\n"] 64 | [15.019245, "o", "Step 8/9 : MAINTAINER ozaytsev\r\n"] 65 | [15.021262, "o", " ---> Using cache\r\n ---> c48d75ffc264\r\n"] 66 | [15.021403, "o", "Step 9/9 : COPY --from=builder /home/gradle/src/build/libs/src-1.0-SNAPSHOT.war $CATALINA_HOME/webapps/cashbox.war\r\n"] 67 | [15.044073, "o", " ---> Using cache\r\n"] 68 | [15.081193, "o", " ---> c51868384d32\r\n"] 69 | [15.087307, "o", "Successfully built c51868384d32\r\n"] 70 | [15.091845, "o", "Successfully tagged cashbox-compose_cashbox-api:latest\r\n"] 71 | [15.127796, "o", "cashbox-compose_cashbox-pg_1 is up-to-date\r\n"] 72 | [15.128219, "o", "cashbox-compose_cashbox-api_1 is up-to-date\r\n"] 73 | [15.179063, "o", "bash-3.2$ "] 74 | [18.014078, "o", "exit\r\n"] 75 | -------------------------------------------------------------------------------- /docs/features.md: -------------------------------------------------------------------------------- 1 | # Features 2 | 3 | All theme’s features are demonstrated in the [index.html](index.html) file. Use it as a reference while building your presentation. More detailed features overview follows below. 4 | 5 | - [Anatomy](#anatomy) 6 | - [Common](#common) 7 | - [Language](#language) 8 | - [Canvas](#canvas) 9 | - [Title](#title) 10 | - [Badge](#badge) 11 | - [Progress](#progress) 12 | - [Slide](#slide) 13 | - [Number](#number) 14 | - [Types](#types) 15 | - [White](#white) 16 | - [Black](#black) 17 | - [Grid](#grid) 18 | - [Content](#content) 19 | - [Header](#header) 20 | - [Paragraphs](#paragraphs) 21 | - [Inline](#inline) 22 | - [Quotes](#quotes) 23 | - [Lists](#lists) 24 | - [Columns](#columns) 25 | - [Tables](#tables) 26 | - [Code](#code) 27 | - [Elements](#elements) 28 | - [Cover](#cover) 29 | - [Shout](#shout) 30 | - [Place](#place) 31 | - [Notes](#notes) 32 | 33 | ## Anatomy 34 | 35 | Theme package consists of the following folders and files: 36 | 37 | 2. `fonts` folder with fonts in WOFF format. 38 | 3. `images` folder with decoration images. 39 | 4. `pictures` folder with sample pictures. 40 | 5. `styles` folder with built styles in 16×10 and 4×3 ratios. 41 | 6. `index.html` file with demonstration of all features. 42 | 43 | In addition to files theme’s repository contains source files: 44 | 45 | 1. `source` folder with font source files in TTF and design in [Sketch](http://bohemiancoding.com/sketch/). 46 | 2. `styles` folder also contains source styles in SCSS format. 47 | 48 | ## Common 49 | 50 | ### Language 51 | 52 | The main presentation language is set on the root element of the document, please note it and set the right one: 53 | 54 | 55 | 56 | 57 | Appropriate typography traditions are used based on this value. `lang` attribute could also be set on separate slides or elements. 58 | 59 | ### Canvas 60 | 61 | The root presentation element has the main `shower` class and additional mode class: `list` for the list and `full` for the full screen. `list` mode is usually set by default, but if there’s no one, it’ll be set to `list` anyway and slides will be opened in the list mode. If `full` is set instead of `list` then slides will be opened in the full screen mode. 62 | 63 | List: 64 | 65 | 66 | 67 | Full: 68 | 69 | 70 | 71 | Theme’s architecture is based on agreement that all presentation elements are nested in `shower` element and mode classes are hiding or showing needed elements depending on current mode. 72 | 73 | ### Caption 74 | 75 | Presentation title is marked with the `caption` element, which has following elements provided: `

` for the header, `

` for the description and also links. 76 | 77 |

78 |

Presentation Title

79 |

Yours Truly, Famous Inc.

80 |
81 | 82 | Caption is visible only in the list mode. Don’t forget to also specify presentation title in document’s `` element. 83 | 84 | ### Badge 85 | 86 | Badge with “Fork me on GitHub” link (or any other call to action) is marked with `badge` element. 87 | 88 | <footer class="badge"> 89 | <a href="…">Fork me on Github</a> 90 | </footer> 91 | 92 | Badge is visible only in the list mode. 93 | 94 | ### Progress 95 | 96 | Progress bar shows how much is left until presentation end and marked with `progress` element visible only in full screen mode: 97 | 98 | <div class="progress"></div> 99 | 100 | To remove it from presentation just remove this element from document. There’s no way to hide it for specific slides. 101 | 102 | ## Slide 103 | 104 | Slides are marked with `slide` class. Please don’t nest slides and don’t forget closing tags, things could go wrong. 105 | 106 | <section class="slide"> 107 | … 108 | </section> 109 | <section class="slide"> 110 | … 111 | </section> 112 | 113 | There are two slide ratios supported: 16×10 and 4×3. To enable needed one include appropriate file `screen-4x3.css` or `screen-16x10.css`. Wide screen 16×10 format is included by default. 114 | 115 | Slide width is 1024 px for the both ratios, for 16×10 height is 640 px, for 4×3 it’s 768. Bare in mind these sizes while preparing presentation pictures. In list mode slides are scaled down 2 or 4 times and in full screen mode they are scaled dynamically based on window size. 116 | 117 | ### Number 118 | 119 | Slide numbers help audience to remember slides for questions and open needed slide by changing number in address field. Numbers are generated automatically using CSS counters and could be turned off for specific slides. 120 | 121 | You can hide number manually: 122 | 123 | <section class="slide" id="off"> 124 | <style> 125 | #off::after { 126 | visibility: hidden; 127 | } 128 | </style> 129 | </section> 130 | 131 | Slide type `clear` could also hide slide number. 132 | 133 | ### Types 134 | 135 | Types are changing slide’s look. You can set type by adding class to the main `slide`. There are few built-in types available in the theme, you could also describe custom types for each presention or add it to your theme. 136 | 137 | #### White 138 | 139 | White type sets white background. 140 | 141 | <section class="slide white"> 142 | 143 | #### Black 144 | 145 | Black type sets black background. 146 | 147 | <section class="slide black"> 148 | 149 | Please note that black slide type doesn’t change text color. 150 | 151 | #### Clear 152 | 153 | Clear type turns off slide number. Use it when you need a pure slide. May be mixed with `white` or `black` type. 154 | 155 | <section class="slide clear"> 156 | 157 | #### Grid 158 | 159 | Grid set a background with two guide types: main magenta guides and additional cyan guides, setting margins, rows and columns. 160 | 161 | <section class="slide grid"> 162 | … 163 | </section> 164 | 165 | All theme elements are aligned by this grid and it’s recommended to follow it while changing or extending a theme. 166 | 167 | ### Content 168 | 169 | Simple content: headers, paragraphs, lists. 170 | 171 | #### Header 172 | 173 | Slide header is marked with `<h2>` element: 174 | 175 | <section class="slide"> 176 | <h2>Slide Header</h2> 177 | </section> 178 | 179 | We haven’t introduced next heading levels to not provoke slides complexity. 180 | 181 | #### Paragraphs 182 | 183 | Paragraphs are marked with `<p>` element. You could also make a note, less important part of a slide, by adding a `note` class to a paragraph: 184 | 185 | <section class="slide"> 186 | <p>Text</p> 187 | <p class="note">Note</p> 188 | </section> 189 | 190 | #### Inline 191 | 192 | There are following inline elements styled in the theme: 193 | 194 | - `<a>` is underlined; 195 | - `<strong>` and `<b>` are bold; 196 | - `<em>` and `<i>` are italic; 197 | - `<code>`, `<samp>`, and `<kbd>` are monospaced; 198 | - `<sup>` and `<sub>` make superscript and subscript indexes; 199 | - `<mark>` highlights text with background color. 200 | 201 | #### Quotes 202 | 203 | Quotes are marked with `<blockquote>` element which contains one or more paragraphs: 204 | 205 | <blockquote> 206 | <p>Flannel bicycle rights locavore selfies.</p> 207 | </blockquote> 208 | 209 | To add quote’s author wrap a quote to a `<figure>` element and put a caption in the `<figcaption>` right after: 210 | 211 | <figure> 212 | <blockquote> 213 | <p>Post-ironic fashion axe flexitarian</p> 214 | </blockquote> 215 | <figcaption>Yours Truly</figcaption> 216 | </figure> 217 | 218 | #### Lists 219 | 220 | For creating list you must use `ul` (`ol` for numerical list). 221 | 222 | <ol> 223 | <li>Literally viral vegan</li> 224 | <li>Wes Anderson chillwave Marfa 225 | <ul> 226 | <li>Retro meh brunch aesthetic</li> 227 | <li>Messenger bag retro cred</li> 228 | </ul> 229 | </li> 230 | </ol> 231 | 232 | You can also create list with inner navigation by adding `next` class to each elements following after element from each you want start navigation: 233 | 234 | <h2>Inner navigation</h2> 235 | <ol> 236 | <li>I'll be seen right away.</li> 237 | <li>Just navigate to next slide and you'll see others.</li> 238 | <li class="next">Hey! It's all okay ?</li> 239 | <li class="next"> ... </li> 240 | </ol> 241 | 242 | And even so: 243 | 244 | <h2>Benefits</h2> 245 | <ol> 246 | <li class="next">The most important advantage</li> 247 | <li class="next">Less important advantage</li> 248 | </ol> 249 | <h2 class="next">Disadvantages</h2> 250 | <ol class="next"> 251 | <li class="next">There's nothing here</li> 252 | <li class="next"> ... </li> 253 | </ol> 254 | 255 | #### Columns 256 | 257 | If you want to form text in two or three columns use `double` or `triple` class 258 | 259 | <p class="double"> 260 | Echo Park 8-bit sustainable umami deep v Kickstarter. 261 | </p> 262 | 263 | Also work with lists: 264 | 265 | <ul class="triple"> 266 | <li>Occupy locavore blog</li> 267 | <li>Mustache you haven’t heard of</li> 268 | <li>Something else</li> 269 | </ul> 270 | 271 | #### Tables 272 | 273 | Create table by using usual `table`, `tr`, `th` 274 | 275 | <table> 276 | <tr> 277 | <th scope="col">Gentrify</th> 278 | <th>Twee</th> 279 | </tr> 280 | <tr> 281 | <th scope="row">Messenger</th> 282 | <td>Mixtape</td> 283 | </tr> 284 | </table> 285 | 286 | Class `striped` stylizes your table: even rows will turn gray background 287 | 288 | <table class="striped"> 289 | 290 | #### Code 291 | 292 | `Code` tag define your program code 293 | 294 | <pre><code>function action() { 295 | // TODO 296 | return true; 297 | }</code></pre> 298 | 299 | If you want to add lines numbers use next construction: 300 | 301 | <pre> 302 | <code>function action() {</code> 303 | <code> // TODO</code> 304 | <code> return true;</code> 305 | <code>}</code> 306 | </pre> 307 | 308 | When neccessary emphasize that code is commented, you need to use span element with `comment` class; 309 | If you want to color part of code, wrap this part with `mark` to add yellow background and `mark` with `important` class to add red background; 310 | 311 | <pre><code>function <mark>action()</mark> { 312 | <span class="comment">// TODO<span> 313 | return <mark class="important">true</mark>; 314 | }</code></pre> 315 | 316 | ### Elements 317 | 318 | … 319 | 320 | #### Cover 321 | 322 | `Cover` class on img attribute indicates that picture will be background for slide 323 | 324 | <section class="slide"> 325 | <img class="cover" src="picture.png"> 326 | </section> 327 | 328 | To stretch the picture in width or height, you need to set a `width` or `height` class respectively; 329 | 330 | Use both classes `width height`, if you want to stretch the picture in width and height 331 | 332 | <img class="cover width" src="picture.png"> 333 | <img class="cover height" src="picture.png"> 334 | <img class="cover width height" src="picture.png"> 335 | 336 | Shortcut for `width`, `height`: 337 | 338 | <img class="cover w" src="picture.png"> 339 | <img class="cover h" src="picture.png"> 340 | 341 | To insert an image description, links to the author's site or other information use `figure` tag with `figcaption` 342 | 343 | <figure> 344 | <img class="cover" src="picture.png"> 345 | <figcaption class="white"> 346 | © Yours Truly 347 | </figcaption> 348 | </figure> 349 | 350 | #### Shout 351 | 352 | There are slides, which need to be described in only a few words. Usually they display a call for action, define common themes, link to project or something else. To stylize this text, use the `shout` class. 353 | 354 | <section class="slide"> 355 | <h2 class="shout">Shout</h2> 356 | </section> 357 | 358 | Add `grow` class to animate text from small to big size 359 | 360 | <section class="slide"> 361 | <h2 class="shout grow">Growing Shout</h2> 362 | </section> 363 | 364 | Or, on the contrary, for animate text size from big to small add `shrink` class. 365 | 366 | <section class="slide"> 367 | <h2 class="shout shrink">Shrinking Shout</h2> 368 | </section> 369 | 370 | #### Place 371 | 372 | Use `place` class on img attribute give same effect as `cover` class - set background image 373 | 374 | <section class="slide"> 375 | <img class="place" src="picture.png"> 376 | </section> 377 | 378 | If you want collocate picture at a certain side, you need to use `top` / `right` / `bottom` / `left` class as shown below 379 | 380 | <img class="place top" src="picture.png"> 381 | <img class="place right" src="picture.png"> 382 | <img class="place bottom" src="picture.png"> 383 | <img class="place left" src="picture.png"> 384 | 385 | You can also combine classes for location in corners: 386 | 387 | <img class="place top left" src="picture.png"> 388 | <img class="place top right" src="picture.png"> 389 | <img class="place bottom left" src="picture.png"> 390 | <img class="place bottom right" src="picture.png"> 391 | 392 | #### Notes 393 | 394 | When neccessary to add some notes for slide, you may use `footer` class, that hide your notes at all time and show them when you hover to slide: 395 | 396 | <section class="slide"> 397 | <p>Retro meh brunch aesthetic.</p> 398 | <footer class="footer"> 399 | <p>Cosby sweater Shoreditch.</p> 400 | </footer> 401 | </section> 402 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="ru"> 3 | <head> 4 | <!-- Google Tag Manager --> 5 | <script> 6 | (function (w, d, s, l, i) { 7 | w[l] = w[l] || []; 8 | w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" }); 9 | var f = d.getElementsByTagName(s)[0], 10 | j = d.createElement(s), 11 | dl = l != "dataLayer" ? "&l=" + l : ""; 12 | j.async = true; 13 | j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl; 14 | f.parentNode.insertBefore(j, f); 15 | })(window, document, "script", "dataLayer", "GTM-P6SW86D"); 16 | </script> 17 | <!-- End Google Tag Manager --> 18 | <title>Docker для фронтендера 19 | 20 | 21 | 22 | 23 | 48 | 49 | 50 | 51 | 59 | 60 |
61 |

Docker для фронтендера

62 |

63 | Алексей Авдеев, 64 | Neuron.Digital 65 |

66 |
67 | 68 |
69 |

Docker для фронтендера

70 |

71 | Алексей Авдеев, 72 | Neuron.Digital 73 |

74 |
75 | FrontendConf Background 76 |
77 | 92 |
93 | 94 | 95 | 96 |
97 | 103 |
104 | 105 |
106 | 107 |
108 | 109 |
110 | 111 |
112 | 113 |
114 |

Требования: Docker

115 |
116 | 117 |
118 |

Эра Docker

119 |
120 | 121 |
122 |

👨‍💻 О себе

123 | 124 |
    125 |
  1. 126 | 👨 Алексей Авдеев (https://github.com/avdeev) 127 |
  2. 128 | 129 | 130 | 131 | 132 |
133 |
134 | 135 | 136 | 137 | 138 |
139 |

Зачем?

140 |
141 | 142 |
143 |

Поднимаем backend

144 |
145 | 146 |
147 | 148 |
149 | 150 |
151 |

😫 Без Docker

152 | 153 |
154 |             $ brew update
155 |             $ brew install mysql
156 |             ...
157 |             $ \curl -sSL https://get.rvm.io | bash
158 |             ...
159 |             $ rails s
160 |         
161 |
162 | 163 |
164 | 165 |
166 | 167 |
168 | 169 |
170 | 171 |
172 | 173 |
174 | 175 |
176 |

👍 С Docker

177 | 178 |
179 |             $ docker-compose up api
180 |             ...
181 |             Listening localhost:8080
182 |         
183 |
184 | 185 |
186 |

👍 С Docker

187 | 188 | 189 |
190 | 191 |
192 |

Автоматизируй

193 |
194 | 195 | 196 | 197 |
198 |

Устойчивость ⚖

199 |
200 | 201 |
202 | 203 |
204 | 205 |
206 | 207 |
208 | 209 |
210 |

👍 С Docker

211 | 212 |
213 |             $ docker rm --volumes api
214 |         
215 | 216 |
217 |             $ docker system prune --all
218 |         
219 |
220 | 221 | 222 | 223 |
224 |

Контролируем эксплуатацию

225 |
226 | 227 |
228 | 229 |
230 | 231 |
232 |

😫 Без Docker

233 | 234 |
    235 | 236 | 237 | 238 | 239 |
240 |
241 | 242 |
243 |

👍 С Docker

244 | 245 |

Упаковано в Docker 📦

246 |
247 | 248 |
249 | 250 |
251 | 252 |
253 | 254 |
255 | 256 |
257 | 262 | 263 |

264 | KEEP CALM
265 | IT WORKS
266 | ON ALL MACHINES 267 |

268 |
269 | 270 |
271 |

Пишите код для продакшна

272 |
273 | 274 |
275 | 276 |
277 | 278 |
279 | 280 |
281 | 282 |
283 | 284 |
285 | 286 |
287 |

288 | Безопасно собирайте, делитесь и запускайте любое приложение где угодно 289 |

290 |
291 | 292 |
293 | 294 |
295 | 296 |
297 | 298 |
299 | 300 |
301 |

302 | Установка
303 | Docker ⏬ 304 |

305 |
306 | 307 |
308 | 309 |
310 | 311 |
312 | 313 |
314 | 315 |
316 |

♻ Установка Docker через Homebrew

317 | 318 |
319 |             $ brew cask install docker
320 |         
321 |
322 | 323 |
324 |

Что входит в Docker Desktop

325 | 326 |
    327 | 328 | 329 | 330 | 331 | 332 |
333 |
334 | 335 | 336 | 337 |
338 |

339 | Docker — это не только для
340 | админов 341 |

342 |
343 | 344 |
345 |

Что-то для админов

346 | 347 |
    348 | 349 | 350 | 351 | 352 | 353 |
354 |
355 | 356 |
357 |

358 | Docker как NPM,
359 | но для Ops 360 |

361 |
362 | 363 |
364 |

Знакомые понятия

365 | 366 |
    367 | 368 | 369 | 370 | 371 | 372 |
373 |
374 | 375 |
376 |

Знакомые понятия

377 | 378 |
    379 | 380 | 381 | 382 |
383 |
384 | 385 |
386 | 387 |
388 | 389 |
390 | 396 |
397 | 398 |
399 | 405 |
406 | 407 |
408 |

Hello World (1)

409 | 410 |
411 |             $ docker run ubuntu:14.04 /bin/echo 'Hello world'
412 |              
413 |             Hello world
414 |         
415 |
416 | 417 |
418 | 424 |
425 | 426 |
427 |

Hello World (2)

428 | 429 |
430 |             $ docker run hello-world
431 |             
432 |             Unable to find image 'hello-world:latest' locally
433 |             latest: Pulling from library/hello-world
434 |             ...
435 |             Hello from Docker!
436 |             This message shows that your installation appears...
437 |             ...
438 |         
439 |
440 | 441 |
442 | 443 |
444 | 445 |
446 |

447 | Немного
448 | рецептов 449 |

450 |
451 | 452 |
453 | 459 |
460 | 461 |
462 | 468 |
469 | 470 |
471 | 477 |
478 | 479 |
480 | 486 |
487 | 488 |
489 | 495 |
496 | 497 |
498 |

Запускаем Lighthouse

499 |
500 | 501 |
502 |

😫 Без Docker

503 | 504 |
505 |             Установить Google Chrome for Desktop.
506 |             Установить текущую LTS-версию Node.
507 |             $ npm install -g lighthouse
508 |             $ lighthouse http://frontendconf.ru
509 |         
510 |
511 | 512 |
513 | 519 |
520 | 521 |
522 |

👍 С Docker

523 | 524 |
525 |             $ docker run \
526 |               --rm \
527 |               --name lighthouse \
528 |               -it \
529 |               --volume ~:/home/chrome/reports \
530 |               --cap-add=SYS_ADMIN \
531 |               femtopixel/google-lighthouse http://frontendconf.ru
532 |         
533 |
534 | 535 |
536 |

Нагрузка

537 |
538 | 539 |
540 |

👍 С Docker

541 | 542 |
543 |             $ docker service scale frontend=10
544 |              
545 |             frontend scaled to 10
546 |         
547 |
548 | 549 |
550 |

Решение организационных вопросов

551 |
552 | 553 |
554 |

Dockerfile

555 | 556 |
557 |             LABEL maintainer="aad.jerry@gmail.com"
558 |         
559 |
560 | 561 |
562 |

docker inspect

563 | 564 |
565 |             $ docker inspect NAME|ID
566 |         
567 | 568 |
569 |             "Labels": {
570 |               "maintainer": "aad.jerry@gmail.com"
571 |             }
572 |         
573 |
574 | 575 |
576 |

577 | Выбираем
578 | технологию 579 |

580 |
581 | 582 |
583 | 584 |
585 | 586 |
587 | 593 |
594 | 595 |
596 |

Dockerfile (1)

597 | 598 |
599 |             FROM    node:10-alpine as builder
600 |             WORKDIR /app
601 |             COPY    package*.json ./
602 |             RUN     npm ci
603 |             COPY    vue.config.js babel.config.js ./
604 |             COPY    src src
605 |             RUN     npm run build
606 |         
607 |
608 | 609 |
610 | 616 |
617 | 618 |
619 |

Dockerfile (2)

620 | 621 |
622 |             FROM   nginx:1.13-alpine
623 |             COPY   nginx /etc/nginx/conf.d
624 |             COPY   --from=builder /app/dist/ /usr/share/nginx/html/
625 |             EXPOSE 5000
626 |         
627 |
628 | 629 |
630 |

Запускаем контейнер

631 | 632 |
633 |             docker build --tag my-app .
634 |             docker run -p 5000:5000 --tag my-app
635 |         
636 |
637 | 638 |
639 |

Демо

640 |
641 | 642 |
643 | 644 |
645 | 646 |
647 | 653 |
654 | 655 |
656 |

Dockerfile для Node.js

657 | 658 |
659 |             FROM node:10-alpine
660 |             WORKDIR /app
661 |             COPY package*.json ./
662 |             RUN npm ci
663 |             COPY . .
664 |             EXPOSE 5000
665 |             CMD ["node", "server.js"]
666 |         
667 |
668 | 669 |
670 | 676 |
677 | 678 |
679 |

Dockerfile для Python

680 | 681 |
682 |             FROM python:3-alpine
683 |             WORKDIR /usr/src/app
684 |             COPY requirements.txt ./
685 |             RUN pip install --no-cache-dir -r requirements.txt
686 |             COPY . .
687 |             EXPOSE 5000
688 |             CMD ["python", "./your-daemon-or-script.py"]
689 |         
690 |
691 | 692 |
693 |

Демо

694 |
695 | 696 |
697 |

Универсальная абстракция

698 |
699 | 700 |
701 |

Компонуемость

702 |
703 | 704 |
705 |

👍 С Docker (docker-compose.yml)

706 | 707 |
708 |             services:
709 |               api:
710 |                 build: ./api
711 |               front:
712 |                 build: ./front
713 |               reverse-proxy:
714 |                 image: abiosoft/caddy
715 |                 ports:
716 |                   - 80:80
717 |                 volumes:
718 |                   - ./Caddyfile:/etc/Caddyfile
719 |         
720 |
721 | 722 |
723 |

Запускаем связку контейнеров

724 | 725 |
726 |             $ docker-compose up
727 |         
728 |
729 | 730 |
731 |

Демо

732 |
733 | 734 |
735 |

Виртуализируй

736 |
737 | 738 |
739 |

👏 Спасибо!

740 | 741 | 746 | 747 | я 752 |
753 | 754 | 757 | 758 |
759 | 760 | 761 | 762 | 763 | 764 | -------------------------------------------------------------------------------- /asciinema/lighthouse.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 120, "height": 29, "timestamp": 1570627723, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} 2 | [5.720577, "o", "Error: No available formula with the name \"qt@5.5\" \r\n"] 3 | [5.748275, "o", "\u001b[?1034hbash-3.2$ "] 4 | [7.74778, "o", "do"] 5 | [7.748105, "o", "cker run --rm --name lighthouse -it -v ~:"] 6 | [7.748164, "o", "/"] 7 | [7.748284, "o", "h"] 8 | [7.748451, "o", "ome/chrome/r"] 9 | [7.748608, "o", "eports "] 10 | [7.748826, "o", "--"] 11 | [7.748895, "o", "cap"] 12 | [7.748938, "o", "-a"] 13 | [7.751756, "o", "dd=SYS_ADMIN femtopixel/google-lighthou \rse http://frontendconf.ru"] 14 | [8.243061, "o", "\r\n"] 15 | [9.616665, "o", " \u001b[34;1mChromeLauncher \u001b[0mWaiting for browser. \u001b[34m+0ms\u001b[0m"] 16 | [9.617716, "o", "\r\n"] 17 | [9.619389, "o", " \u001b[34;1mChromeLauncher \u001b[0mWaiting for browser... \u001b[34m+2ms\u001b[0m"] 18 | [9.620159, "o", "\r\n"] 19 | [10.134066, "o", " \u001b[34;1mChromeLauncher \u001b[0mWaiting for browser..... \u001b[34m+517ms\u001b[0m\r\n"] 20 | [10.136484, "o", " \u001b[34;1mChromeLauncher \u001b[0mWaiting for browser.....\u001b[32m✓\u001b[0m \u001b[34m+2ms\u001b[0m"] 21 | [10.13672, "o", "\r\n"] 22 | [10.317457, "o", " \u001b[33;1mconfig:warn \u001b[0mIFrameElements gatherer requested, however no audit requires it. \u001b[33m+182ms\u001b[0m\r\n"] 23 | [10.329141, "o", " \u001b[34;1mstatus \u001b[0mConnecting to browser \u001b[34m+11ms\u001b[0m"] 24 | [10.329385, "o", "\r\n"] 25 | [10.356999, "o", " \u001b[34;1mstatus \u001b[0mResetting state with about:blank \u001b[34m+25ms\u001b[0m\r\n"] 26 | [10.419303, "o", " \u001b[34;1mstatus \u001b[0mBenchmarking machine \u001b[34m+64ms\u001b[0m\r\n"] 27 | [10.931353, "o", " \u001b[34;1mstatus \u001b[0mInitializing… \u001b[34m+512ms\u001b[0m\r\n"] 28 | [10.979693, "o", " \u001b[34;1mstatus \u001b[0mResetting state with about:blank \u001b[34m+50ms\u001b[0m\r\n"] 29 | [11.003461, "o", " \u001b[34;1mstatus \u001b[0mSetting up network for the pass trace \u001b[34m+22ms\u001b[0m"] 30 | [11.00393, "o", "\r\n"] 31 | [11.011455, "o", " \u001b[34;1mstatus \u001b[0mCleaning browser cache \u001b[34m+10ms\u001b[0m"] 32 | [11.011772, "o", "\r\n"] 33 | [11.025945, "o", " \u001b[34;1mstatus \u001b[0mBeginning devtoolsLog and trace \u001b[34m+13ms\u001b[0m"] 34 | [11.026445, "o", "\r\n"] 35 | [11.095286, "o", " \u001b[34;1mstatus \u001b[0mLoading page & waiting for onload CSSUsage, ViewportDimensions, RuntimeExceptions, ConsoleMessages, AnchorElements, ImageElements, LinkElements, MetaElements, ScriptElements, IFrameElements, AppCacheManifest, Doctype, DOMStats, OptimizedImages, PasswordInputsWithPreventedPaste, ResponseCompression, TagsBlockingFirstPaint, FontSize, EmbeddedContent, RobotsTxt, TapTargets, Accessibility \u001b[34m+71ms\u001b[0m"] 36 | [11.095603, "o", "\r\n"] 37 | [13.523168, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: CSSUsage \u001b[34m+2s\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: ViewportDimensions \u001b[34m+1ms\u001b[0m"] 38 | [13.523395, "o", "\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: RuntimeExceptions \u001b[34m+0ms\u001b[0m\r\n"] 39 | [13.524712, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: ConsoleMessages \u001b[34m+1ms\u001b[0m\r\n"] 40 | [13.526697, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: AnchorElements \u001b[34m+0ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: ImageElements \u001b[34m+1ms\u001b[0m\r\n"] 41 | [13.526886, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: LinkElements \u001b[34m+0ms\u001b[0m\r\n"] 42 | [13.528407, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: MetaElements \u001b[34m+1ms\u001b[0m\r\n"] 43 | [13.529949, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: ScriptElements \u001b[34m+1ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: IFrameElements \u001b[34m+0ms\u001b[0m\r\n"] 44 | [13.531913, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: AppCacheManifest \u001b[34m+2ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: Doctype \u001b[34m+1ms\u001b[0m\r\n"] 45 | [13.533416, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: DOMStats \u001b[34m+1ms\u001b[0m\r\n"] 46 | [13.536237, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: OptimizedImages \u001b[34m+1ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: PasswordInputsWithPreventedPaste \u001b[34m+1ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: ResponseCompression \u001b[34m+1ms\u001b[0m\r\n"] 47 | [13.537027, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: TagsBlockingFirstPaint \u001b[34m+0ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: FontSize \u001b[34m+0ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: EmbeddedContent \u001b[34m+0ms\u001b[0m\r\n"] 48 | [13.538912, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: RobotsTxt \u001b[34m+1ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: TapTargets \u001b[34m+0ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: Accessibility \u001b[34m+0ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering trace \u001b[34m+0ms\u001b[0m\r\n"] 49 | [13.665681, "o", " \u001b[34;1mstatus \u001b[0mGathering devtoolsLog & network records \u001b[34m+130ms\u001b[0m\r\n"] 50 | [13.691376, "o", " \u001b[34;1mstatus \u001b[0mGathering: CSSUsage \u001b[34m+26ms\u001b[0m"] 51 | [13.691659, "o", "\r\n"] 52 | [13.732742, "o", " \u001b[34;1mstatus \u001b[0mGathering: ViewportDimensions \u001b[34m+41ms\u001b[0m\r\n"] 53 | [13.740664, "o", " \u001b[34;1mstatus \u001b[0mGathering: RuntimeExceptions \u001b[34m+8ms\u001b[0m\r\n"] 54 | [13.743692, "o", " \u001b[34;1mstatus \u001b[0mGathering: ConsoleMessages \u001b[34m+3ms\u001b[0m\r\n"] 55 | [13.747602, "o", " \u001b[34;1mstatus \u001b[0mGathering: AnchorElements \u001b[34m+4ms\u001b[0m\r\n"] 56 | [13.760147, "o", " \u001b[34;1mstatus \u001b[0mGathering: ImageElements \u001b[34m+13ms\u001b[0m\r\n"] 57 | [13.863066, "o", " \u001b[34;1mstatus \u001b[0mGathering: LinkElements \u001b[34m+103ms\u001b[0m\r\n"] 58 | [13.869079, "o", " \u001b[34;1mstatus \u001b[0mGathering: MetaElements \u001b[34m+6ms\u001b[0m\r\n"] 59 | [13.874216, "o", " \u001b[34;1mstatus \u001b[0mGathering: ScriptElements \u001b[34m+5ms\u001b[0m\r\n"] 60 | [13.939692, "o", " \u001b[34;1mstatus \u001b[0mGathering: IFrameElements \u001b[34m+65ms\u001b[0m\r\n"] 61 | [13.953512, "o", " \u001b[34;1mstatus \u001b[0mGathering: AppCacheManifest \u001b[34m+10ms\u001b[0m\r\n"] 62 | [13.961046, "o", " \u001b[34;1mstatus \u001b[0mGathering: Doctype \u001b[34m+11ms\u001b[0m\r\n"] 63 | [13.966066, "o", " \u001b[34;1mstatus \u001b[0mGathering: DOMStats \u001b[34m+6ms\u001b[0m\r\n"] 64 | [13.980272, "o", " \u001b[34;1mstatus \u001b[0mGathering: OptimizedImages \u001b[34m+14ms\u001b[0m\r\n"] 65 | [14.609625, "o", " \u001b[34;1mstatus \u001b[0mGathering: PasswordInputsWithPreventedPaste \u001b[34m+630ms\u001b[0m\r\n"] 66 | [14.621947, "o", " \u001b[34;1mstatus \u001b[0mGathering: ResponseCompression \u001b[34m+12ms\u001b[0m\r\n"] 67 | [14.62959, "o", " \u001b[34;1mstatus \u001b[0mGathering: TagsBlockingFirstPaint \u001b[34m+8ms\u001b[0m\r\n"] 68 | [14.637234, "o", " \u001b[34;1mstatus \u001b[0mGathering: FontSize \u001b[34m+8ms\u001b[0m\r\n"] 69 | [14.729945, "o", " \u001b[34;1mstatus \u001b[0mGathering: EmbeddedContent \u001b[34m+92ms\u001b[0m\r\n"] 70 | [14.73733, "o", " \u001b[34;1mstatus \u001b[0mGathering: RobotsTxt \u001b[34m+7ms\u001b[0m\r\n"] 71 | [14.758843, "o", " \u001b[34;1mstatus \u001b[0mGathering: TapTargets \u001b[34m+22ms\u001b[0m\r\n"] 72 | [14.795569, "o", " \u001b[34;1mstatus \u001b[0mGathering: Accessibility \u001b[34m+37ms\u001b[0m\r\n"] 73 | [15.280865, "o", " \u001b[34;1mstatus \u001b[0mResetting state with about:blank \u001b[34m+485ms\u001b[0m\r\n"] 74 | [15.317146, "o", " \u001b[34;1mstatus \u001b[0mSetting up network for the pass trace \u001b[34m+36ms\u001b[0m\r\n"] 75 | [15.328048, "o", " \u001b[34;1mstatus \u001b[0mBeginning devtoolsLog and trace \u001b[34m+12ms\u001b[0m\r\n"] 76 | [15.328862, "o", " \u001b[34;1mstatus \u001b[0mLoading page & waiting for onload ServiceWorker, Offline, StartUrl \u001b[34m+0ms\u001b[0m\r\n"] 77 | [15.416614, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: ServiceWorker \u001b[34m+88ms\u001b[0m\r\n"] 78 | [15.4169, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: Offline \u001b[34m+0ms\u001b[0m\r\n"] 79 | [15.417502, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: StartUrl \u001b[34m+1ms\u001b[0m\r\n"] 80 | [15.418144, "o", " \u001b[34;1mstatus \u001b[0mGathering devtoolsLog & network records \u001b[34m+1ms\u001b[0m\r\n"] 81 | [15.428037, "o", " \u001b[34;1mstatus \u001b[0mGathering: ServiceWorker \u001b[34m+10ms\u001b[0m\r\n"] 82 | [15.43158, "o", " \u001b[34;1mstatus \u001b[0mGathering: Offline \u001b[34m+3ms\u001b[0m\r\n"] 83 | [15.435919, "o", " \u001b[34;1mstatus \u001b[0mGathering: StartUrl \u001b[34m+5ms\u001b[0m\r\n"] 84 | [15.441295, "o", " \u001b[34;1mstatus \u001b[0mResetting state with about:blank \u001b[34m+5ms\u001b[0m\r\n"] 85 | [15.51135, "o", " \u001b[34;1mstatus \u001b[0mSetting up network for the pass trace \u001b[34m+70ms\u001b[0m\r\n"] 86 | [15.520577, "o", " \u001b[34;1mstatus \u001b[0mBeginning devtoolsLog and trace \u001b[34m+9ms\u001b[0m\r\n"] 87 | [15.521409, "o", " \u001b[34;1mstatus \u001b[0mLoading page & waiting for onload HTTPRedirect, HTMLWithoutJavaScript \u001b[34m+1ms\u001b[0m\r\n"] 88 | [15.724532, "o", " \u001b[34;1mstatus \u001b[0mGathering in-page: HTTPRedirect \u001b[34m+203ms\u001b[0m\r\n \u001b[34;1mstatus \u001b[0mGathering in-page: HTMLWithoutJavaScript \u001b[34m+1ms\u001b[0m\r\n"] 89 | [15.725494, "o", " \u001b[34;1mstatus \u001b[0mGathering devtoolsLog & network records \u001b[34m+0ms\u001b[0m\r\n"] 90 | [15.763098, "o", " \u001b[34;1mstatus \u001b[0mGathering: HTTPRedirect \u001b[34m+38ms\u001b[0m\r\n"] 91 | [15.792185, "o", " \u001b[34;1mstatus \u001b[0mGathering: HTMLWithoutJavaScript \u001b[34m+29ms\u001b[0m\r\n"] 92 | [15.804494, "o", " \u001b[34;1mstatus \u001b[0mDisconnecting from browser... \u001b[34m+12ms\u001b[0m\r\n"] 93 | [15.839211, "o", " \u001b[34;1mstatus \u001b[0mAnalyzing and running audits... \u001b[34m+32ms\u001b[0m\r\n"] 94 | [15.852269, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Uses HTTPS \u001b[34m+16ms\u001b[0m\r\n"] 95 | [15.860962, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Redirects HTTP traffic to HTTPS \u001b[34m+9ms\u001b[0m\r\n"] 96 | [15.862981, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Registers a service worker that controls page and `start_url` \u001b[34m+2ms\u001b[0m\r\n"] 97 | [15.865035, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Current page responds with a 200 when offline \u001b[34m+2ms\u001b[0m\r\n"] 98 | [15.867631, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Has a `` tag with `width` or `initial-scale` \u001b[34m+2ms\u001b[0m\r\n"] 99 | [15.872859, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Contains some content when JavaScript is not available \u001b[34m+6ms\u001b[0m\r\n"] 100 | [15.87493, "o", " \u001b[34;1mstatus \u001b[0mAuditing: First Contentful Paint \u001b[34m+2ms\u001b[0m\r\n"] 101 | [15.934522, "o", " \u001b[34;1mstatus \u001b[0mAuditing: First Meaningful Paint \u001b[34m+60ms\u001b[0m\r\n"] 102 | [15.949722, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Page load is fast enough on mobile networks \u001b[34m+15ms\u001b[0m\r\n"] 103 | [15.978856, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Speed Index \u001b[34m+29ms\u001b[0m\r\n"] 104 | [16.500007, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Screenshot Thumbnails \u001b[34m+522ms\u001b[0m\r\n"] 105 | [16.785558, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Final Screenshot \u001b[34m+285ms\u001b[0m\r\n"] 106 | [16.791968, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Estimated Input Latency \u001b[34m+6ms\u001b[0m\r\n"] 107 | [16.816738, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Total Blocking Time \u001b[34m+25ms\u001b[0m\r\n"] 108 | [16.832901, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Max Potential First Input Delay \u001b[34m+17ms\u001b[0m\r\n"] 109 | [16.872747, "o", " \u001b[34;1mstatus \u001b[0mAuditing: No browser errors logged to the console \u001b[34m+40ms\u001b[0m\r\n"] 110 | [16.875246, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Server response times are low (TTFB) \u001b[34m+2ms\u001b[0m\r\n"] 111 | [16.879691, "o", " \u001b[34;1mstatus \u001b[0mAuditing: First CPU Idle \u001b[34m+4ms\u001b[0m\r\n"] 112 | [16.888653, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Time to Interactive \u001b[34m+10ms\u001b[0m\r\n"] 113 | [16.890329, "o", " \u001b[34;1mstatus \u001b[0mAuditing: User Timing marks and measures \u001b[34m+1ms\u001b[0m\r\n"] 114 | [16.89316, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Minimize Critical Requests Depth \u001b[34m+3ms\u001b[0m\r\n"] 115 | [16.896031, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Avoid multiple page redirects \u001b[34m+3ms\u001b[0m\r\n"] 116 | [16.898164, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Web app manifest meets the installability requirements \u001b[34m+2ms\u001b[0m\r\n"] 117 | [16.900163, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Provides a valid `apple-touch-icon` \u001b[34m+2ms\u001b[0m\r\n"] 118 | [16.902777, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Configured for a custom splash screen \u001b[34m+2ms\u001b[0m\r\n"] 119 | [16.904775, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Sets a theme color for the address bar. \u001b[34m+2ms\u001b[0m\r\n"] 120 | [16.906767, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Content is sized correctly for the viewport \u001b[34m+2ms\u001b[0m\r\n"] 121 | [16.908575, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Displays images with correct aspect ratio \u001b[34m+2ms\u001b[0m\r\n"] 122 | [16.910613, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Avoids deprecated APIs \u001b[34m+3ms\u001b[0m\r\n"] 123 | [16.912745, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Minimizes main-thread work \u001b[34m+2ms\u001b[0m\r\n"] 124 | [16.940831, "o", " \u001b[34;1mstatus \u001b[0mAuditing: JavaScript execution time \u001b[34m+28ms\u001b[0m\r\n"] 125 | [16.946752, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Preload key requests \u001b[34m+5ms\u001b[0m\r\n"] 126 | [16.949829, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Preconnect to required origins \u001b[34m+4ms\u001b[0m\r\n"] 127 | [16.952905, "o", " \u001b[34;1mstatus \u001b[0mAuditing: All text remains visible during webfont loads \u001b[34m+3ms\u001b[0m\r\n"] 128 | [16.956259, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Diagnostics \u001b[34m+3ms\u001b[0m\r\n"] 129 | [16.958541, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Network Requests \u001b[34m+2ms\u001b[0m\r\n"] 130 | [16.96105, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Network Round Trip Times \u001b[34m+3ms\u001b[0m\r\n"] 131 | [16.963028, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Server Backend Latencies \u001b[34m+2ms\u001b[0m\r\n"] 132 | [16.964789, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Tasks \u001b[34m+2ms\u001b[0m\r\n"] 133 | [16.966075, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Metrics \u001b[34m+1ms\u001b[0m\r\n"] 134 | [16.968927, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `start_url` responds with a 200 when offline \u001b[34m+3ms\u001b[0m\r\n"] 135 | [16.970864, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Performance budget \u001b[34m+2ms\u001b[0m\r\n"] 136 | [16.974942, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Keep request counts low and transfer sizes small \u001b[34m+4ms\u001b[0m\r\n"] 137 | [16.977619, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Third-Party usage \u001b[34m+2ms\u001b[0m\r\n"] 138 | [16.993599, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Site works cross-browser \u001b[34m+17ms\u001b[0m\r\n"] 139 | [16.995797, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Page transitions don't feel like they block on the network \u001b[34m+2ms\u001b[0m\r\n"] 140 | [16.997566, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Each page has a URL \u001b[34m+1ms\u001b[0m\r\n"] 141 | [16.999481, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[accesskey]` values are unique \u001b[34m+2ms\u001b[0m\r\n"] 142 | [17.003899, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[aria-*]` attributes match their roles \u001b[34m+5ms\u001b[0m\r\n"] 143 | [17.006333, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[role]`s have all required `[aria-*]` attributes \u001b[34m+2ms\u001b[0m\r\n"] 144 | [17.008291, "o", " \u001b[34;1mstatus \u001b[0mAuditing: Elements with an ARIA `[role]` that require children to contain a specific `[role]` have all required children. \u001b[34m+2ms\u001b[0m\r\n"] 145 | [17.009684, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[role]`s are contained by their required parent element \u001b[34m+2ms\u001b[0m\r\n"] 146 | [17.011113, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[role]` values are valid \u001b[34m+1ms\u001b[0m\r\n"] 147 | [17.012576, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[aria-*]` attributes have valid values \u001b[34m+2ms\u001b[0m\r\n"] 148 | [17.014687, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `[aria-*]` attributes are valid and not misspelled \u001b[34m+2ms\u001b[0m\r\n"] 149 | [17.01738, "o", " \u001b[34;1mstatus \u001b[0mAuditing: `