Module: Kowl::Docker
- Included in:
- Generators::Base, Overrides::AppGenerator
- Defined in:
- lib/kowl/docker.rb
Instance Method Summary collapse
-
#alpine_docker_dependencies(options = {}) ⇒ String
Used to generate a dependencies list in the dockerfile based on the applications requirements.
-
#app_js_volumes ⇒ String
List of JS volumes to use for the apps docker-compose filees.
-
#app_volumes(skip_javascript = false, indention = 2) ⇒ String
Generate a list of volumes to attach to the applications docker-compose service.
-
#db_volumes(database) ⇒ String
Return volumes for docker-compose database services.
-
#debian_database_dependencies(database) ⇒ String
Return a list of apt packages to install for Debian docker image.
-
#debian_docker_dependencies(options = {}) ⇒ String
Return a list of dependencies to inject into the applications Dockerfile (if they are using Debian).
-
#docker_app_command(database, skip_sidekiq = false) ⇒ String
Generate the command for the application service in the applications docker-compose file.
-
#docker_compose_database_string(database) ⇒ String
Returns a command for the docker-compose app service.
-
#docker_databases(database) ⇒ String
If a database is to be used (other than sqlite3) thiss creates the docker-compose service.
-
#docker_depends_on(options = {}) ⇒ String
For generating the docker services depends_on tag for all services it requires in order to run.
-
#docker_port_watcher(database, skip_sidekiq = false) ⇒ String
Create a CMD entry for services to watch before firing up the specific application.
-
#docker_redis_service ⇒ String
Used to generate and return a string for adding a Redis docker service to the docker-compose file.
-
#docker_sidekiq_service(database = 'sqlite3') ⇒ String
Generate and return the sidekiq service for the applicatio.
-
#docker_variables(options) ⇒ String
Create a list of variables and values for the docker-compose file depending on requirements.
-
#docker_volumes(options) ⇒ String
Docker-compose volumes.
-
#docker_webpacker_service(options) ⇒ String
Generate a string containing the applications webpacker service (for recompiling new assets).
-
#dockerfile_database_args ⇒ String
This is required, during built; because ENV variables are passed from the docker-compose file using env_file These variables aren’t picked up by the container unless they are specified as ARGS and ENV values in the dockerfile they are assigned as args in case the user wwants to dynamically change the database credentials the container connects to.
-
#dockerfile_migration_snip(database = '') ⇒ String
Add the applications database commands to the Dockerfile.
-
#js_volumes(skip_javascript = false) ⇒ String
Return a list of JS volumes for the application.
-
#mysql_volumes ⇒ String
Return a list of volumes for the mysql database service in the docker-compose.yml file.
-
#postgresql_volumes ⇒ String
Return a list of volume names for the postgresql database service in the docker-compose.yml file.
-
#redis_volumes(skip_sidekiq = false) ⇒ String
Return a volume name for the redis service in the docker-compose.yml file.
Instance Method Details
#alpine_docker_dependencies(options = {}) ⇒ String
Used to generate a dependencies list in the dockerfile based on the applications requirements
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
# File 'lib/kowl/docker.rb', line 390 def alpine_docker_dependencies( = {}) # core dependencies dependencies = %w[brotli dumb-init git python3 sqlite sqlite-dev tzdata vips vips-dev yarn] # optional dependencies dependencies << 'graphviz' unless [:skip_erd] dependencies << 'libsodium-dev' if [:encrypt] # database dependencies case [:database] when 'mysql' dependencies << 'mysql-dev' when 'postgresql' dependencies << 'postgresql-dev' when 'sqlserver' dependencies << 'freetds-dev' end return '' if dependencies.empty? dep_str = "apk add #{dependencies.sort.join(' ')} >/dev/null 2>&1 && \\\n" optimize_indentation(dep_str, 4) end |
#app_js_volumes ⇒ String
List of JS volumes to use for the apps docker-compose filees
312 313 314 315 316 317 |
# File 'lib/kowl/docker.rb', line 312 def app_js_volumes <<~JS_VOLUMES - node_modules:/app/node_modules - packs:/app/public/packs JS_VOLUMES end |
#app_volumes(skip_javascript = false, indention = 2) ⇒ String
Generate a list of volumes to attach to the applications docker-compose service
323 324 325 326 327 328 329 330 331 332 |
# File 'lib/kowl/docker.rb', line 323 def app_volumes(skip_javascript = false, indention = 2) js_volumes_str = app_js_volumes unless skip_javascript volumes_str = <<~VOLUMES - .:/app:cached - bundle:/app/vendor/cache #{js_volumes_str} - rails_cache:/app/tmp/cache VOLUMES optimize_indentation(volumes_str.squeeze("\n").strip, indention) end |
#db_volumes(database) ⇒ String
Return volumes for docker-compose database services
337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/kowl/docker.rb', line 337 def db_volumes(database) return '' unless %w[mysql postgresql].include?(database) case database when 'mysql' mysql_volumes when 'postgresql' postgresql_volumes else '' end end |
#debian_database_dependencies(database) ⇒ String
Return a list of apt packages to install for Debian docker image
432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/kowl/docker.rb', line 432 def debian_database_dependencies(database) return '' if database.blank? case database when 'mysql' 'mysql-client' when 'oracle' 'alien libaio1' when 'postgresql' 'postgresql-client libpq-dev' when 'sqlserver' 'libpq-dev libc6-dev' end end |
#debian_docker_dependencies(options = {}) ⇒ String
Return a list of dependencies to inject into the applications Dockerfile (if they are using Debian)
415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/kowl/docker.rb', line 415 def debian_docker_dependencies( = {}) dependencies = %w[brotli curl git libjemalloc-dev libsqlite3-dev libvips python sqlite3 wget] # optional dependencies dependencies << 'graphviz' unless [:skip_erd] dependencies << 'libsodium23' if [:encrypt] # database dependencies dependencies << debian_database_dependencies([:database]) if %w[mysql oracle postgresql sqlserver].include?([:database]) return '' if dependencies.empty? dep_str = "apt-get install -qq --no-install-recommends #{dependencies.sort.join(' ')} 2>/dev/null && \\\n" optimize_indentation(dep_str, 4) end |
#docker_app_command(database, skip_sidekiq = false) ⇒ String
Generate the command for the application service in the applications docker-compose file
236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/kowl/docker.rb', line 236 def docker_app_command(database, skip_sidekiq = false) db_str = docker_compose_database_string(database) joined_cmd_str = "#{docker_port_watcher(database, skip_sidekiq)}#{db_str}".strip # This is used in case the app is generated with --database=sqlite && --skip_sidekiq # => Thus meaning it doesn't to wait on a database and redis to connect to container before running it joined_cmd_str = joined_cmd_str.blank? ? '' : joined_cmd_str cmd_str = <<~CMD_STR #{joined_cmd_str} rm -rf /app/tmp/pids/server.pid /app/.local >/dev/null 2>&1 && bundle exec rails s -p 3000 -b 0.0.0.0 CMD_STR optimize_indentation(cmd_str, 13).strip end |
#docker_compose_database_string(database) ⇒ String
Returns a command for the docker-compose app service
219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/kowl/docker.rb', line 219 def docker_compose_database_string(database) case database.to_s when 'mysql', 'oracle', 'sqlite3' "bundle exec rails db:migrate db:seed >/dev/null 2>&1 &&\n" when 'sqlserver' "bundle exec rails db:setup >/dev/null 2>&1 &&\n" when 'postgresql' "bundle exec rails db:setup db:test:prepare db:seed >/dev/null 2>&1 &&\n" else '' end end |
#docker_databases(database) ⇒ String
If a database is to be used (other than sqlite3) thiss creates the docker-compose service
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/kowl/docker.rb', line 134 def docker_databases(database) return nil if database.blank? || database == 'sqlite3' case database.to_s when 'mysql' db_service = <<-DB_SERVICE # https://hub.docker.com/_/mysql image: mysql:latest container_name: mysql environment: - MYSQL_DATABASE=#{app_name}_development - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASSWORD} - MYSQL_RANDOM_ROOT_PASSWORD=true volumes: - mysqldata:/var/lib/mysql healthcheck: test: "/usr/bin/mysql --user=${DB_USER} --password=${DB_PASSWORD} --execute \\"SHOW DATABASES;\\"" interval: 3s timeout: 45s retries: 10 ports: - 3306:3306 DB_SERVICE when 'oracle' db_service = <<-DB_SERVICE image: wnameless/oracle-xe-11g-r2 environment: # Disable the disk asynch IO (improves performance) - ORACLE_DISABLE_ASYNCH_IO=true - ORACLE_ALLOW_REMOTE=true ports: - 1521:1521 DB_SERVICE when 'postgresql' db_service = <<-DB_SERVICE # https://hub.docker.com/_/postgres image: postgres:12-alpine environment: - PSQL_HISTFILE=/root/log/.psql_history - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_NON_DURABLE_SETTINGS=1 # https://gilgamezh.me/en/posts/postgres-non-durable-options-docker-container/ volumes: # - ./tmp/db:/var/lib/postgresql/data - postgresdata:/var/lib/postgresql/data - postgresconfig:/etc/postgresql - postgreslog:/var/log/postgresql healthcheck: test: ["CMD", "pg_isready", "-U", "${DB_USER}"] timeout: 45s interval: 5s retries: 10 ports: - 5432:5432 DB_SERVICE when 'sqlserver' db_service = <<-DB_SERVICE # https://hub.docker.com/_/microsoft-mssql-server image: mcr.microsoft.com/mssql/server:2017-latest environment: - ACCEPT_EULA=Y - SA_PASSWORD=${DB_PASSWORD} ports: - 1433:1433 DB_SERVICE end db_str = <<-DOCKER_COMPOSE_DATABASE db: #{db_service.strip} env_file: .env stdin_open: true tty: true restart: always networks: - internal_network DOCKER_COMPOSE_DATABASE db_str end |
#docker_depends_on(options = {}) ⇒ String
For generating the docker services depends_on tag for all services it requires in order to run
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/kowl/docker.rb', line 49 def docker_depends_on( = {}) database = .fetch(:database) { 'sqlite3' } skip_sidekiq = .fetch(:skip_sidekiq) { false } indention = .fetch(:indention) { 4 } requires_base = .fetch(:requires_base) { false } spaces = .fetch(:spaces) { 4 } return nil if requires_base == false && database == 'sqlite3' && skip_sidekiq base_str = (requires_base ? optimize_indentation("- base\n", indention) : '') db_str = optimize_indentation("- db\n", indention) unless database == 'sqlite3' redis_str = optimize_indentation("- redis\n", indention) unless skip_sidekiq spaces_str = (' ' * spaces) depends_on = <<~DEPENDS_ON #{spaces_str}depends_on: #{base_str}#{db_str}#{redis_str} DEPENDS_ON # Used to strip off additional trailing \n in cause both components aren't used depends_on.chomp end |
#docker_port_watcher(database, skip_sidekiq = false) ⇒ String
Create a CMD entry for services to watch before firing up the specific application
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/kowl/docker.rb', line 255 def docker_port_watcher(database, skip_sidekiq = false) return '' if database == 'sqlite3' && skip_sidekiq db_port = if database == 'mysql' '3306' elsif database == 'oracle' '1521' elsif database == 'postgresql' '5432' elsif database == 'sqlserver' '1433' else '' end return '' if db_port.blank? && skip_sidekiq service_list = [] service_list << "-wait tcp://db:#{db_port}" unless db_port.blank? || database == 'sqlite3' service_list << '-wait tcp://redis:6379' unless skip_sidekiq service_watcher_str = service_list.empty? ? '' : "dockerize #{service_list.join(' ')}" "#{service_watcher_str.strip} -timeout 60m &&\n" end |
#docker_redis_service ⇒ String
Used to generate and return a string for adding a Redis docker service to the docker-compose file
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/kowl/docker.rb', line 71 def docker_redis_service <<-REDIS_SERVICE redis: image: redis:alpine ports: - 6379:6379 networks: - internal_network volumes: - redis:/data healthcheck: test: redis-cli ping interval: 1s timeout: 3s retries: 30 sysctls: # https://github.com/docker-library/redis/issues/35 net.core.somaxconn: '511' REDIS_SERVICE end |
#docker_sidekiq_service(database = 'sqlite3') ⇒ String
Generate and return the sidekiq service for the applicatio
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/kowl/docker.rb', line 95 def docker_sidekiq_service(database = 'sqlite3') cmd_str = "#{docker_port_watcher(database, false)}rm -rf /app/.local >/dev/null 2>&1 &&\nbundle exec sidekiq" cmd_str = optimize_indentation(cmd_str, 13).strip <<-SIDEKIQ_SERVICE sidekiq: <<: *x-app_base image: #{app_name}_base:latest command: > sh -c "#{cmd_str}" depends_on: - base SIDEKIQ_SERVICE end |
#docker_variables(options) ⇒ String
Create a list of variables and values for the docker-compose file depending on requirements
281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/kowl/docker.rb', line 281 def docker_variables() vars_str = "BINDING: 0.0.0.0\n" vars_str += "COMPOSE_HTTP_TIMEOUT: 300\n" vars_str += "DB_HOST: db\n" unless [:database] == 'sqlite3' vars_str += "RAILS_ENV: ${RAILS_ENV:-development}\n" vars_str += "REDIS_URL: redis://redis:6379/0\n" unless [:skip_sidekiq] vars_str += "WEBPACKER_DEV_SERVER_HOST: webpacker\n" unless [:skip_javascript] vars_str += "WEB_CONCURRENCY: 1\n" optimize_indentation(vars_str.strip, 4) end |
#docker_volumes(options) ⇒ String
Docker-compose volumes
Used when generating docker-compose to determine what volumes will be created for the application
299 300 301 302 303 304 305 306 307 308 |
# File 'lib/kowl/docker.rb', line 299 def docker_volumes() volume_str = <<~VOLUME_STR bundle: rails_cache: #{db_volumes([:database]).strip} #{js_volumes([:skip_javascript]).strip} #{redis_volumes([:skip_sidekiq]).strip} VOLUME_STR optimize_indentation(volume_str.squeeze("\n").strip, 2) end |
#docker_webpacker_service(options) ⇒ String
Generate a string containing the applications webpacker service (for recompiling new assets)
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/kowl/docker.rb', line 113 def docker_webpacker_service() return '' if [:skip_javascript] webpacker_str = <<-WEBPACKER webpacker: <<: *x-app_base image: #{app_name}_base:latest command: ./bin/webpack-dev-server ports: - '3035:3035' environment: WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 depends_on: - base WEBPACKER webpacker_str.chomp end |
#dockerfile_database_args ⇒ String
This is required, during built; because ENV variables are passed from the docker-compose file using env_file These variables aren’t picked up by the container unless they are specified as ARGS and ENV values in the dockerfile they are assigned as args in case the user wwants to dynamically change the database credentials the container connects to.
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/kowl/docker.rb', line 34 def dockerfile_database_args <<~DB_VARIABLES # Database Arguements passed when docker image is building ARG DB_HOST ARG DB_PASSWORD ARG DB_USER ENV DB_HOST=$DB_HOST \\ DB_PASSWORD=$DB_PASSWORD \\ DB_USER=$DB_USER DB_VARIABLES end |
#dockerfile_migration_snip(database = '') ⇒ String
Add the applications database commands to the Dockerfile
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/kowl/docker.rb', line 13 def dockerfile_migration_snip(database = '') return '' if database.blank? if database == 'sqlite3' ' && rails db:migrate db:seed' else <<~DB_MIGRATION_STR # Uncomment if you want to have your database setup when the container is running # => Note your database should generally be setup own it's own, but this can be used if running such as docker-compose # => where the database is another Docker container # RUN rails db:create db:migrate # RUN ["bin/rails", "db:seed"] DB_MIGRATION_STR end end |
#js_volumes(skip_javascript = false) ⇒ String
Return a list of JS volumes for the application
353 354 355 356 357 358 359 360 |
# File 'lib/kowl/docker.rb', line 353 def js_volumes(skip_javascript = false) return '' if skip_javascript <<~JS_VOLUMES node_modules: packs: JS_VOLUMES end |
#mysql_volumes ⇒ String
Return a list of volumes for the mysql database service in the docker-compose.yml file
364 365 366 367 368 |
# File 'lib/kowl/docker.rb', line 364 def mysql_volumes <<~DB_STR mysqldata: DB_STR end |
#postgresql_volumes ⇒ String
Return a list of volume names for the postgresql database service in the docker-compose.yml file
372 373 374 375 376 377 378 |
# File 'lib/kowl/docker.rb', line 372 def postgresql_volumes <<~DB_STR postgresconfig: postgresdata: postgreslog: DB_STR end |
#redis_volumes(skip_sidekiq = false) ⇒ String
Return a volume name for the redis service in the docker-compose.yml file
383 384 385 |
# File 'lib/kowl/docker.rb', line 383 def redis_volumes(skip_sidekiq = false) skip_sidekiq ? '' : 'redis:' end |