Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include startup actions like "migrate" #36

Closed
andygrunwald opened this issue Jan 26, 2016 · 17 comments
Closed

Include startup actions like "migrate" #36

andygrunwald opened this issue Jan 26, 2016 · 17 comments

Comments

@andygrunwald
Copy link
Contributor

If you use the Cachet Docker image you fire the image up (via run).
If you own an empty database (e.g. MySQL) you need to fire three more commands manually:

$ docker exec -i cachet php artisan migrate --force
$ docker exec -it cachet php artisan key:generate
$ docker exec -it cachet php artisan config:cache

This is describes in the Get started with Docker.

This is fine when you run Cachet on your local machine or a dedicated docker host.
But if you want to run Cachet on a resource scheduler like Mesos (e.g. Marathon) you are not able to execute those commands by hand.
As a further advantage: With such a change it is much more easier to run Cachet on AWS Elastic Beanstalk (see #13) or AWS Elastic Container Engine.

The challenge is here (and this is an important information to keep in mind):
On such scheduler a node can go down. When this happen your container (Cachet) will be rescheduled and booted up again at another node. In such a case the commands will be executed again (with the same database config). So these commands need to be idempotent and it have to be non dangerous to run them in a production env at every time (when we run the same cachet version).

My proposal here is to include those three commands into the entrypoint.sh after the composer install.

Lets get into detail for the single commands (i am not so fimilar with Laravel, so please correct me if i am wrong):

$ docker exec -i cachet php artisan migrate --force

This is the command to boot up the initial database structure or migrate form an older cachet version to a newer one. According to Database: Migrations the --force flag is there to avoid a manual user interaction ( a prompt) for destructive operations that can cause data loss. Do we get those operations in Cachet?
Or can we run those commands every time?

$ docker exec -it cachet php artisan key:generate

This command will generate a new encryption key for the database encryption. Correct?
So this command is not idempotent and i read a note in the documentation that you should generate a new key once you generated one. But is this the same as the env var APP_KEY (from entrypoint.sh)? If yes, we only execute this command if the env var APP_KEY is not set.

$ docker exec -it cachet php artisan config:cache

This generates the config cache. Seems to be idempotent.
So this is fine to execute at every time.

I would like to get your opinion.
In the end this makes the usage of Cachet in a Docker env much more easier, because you skip the manual steps. Further more it enables you to uns runs on Mesos or AWS easier (and enables maybe more users).
If you agree with me i would create a PR for this. And i offer my help to run this on Mesos and / or AWS (my goal is it to un on Mesos).

@jbrooksuk
Copy link
Member

If you agree with me i would create a PR for this. And i offer my help to run this on Mesos and / or AWS (my goal is it to un on Mesos).

We're actually looking to create an AMI image, that we could sell on the Marketplace, cachethq/cachet#1324 — with no experience in doing this, is it something you could help out with?

@andygrunwald
Copy link
Contributor Author

@jbrooksuk The AMI is a good idea, but it don't solve this problem here.
Your custom AMI can only be used on AWS EC2 instances.
But if you want to use AWS Elastic Container Engine or AWS Elastic Beanstalk, you can`t use the AMI image.
This applies for Mesos or Kubernetes as well. With the modifications i suggested you can use them all (because you are running in a container / docker).

@andygrunwald
Copy link
Contributor Author

I made a little bit research about the execution of the commands. Here is a small update:

$ php artisan migrate --force

If this command can be executed several times depends on the individual app.
I assume that this comes handy if you do an upgrade of cachet

$ php artisan key:generate

This command generates the key for hashing secret information (like passwords) in Laravel.
The generated key will be stored in APP_KEY of the .env file.
This means: This command should not be executed more than once in a production env.
The good part: This docker script supports injecting a APP_KEY env var. With this we don't need to execute this at all (of the APP_KEY env var is set).

$ php artisan config:cache

Can be run every time. Only a "cache" will be updated. See https://laravel.com/docs/5.0/configuration#configuration-caching

@andygrunwald
Copy link
Contributor Author

Another update:
We don't need to fire php artisan config:cache, because this will be executed as a post script at composer install.
See

Loading composer repositories with package information
Installing dependencies from lock file
Nothing to install or update
Generating optimized autoload files
> php artisan clear-compiled
> php artisan optimize --force
Generating optimized class loader
Compiling common classes
> php artisan config:cache
Configuration cache cleared!
Configuration cached successfully!
> php artisan route:cache
Route cache cleared!
Routes cached successfully!
> chmod -R 755 storage
...

@andygrunwald
Copy link
Contributor Author

I created a PR for this.
I tested it and it works quite fine. Check the PR at #39

You can start the image like:

$ docker run -d --name cachet -p 8000:8000 -e DB_HOST="192.168.178.22" -e DB_DATABASE=cachet -e DB_USERNAME=cachet -e DB_PASSWORD="cachet" -e APP_KEY="LGUbYbh4GpeVHxLZwAgzUEwkrw66iGFU" -e DB_MIGRATION="YES" andy/cachet-startup

In the first run the log looks like:

docker logs 31d0de1ecbce
Loading composer repositories with package information
Installing dependencies from lock file
Nothing to install or update
Generating optimized autoload files
> php artisan clear-compiled
> php artisan optimize --force
Generating optimized class loader
Compiling common classes
> php artisan config:cache
Configuration cache cleared!
Configuration cached successfully!
> php artisan route:cache
Route cache cleared!
Routes cached successfully!
> chmod -R 755 storage
Migration table created successfully.
Migrated: 2015_01_05_201324_CreateComponentGroupsTable
Migrated: 2015_01_05_201444_CreateComponentsTable
Migrated: 2015_01_05_202446_CreateIncidentTemplatesTable
Migrated: 2015_01_05_202609_CreateIncidentsTable
Migrated: 2015_01_05_202730_CreateMetricPointsTable
Migrated: 2015_01_05_202826_CreateMetricsTable
Migrated: 2015_01_05_203014_CreateSettingsTable
Migrated: 2015_01_05_203235_CreateSubscribersTable
Migrated: 2015_01_05_203341_CreateUsersTable
Migrated: 2015_01_09_083419_AlterTableUsersAdd2FA
Migrated: 2015_01_16_083825_CreateTagsTable
Migrated: 2015_01_16_084030_CreateComponentTagTable
Migrated: 2015_02_28_214642_UpdateIncidentsAddScheduledAt
Migrated: 2015_05_19_214534_AlterTableComponentGroupsAddOrder
Migrated: 2015_05_20_073041_AlterTableIncidentsAddVisibileColumn
Migrated: 2015_05_24_210939_create_jobs_table
Migrated: 2015_05_24_210948_create_failed_jobs_table
Migrated: 2015_06_10_122216_AlterTableComponentsDropUserIdColumn
Migrated: 2015_06_10_122229_AlterTableIncidentsDropUserIdColumn
Migrated: 2015_08_02_120436_AlterTableSubscribersRemoveDeletedAt
Migrated: 2015_08_13_214123_AlterTableMetricsAddDecimalPlacesColumn
Migrated: 2015_10_31_211944_CreateInvitesTable
Migrated: 2015_11_03_211049_AlterTableComponentsAddEnabledColumn
Migrated: 2015_12_26_162258_AlterTableMetricsAddDefaultViewColumn
Starting supervisord...
2016-01-26 20:51:49,958 CRIT Supervisor running as root (no user in config file)
2016-01-26 20:51:49,964 INFO RPC interface 'supervisor' initialized
2016-01-26 20:51:49,964 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2016-01-26 20:51:49,964 INFO supervisord started with pid 1
2016-01-26 20:51:50,967 INFO spawned: 'cron' with pid 87
2016-01-26 20:51:50,969 INFO spawned: 'nginx' with pid 88
2016-01-26 20:51:50,974 INFO spawned: 'php5-fpm' with pid 89
2016-01-26 20:51:52,008 INFO success: cron entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2016-01-26 20:51:52,008 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2016-01-26 20:51:52,008 INFO success: php5-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

In the second run the log looks like:

Loading composer repositories with package information
Installing dependencies from lock file
Nothing to install or update
Generating optimized autoload files
> php artisan clear-compiled
> php artisan optimize --force
Generating optimized class loader
Compiling common classes
> php artisan config:cache
Configuration cache cleared!
Configuration cached successfully!
> php artisan route:cache
Route cache cleared!
Routes cached successfully!
> chmod -R 755 storage
Nothing to migrate.
Starting supervisord...
2016-01-26 21:01:12,127 CRIT Supervisor running as root (no user in config file)
2016-01-26 21:01:12,135 INFO RPC interface 'supervisor' initialized
2016-01-26 21:01:12,136 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2016-01-26 21:01:12,136 INFO supervisord started with pid 1
2016-01-26 21:01:13,139 INFO spawned: 'cron' with pid 84
2016-01-26 21:01:13,140 INFO spawned: 'nginx' with pid 85
2016-01-26 21:01:13,142 INFO spawned: 'php5-fpm' with pid 86
2016-01-26 21:01:14,179 INFO success: cron entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2016-01-26 21:01:14,179 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2016-01-26 21:01:14,179 INFO success: php5-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

@djdefi
Copy link
Contributor

djdefi commented Jan 27, 2016

Looks like there is a different method for this per #39 (comment)

@andygrunwald
Copy link
Contributor Author

I posted a little bit more detailed question to #39. Waiting for feedback.

@djdefi
Copy link
Contributor

djdefi commented Feb 17, 2016

Looks like we need to wait for upstream docs to be updated at this point.

@andygrunwald
Copy link
Contributor Author

Yep, because i dont know what commands will be replaced by theinstallorupdate` command.

@jbrooksuk
Copy link
Member

For new installations it should be php artisan app:install and for existing it's php artisan app:update :)

@GrahamCampbell
Copy link
Contributor

Yep, because i dont know what commands will be replaced by theinstallorupdate` command.

Well, basically just don't make any assumptions about needing to run migration commands when we don't ask you to in the docs, and you'll be ok.

@andygrunwald
Copy link
Contributor Author

@GrahamCampbell true.
BUt i think you don`t get the problem / goal of this here. The goal is to start a docker container just by "docker run -e foo=bar..." and than access http://docker-host/ and have an up and running Cachet without any kind of action with migrate, commands and so on.
That is why i asked what is the correct order / commands.

@jessesanford
Copy link

I am a big fan of this. Anyone who wants to use any sort of automation to deploy this docker image will need this. +1

@jbrooksuk
Copy link
Member

@andygrunwald anything within .env can be supplied as a system environment variable anyway.

@jbrooksuk
Copy link
Member

I've updated the documentation to show the app:install command that should be ran after key:generate.

@djdefi
Copy link
Contributor

djdefi commented Mar 4, 2016

Thanks @jbrooksuk

I still need to run a php artisan config:cache but it may actually be a browser caching issue on my side as well.

@mre
Copy link

mre commented Mar 9, 2016

Seeing that these environment variables are completely optional, I think it would be awesome to include them as they would help new users like myself getting started. It's awesome to get Cachet up and running with a single command. Also, as @jessesanford said, it makes automation much easier. This would enable Docker Swarm and Marathon deploy support out of the box. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants