CodeIgniter Forums

Full Version: Creating Web Installer for CI Based Application
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Im looking for a way to create a decent installer for an open source application, based on CI. Does anyone have any recommendations?

I was thinking have it so when they git clone/untar/unzip/whatever the files initially, and go to the folder in the browser, it would show
them a web interface that they can use to configure the app, something along the lines of...
  1. Check proper PHP version and PHP dependencies
  2. Check the proper file/folder permissions
  3. Check other system related stuff (EG: Resources)
  4. Have them specify the database creds, test them, and update the database.php file (If perms allow)
  5. Create the first administrative user
  6. etc
My question is, where should the PHP code for all this go? I was thinking maybe have the setup code in its own folder, then once the setup is 100% complete, just have the whole setup folder deleted... Ive seen that before, I actually thought it was pretty neat. lol
Pyro CMS had a good installer, they've moved over to Laravel now but you can still get the Codeigniter version in the 2.2 branch. Might be worth installing and looking at the installer code to see how it works. This file is a good place to start. https://github.com/pyrocms/pyrocms/blob/...er_lib.php
Thanks AidanW

My buddy thinks that the installer should actually be a part of CI... The problem I have with that, is if they somehow provide a value, that somehow gets past the PHP sanity checking and causes a fatal PHP error... then the installer is down, and they cant re-install..

Anyone have an opinion on that? Should the installer be part of CI? or its own independent PHP files?
If the installer is depending on CI, you pretty much have to guide the installation process and only allow configuration changes which are going to work. A lot of the work in guiding the process is simply anticipating what a user might do wrong. For example, if you setup a default directory layout which sets the application and system directories outside the web root, you should place an index.php file in the project root and/or the application root which tells the user their site needs to be configured to point to the other location.

In each step of the process, you would most likely display the current configuration, indicate anything which may need to be changed, and only allow the user to take the next step when the installation can continue.

One of the biggest things is tracking what has already been done to prevent the installer from doing anything which might be dangerous on a site which has already been configured to a certain point (or already completed installation). In most cases, you'll probably want layered, even potentially redundant checks in an installer to make sure the installer is permitted to take the requested action.

In some cases, you may want to base whether you can repeat a particular step in the installation on whether a later step in the process was successfully completed. For example, if you allow the user to configure the database connection, you may want to allow them to re-configure the connection at any point until the installation is complete, or until the installer has successfully performed certain operations on the database. You may even want to permit them to configure the database with one account early in the process, then allow them to change the account after the site has finished setting up the database, but before inserting data, then lock out that part of the installer once you verify the data has been successfully inserted. After all, the user might need to use an account with more privileges to create tables, but use an account which can't modify/create/drop tables for daily site operations. If they mis-type something in the configuration, though, the inserts would fail and they'd need to be able to fix the configuration.

Overall, I think it's easier to be able to rely on CI for portions of the installation and it makes sense to work in an environment with which you are already comfortable, rather than having to create your own code or use some different code to manage certain operations. On the other hand, it can be frustrating when you need to more or less duplicate code in your installer because you need to handle an error rather than exit and display an error message. You also have to be very careful about making sure your installer can run to some degree with very few dependencies, making it as flexible as possible in the face of errors.
(10-20-2015, 12:27 PM)mwhitney Wrote: [ -> ]A lot of the work in guiding the process is simply anticipating what a user might do wrong. 

One of the biggest things is tracking what has already been done to prevent the installer from doing anything which might be dangerous on a site which has already been configured to a certain point (or already completed installation). In most cases, you'll probably want layered, even potentially redundant checks in an installer to make sure the installer is permitted to take the requested action.

I agree, and I'm OK doing the work, but one thing I've learned when developing websites, is you cant account for 100% of possible cases, and even if you can (or think you can), you should assume that theres a possibility that something can get through.

So with that assumption, if the installer is a CI controller, and they do something that somehow brings down CI (that somehow gets past all the sanity checking I put in place), then that means they cant re-install anything, especially if its a fatal error..

I plan on having the install not rely on the database at all, rather it will configure the config/{database,config,constants,custom}.php files from templates in the install directory. But if they get thrown into place from the install and it breaks the application, then theres nothing they can do, the installer itself is down as well.

This is the only part I'm skeptical about... When I worked for a company called JAWA, I was in the NOC, and we had a major outage, and we were able to bring the ESXi server up, but we had to login to the interface and start some of the important servers... then we realized that whoever created the password repository (which had the password for this), was kept in one of the servers that were on this ESXi host... lol, yeah, sucked. 

Trust me, I actually would rather have the installer as part of CI, that would save a lot of work, and a lot of code, this is why im kinda on the fence...

What do you think is better..
  1. Having the installer as a CI class, and on the off-chance, something they configure brings down CI, just have them re-download the entire installation file (or whatever the install method was). (Less work/code, but more vulnerable)
  2. Or do all the extra work involved in creating an installer thats totally independent, but allow the installer to be able to remedy any fatal errors that may be caused in the install process (More code/work, less vulnerable)

In the independent install, it would still be possible to include system/core/Common.php and anything in system/helpers/* or application/helpers/*, to make the install easier, which id probably end up doing, since they're just functions, not classes

P.S. Thanks for the tips thus far, much appreceated
Generally I would go with method #1, but I'm thinking more along the lines of setting up an installer that runs in incremental steps, where you would be able to go back to a previous step if something broke as a result of whatever was done in the last step.

It's really a question of how much they're going to be allowed to change, though. If the installer is going to give them free reign over the config.php and .htaccess file, then they're probably going to find a way to break it. These are the items that are most likely to put you into a situation from which you can't recover. Routing is another area that could make this difficult.

The database is dangerous in the sense that someone has a great deal of power over a site if they can modify the database, but it's relatively easy to keep your installer from breaking if you can't access the database.

As far as I know, CI doesn't use the constants config (SHOW_DEBUG_BACKTRACE is used in the error_exception view, but its in an if (defined()) check), so you can only break your app/installer there if you depend on a value in the file without checking it (unless you do something especially nasty, like write exit() or die() into it).

So, the big worry is really the config.php file, and, as long as it writes out without corruption in the first place, the biggest thing at that point is whether the settings are compatible with the server configuration.

I think the best thing you can do to really get an idea of what helps make an installer robust is to start doing things that you know will break an application and look at how it breaks. This will get you thinking about what you might be able to do to either prevent a complete break or make it recoverable. Maybe it could be as simple as putting a link in the installer's error views which allows the user to indicate to the installer that something is broken and the installer needs to use a known-good configuration rather than the current configuration.

In the end, a lot of it is part of basic application security: filter input, and, perhaps more important in this situation, limit their capabilities. Build an extremely limited installer, first. Then, add features, considering along the way how each new feature can break the application. If you need a config value in your application, start with a sane default, then check the value you get from the config file to make sure it's within a limited set of permitted values, and that any related values are compatible.

The most difficult part to deal with is anything that's going to impact routing or otherwise prevent your controller from loading in the first place. Once execution has reached your controller, you should find that you can give the user a lot of options and flexibility in a lot of areas without letting them break the application.
just one opinion but i've had the experience so many times where an installer fails on some step, and then instead of trying out the application i'm trying to debug the installer. so if possible there should be an 'installer free' version of the app, with the relevant sql files to create the database tables, and basic instructions for filling out configs like server path, etc. also there are times when you want to check out an application before doing an install and creating a bunch of db tables etc.
For my cms I've managed to bundle the installer within codeigniter using a bit of vanilla php to do the immediate communication of the database and then write to the db config file.

For example, in my installer controller I query if a line has been written to the db.config file if it hasn't been written I use the information stored from the form input to write in the details. Obviously you have to be careful with any controller that writes to a file, but for extra safety I made the write controller a private method so you can't just call the write method from a url. I debated whether to have the system automagically delete the install controller for safety measures but decided against it as you would need another method with file delete permissions anyway to delete the controller, which in turn would be a security vulnerability!!

I've yet to find a solution where the installer automagically finds the default url. For example, if you rename the base folder or install on a live domain you have to go in and change the line of the base url in config.php.

The only way around that was maybe using a separate installer away from codeigniter in pure PHP and then have the system delete the installer after install. I found this to be a little too inconvenient and risky in terms of security without offering much functionality so I opted out of this option.

But wordpress does this pretty much flawlessly so I may revisit the above point.
I agree with Cartalot, have experienced that too and it is so frustrating. And yes, WP has it down to a fine art. I love the way it says 'That's it. Did you expect more?' or something similar. However, if it went wrong who knows what you would do.

I am not sure it is a security vulnerability to have a piece of php code do the writing of the config file for you. Since it is only up and being used for five minutes, then removed. I have seen a few installs that after asking you about DB settings, root paths and admin passwords etc, tell you to delete the install files, and that the main app will not run until the install files have been deleted (although admittedly people like me just rename them in case I need them again).

Now I am thinking about it, I have not actually seen that for a while now, so perhaps it was considered to be bad practice.

Anyway, just thought I would chime in on the conversation.

Best wishes,

Paul.