Node js/Express to replace LAMP - php

I need help from you NodeJS ninjas. I am starting to learn it, after doing a good amount of LAMP stuff. I have written several systems in Apache/PHP/MySQL for a small corporate intranet (including things like a ticket system, employee scheduling, production reports, financial reports, etc).
So, in LAMP world, I start the Apache and MySQL engine. Then people go to their browsers, type the server IP and browse the different systems I've written for them based on the folder in htdocs.
I am trying to think what the equivalent would be in a set up with NodeJS, Express using the MVC model (something I am also new to). Two main questions:
Since I have several systems (employee scheduling, financial
reports, etc), would each one of these have their own middleware for managing, with their middleware rules and all that? or would they all run under just a main thread? (load balancing is another thing that came up).
What would the folder layout be? XAMPP had the htdocs folder and the folder structure was whatever I wanted.
From what I've seen in most tutorials, an option for a folder layout is:
-app
-- controllers
-- models
-- routes
-- views
-config
-- env
-node_modules
-public (I imagine the systems I implement would be on here?)
-server.js
Thank you for your help, I am still a complete noob, but I am excited to get into this.

I come from LAMP stack word and moved to nodeJS 2 years ago. A lot changed since then.
Things you need to know for nodeJS vs PHP :
nodeJS runs under google's JavaScript V8 engine.
nodeJS is ingle-threaded. PHP is multi-thread. That means any modification to a global variable, if there's any, is seen by all the connected users.
nodeJS with express alone is not MVC since MVC is a architectural pattern. You can if you want create folders to define a MVC pattern or hMVC pattern (depending on your needs). A bigger frameworks called SAILS does native MVC for you.
to start a nodeJS project, you have to cli node yourApp.js. That said, there is a better way to start a project using a script placed inside package.json managed by npm or using other npm package such as nodemon. There is no specific folder to start a project like PHP since PHP is managed by Apache and Apache is configured to have a specific folder for html docs.
Other things to add :
Javascript uses EcmaScript as scripting language. The version 6 of ES was finalised in summer 2015, and all browsers still doesn't native take it in charge. Since nodejs uses google's v8 engine, it's still based on ES5.1 or experimental ES6 with --hamrony flag calling node in cli. Since node5 many ES6 features are implemented but still not all are.
NodeJS is asynchronous, and async call are HARD to learn when you come from php word. You will need a lot of practices. I suggest you go read module pattern and revealing pattern.
I hope I have answered you'r questions

Related

Zend Framework 2 Application inside Zend Framework 1 Application and Session Sharing

Before explaining my situation, here is a small briefing of the system I am running and my overall experience with web programming:
Development Environment: Ubuntu Server 4.14 64-bit, Apache 2, PHP and MYSQL database.
Experience: I do not have much experience with PHP, the main language I am using for my current project (it has been almost three years since I last worked with web programming; these last few years my focus was mainly on the development of desktop apps).
I am developing a new website for a company and almost all of the application code is ready. This application was developed in Zend Framework 2 (PHP) + Doctrine 2. Only a few aspects are missing, which are:
1 - The client currently has a website that works as an educational social network focused on providing a platform for students and teachers to interact and share knowledge and ideas. My work is related to the development of a new interface which we defined as a 'relational-modular interface' consisting in a new way of displaying information to the users of this platform. The website that the client already has was developed in Zend Framework 1, and we need the new application to coexist with the old application in the same domain. So far so good. The question is: these frameworks have a structure of files and directories that I do not fully understand yet, particularly concerning the implementation of Zend Framework 2 when organized within the implementation of Zend Framework 1. In simpler terms, I need to have the ZF2 application that I have developed running inside a fully functional ZF1 application [there are reasons for this choice that, albeit counter intuitive at first glance, will give us valuable time to work on the transition from the original platform to our new system]. The reason for running ZF2 inside ZF1 is that at certain points in the old application [ZF1], the user will be redirected to the new application [ZF2] without ever leaving the domain.
2 - Both applications [ZF1 and ZF2] will use the same domain (eg -..> Domain.com). The old application currently resides in a subdomain (ZF1 -> school.domain.com) and, for now, the new application will be located in a subdomain of the old application (ZF2 -> imr.school.domain.com). Up to this point, I suppose none of this is complicated to accomplish. However, using the aforementioned structure we still can't read the Session data that was created in the parent domain (school.domain.com) from the subdomain (imr.school.domain.com), which apparently is setting Cookies. We need to read and set these Session values in order for the user to be able to log in the relational modular interface and be redirected to the old application keeping his session active (and vice versa).
How can I achieve this?
In case someone needs an answer to my problem, i've found a solution:
Run ZF1 and ZF2 together
Unfortunately, can't use sub-domains. Had to use school.domain.com/imr.
Not exactly what i've expected, but works.

Zend framework installation - need clarification

I've seen lots of videos and instructions on how to install zend framework on wamp and other similiar local host environments. I've also seen lots of references, including here, that mention you don't need to 'install' zend, it just needs to be included in the php files to work.
As I think I understand it, installing zend on localhost environments will allow you to utilize certain tools that for example automate the creation of projects and gets the most out of the framework. I'm assuming that to then use these projects in a web host environment, you simply need to upload a specific project's files and ensure the zend files are in place and included in the directories.
Are my assumptions correct? I'm still trying to grasp the basics of this one and haven't found clarifications in my google searches.
Everything you wrote is correct. It helped me to think of Zend Framework as a library of components rather than as a program you need to install. As long as your application has access to that library of components, Zend Framework is installed. This doesn't address any of the configuration tasks you'll need in Bootstrap and/or application.ini, but should clear up installation.
Regarding the automated creation of projects and project elements (controllers, actions, etc.) this feature is available via Zend_Tool and is typically used only during development, so it shouldn't come into play once you've ported from your localhost.
Automated creation of the projects is far not the main feature of Zend.
The majority of the php frameworks are about providing the best infrastructure for complying to MVC design pattern, about object relational mapping, security enhancements etc.
And yes, the whole project tree is what you'd need to carry around for deployments.

In search of opinions on web based version control systems

Researching various open source, web-based document management/version control systems. I've checked google/questions here, etc...
I'm looking for a lightweight web-based (apache) document mgmt/version control app that runs on top of SVN.
I need to have the ability to:
have multiple users checkin/checkout
have a workflow (when userA checks the file in, and finishes the app passes it to the next person, etc...
the app needs to allow me to have a structure where the files can be moved as a group. the files will be changed on a monthly basis
app needs to have a access/premission control system. some people can see certain files, and perform certain actions on the files
I imagine that I'm going to have 40-50 people dealing with the different files. I imagine that I'm going to have 2000-3000 files that have to be massaged.
I'd prefer that the app be php based if possible, as opposed to a straight java app.
Thanks
I suggest you take a look at Subversion:
WikiPedia: http://en.wikipedia.org/wiki/Subversion_(software)
Mainpage: http://subversion.apache.org.
I honestly don't know if it fits all requirements that you've posted, as I've only used it on projects involving small teams, but you should be able to sort that out by reading the WikiPedia page linked above. That said, it definitely meets the web-dev version control.
A vanilla installation of SVN isn't going to do this; it only does regular version control (commits, branches, etc.). There are plenty of web based svn interfaces, but all they do is give you a way to work with regular svn over the web. The document management features and workflow you require are going to come from some other document management system; I don't know of any that use svn as a back end.
I believe Mercurial provides a web-based interface as well.
For a simplistic, but working version control system made entirely in PHP, built on top of ASVCS, take a look at IntraVersion (http://webscripts.softpedia.com/script/Development-Scripts-js/IntraVersion-39805.html) Not much, but for those stuck like me with no server to host private projects on at the moment, it's a helper.
Have a look at knowledge tree. PHP, open source, with support/hosting available. I've used it in the past. It sucks less than other solutions.

How do you handle library dependencies during deployment using PHP?

this is a question on PHP mainly. I was wondering: How do you make sure that all necessary libaries are packaged with your application when you do a deployment to (production) servers?
A more concrete example: I have an app running on Zend Framework and each time I roll the application to a server the deployment process creates a fresh "installation" on that system. Therefore, I need to bundle Zend Framework together with my application and then copy the files to the right places together (it is done automatically). Currently, I am using a svn:externals definition to get the files out of Zend's SVN system during deployment, however, I don't want to rely on that SVN and I also don't want to put traffic on external SVNs with each deployment.
In the Java world, I am used to Maven which handles such stuff using central artifact repositries. I know that there is a Maven4PHP version, however, I am more looking for a PHP-based solution. Additionally, I don't believe that PEAR is a good way to go as it doesn't really fulfill my requirement of bundling the applicaiton (incl. libs) into a single deployable.
Is there some tool available already that I am not aware? Or do you have any great technique that I should know?
Thanks much for your help!
Michael
There's a build system called Phing which is written in PHP and based on Apache Ant.
I personally can very well live with externals.
I think the vendor branching would solve the problem from your example quite straightforward, but if you also don't like large repositories I'd recommended to keep watching on the modern toys like composer and what it solve(and maybe phark, I never heard before :) )
It isn't production ready yet but you might want to keep an eye on the Phark project. It is a port of Bundler to PHP.
While looking through the Simplify your external dependency management slides I came across a tool called pantr which can be used as a PEAR installer. pantr as PEAR installer which allows you to specify your dependencies in a project specific file.
The article Version Control != Dependency Management has some information about using the new PEAR installer called Pyrus

How to efficiently manage multiple installations of a web application?

From my experience, one of the bigger problems we come across during our webdevelopment process is keeping different setups updated and secure across different servers.
My company has it's own CMS which is currently installed across 100+ servers. At the moment, we use a hack-ish FTP-based approach, combined with upgrade scripts at specific locations to upgrade all of our CMS setups. Efficiently managing these setups becomes increasingly difficult and risky when there are several custom modules involved.
What is the best way to keep multiple setups of a web application secure and up-to-date?
How do you do it?
Are there any specific tips regarding modularity in applications, in order to maintain flexibility towards our clients, but still being able to efficiently manage multiple "branches" of an application?
Some contextual information: we mainly develop on the LAMP-stack. One of the main factors that helps us sell our CMS is that we can plugin pretty much anything our client wants. This can very from 10 to to 10.000 lines of custom code.
A lot of custom work consists of very small pieces of code; managing all these small pieces of code in Subversion seems quite tedious and inefficient to me (since we deliver around 2 websites every week, this would result in a lot of branches).
If there is something I am overlooking, I'd love to hear it from you.
Thanks in advance.
Roundup: first of all, thanks for all of your answers. All of these are really helpful.
I will most likely use a SVN-based approach, which makes benlumley's solution closest to what I will use. Since the answer to this question might differ in other usecases, I will accept the answer with the most votes at the end of the run.
Please examine the answers and vote for the ones that you think have the most added value.
I think using a version control system and "branching" the part of the codes that you have to modify could turn out to be the best approach in terms of robustness and efficiency.
A distributed version system could be best suited to your needs, since it would allow you to update your "core" features seamlessly on different "branches" while keeping some changes local if need be.
Edit: I'm pretty sure that keeping all that up to date with a distributed version system would be far less tedious than what you seem to expect : you can keep the changes you are sure you're never going to need elsewhere local, and the distributed aspect means each of your deployed application is actually independent from the others and only the fix you mean to propagate will propagate.
If customizing your application involves changing many little pieces of code, this may be a sign that your application's design is flawed. Your application should have a set of stable core code, extensibility points for custom libraries to plug into, the ability to change appearance using templates, and the ability to change behavior and install plugins using configuration files. In this way, you don't need a separate SVN branch for every client. Rather, keep the core code and extension plugin libraries in source control as normal. In another repository, create a folder for each client and keep all their templates and configuration files there.
For now, creating SVN branches may be the only solution that helps you keep your sanity. In your current state, it's almost inevitable that you'll make a mistake and mess up a client's site. At least with branches you are guaranteed to have a stable code base for each client. The only gotcha with SVN branches is if you move or rename a file in a branch, it's impossible to merge that change back down to the trunk (you'd have to do it manually).
Good luck!
EDIT: For an example of a well-designed application using all the principles I outlined above, see Magento E-Commerce. Magento is the most powerful, extensible and easy to customize web application I've worked with so far.
I may be wrong, but it seems to me what Aron is after is not version control. Versioning is great, and I'm sure they're using it already, but for managing updates on hundreds of customized installations, you need something else.
I'm thinking something along the lines of a purpose-built package system. You'll want every version of a module to keep track of its individual dependencies and 'guaranteed compatibilities', and use this information to automatically update only the 'safe' modules.
E.g. let's say you've built a new version 3 of your 'Wiki' module. You want to propagate the new version to all the servers running your application, but you've made changes to one of the interfaces within the Wiki module since version 2. Now, for all default installations, that is no problem, but it would break installations with custom extensions on top of the old interface. A well-planned package system would take care of this.
To address the security question, you should look into using digital signatures on your patches. There are lots of good libraries available for public-key-based signatures, so just go with whatever seems to be the standard for your chosen platform.
Not sure whether someone's said this, there are a lot of long responses here, and I've not read them all.
I think a better approach to your version control would be to have your CMS sat on its own in its own repository and each project in its own. (or, all of these could be subfolders within one repo i guess)
You can then use its trunk (or a specific branch/tag if you prefer) as an svn:external in each project that requires it. This way, any updates you make to the CMS can be committed back to its repository, and will be pulled into other projects as and when they are svn updated (or the external is svn:switch 'ed).
As part of making this easier, you will need to make sure the CMS and the custom functionality sit in different folders, so that svn externals works properly.
IE:
project
project/cms <-- cms here, via svn external
project/lib <-- custom bits here
project/www <-- folder to point apache/iis at
(you could have cms and lib under the www folder if needed)
This will let you branch/tag each project as you wish. You can also switch the svn:external location on a per branch/tag basis.
In terms of getting changes live, I'd suggest that you immediately get rid of ftp and use rsync or svn checkout/exports. Both work well, the choice is up to you.
I've got most experience with the rsync route, rsyncing an svn export to the server. If you go down this route, write some shell scripts, and you can create a test shell script to show you the files it will upload without uploading them as well, using the -n flag. I generally use a pair of scripts for each environment - one a test, and one to actually do it.
Shared key authentication so you don't need a password to send uploads up may also be useful, depending on how secure the server to be given the access is.
You could also maintain another shell script for doing bulk upgrades, which simply calls the relevant shell script for each project you want to upgrade.
Have you looked at Drupal? No, not to deploy and replace what you have, but to see how they handle customizations and site-specific modules?
Basically, there's a "sites" folder which has a directory for every site you're hosting. Within each folder is a separate settings.php which allows you to specify a different database. Finally, you can (optionally) have "themes" and "modules" folders within sites.
This allows you to do site-specific customizations of particular modules and limit certain modules to those sites. As a result, you end up with a site that the vast majority of everything is perfectly identical and only the differences get duplicated. Combine that with the way it handles upgrades and updates and you might have a viable model.
Build into the code a self-updating process.
It will check for updates and run them when/where/how you have configured it for the client.
You will have to create some sort of a list of modules (custom or not) that need to be tested with the new build prior to roll-out. When deploying an update you will have to ensure these are tested and integrated correctly. Hopefully your design can handle this.
Updates are ideally a few key steps.
a) Backup so you can back out. You should be able to back out
the entire update at any time. So,
that means creating a local archive
of the application and database
first.
b) Update Monitoring Process - Have the CMS system phone home to look for a new build.
c) Schedule Update on availability - Chances are you don't want the update to run the second it is available. This means you will have to create a cron/agent of some kind to do the system update automatically in the middle of the night. You can also consider client requirements to update on weekends, or on specific days. You can also stagger rolling out your updates so you don't update 1000 clients in 1 day and get tech support hell. Staggered roll-out of some kind might be beneficial for you.
d) Add maintenance mode to update the site -- Kick the site into maintenance mode.
e) SVN checkout or downloadable packages -- ideally you can deploy via svn checkout, and if not, setup your server to deliver svn generated packages into an archive that can be deployed on client sites.
f) Deploy DB Scripts - Backup the databases, update them, populate them
g) Update site code - All this work for one step.
h) Run some tests on it. If your code has self-tests built in, it would be ideal.
Here's what I do...
Client-specific include path
Shared, common code is in shared/current_version/lib/
Site specific code is in clients/foo.com/lib
The include path is set to include from the clients/foo.com/lib, and then share/lib
The whole thing is in a version control system
This ensures that the code uses shared files wherever possible, but if I need to override a particular class or file for some reason, I can write a client specific version in their folder.
Alias common files
My virtual host configuration will contain a line like
Alias /common <path>/shared/current_version/public_html/common
Which allows common UI elements, icons, etc to be shared across projects
Tag the common code with each site release
After each site release, I tag the common code by creating a branch to effectively freeze that point in time. This allows me to deploy /shared/version_xyz/ to the live server. Then I can have a virtual host use a particular version of the common files, or leave it pointing at the current_version if I want it to pick up the latest updates.
Have you looked at tools such as Puppet (for system administration incl. app deployment) or Capistrano (deployment of apps in RubyOnRails but not limited to these)?
One option would be to set up a read-only version control system (Subversion). You could integrate access to the repository into your CMS and invoke the updates through a menu, or automatically if you do not want the user to have a choice about an update (could be critical). Using a version control system would also allow you to keep different branches easily
As people have already mentioned that using version control (I prefer Subversion due to functionality) and branching would be the best option. Another open source software available on sourceforge called cruisecontrol. Its amazing, you configure cruisecontrol with subversion in sach a way that any code modification or new code added in serversion, Cruise control will know automatically and will do build for you. It will save your hell of time.
I have done the same way in my company. we have four projects and have to deploy that project on different servers. I have setup cruiseconrol in such a way that any modification in code base triggers automatic build. and another script will deploy that build on the server. your are good to go.
If you use a LAMP stack I would definitely turn the solutions files into a package of your distribution and use it for propagate changes. I recommend for that matter Redhat/Fedora because of RPM and it's what I have experience on. Anyway you can use any Debian based distribution too.
Sometime ago I made a LAMP solution for managing an ISP hosting servers. They had multiple servers to take care of web hosting and I needed a way to deploy the changes of my manager, because every machine was self-contained and had a online manager. I made a RPM package containing the solution files (php mostly) and some deploying scripts that runned with the RPM.
For automated updating we had our own RPM repository set on every server in yum.conf. I set an crontab job to update the servers daily with the latest RPMs from that trusted repository.
Trustiness can be achieve too because you can use trust settings in the RPM packages, like signing them with your public key file and accepting only signed packages.
Hm could it be an idea to add configuration files? You wrote that a lot of small script are doing something. Now if you'd build them into the sources and steered them with configuration files shouldn't that "ease" that?
On the other hand having branches for every customer looks like an exponential growth to me. And how would you "know" which areas you've done something and do not forget to "make" changes in all other branches also. That looks quite ugly to me.
It seems a combination of revision controls, configuration options and/or deployment receipts seems to be a "good" idea.....
With that many variations on your core software, I think you really need a version control system to stay on top of pushing updates from the trunk to the individual client sites.
So if you think Subversion would be tedious, you've got a good sense for what the pain points will be... Personally, I wouldn't recommend Subversion for this, since it's not really that good at managing & tracking branches. Although benlumley's suggestion to use externals for your core software is a good one, this breaks down if you need to tweak the core code for your client sites.
Look into Git for version control, it's built for branching, and it's fast.
Check out Capistrano for managing your deployments. It's a ruby script, often used with Rails, but it can be used for all sorts of file management on remote servers, even non-ruby sites. It can get the content to the remote end through various stragegies including ftp, scp, rsync, as well as automatically checking out the latest version from your repository. The nice features it provides include callback hooks for every step of the deploy process (e.g. so you can copy your site-specific configuration files which might not be in version control), and a release log system--done through symlinks--so you can quickly roll back to a previous release in case of trouble.
I'd recommend a config file with the list of branches and their hosted location, then run through that with a script that checks out each branch in turn and uploads the latest changes. This could be cron'd to do nightly updates automatically.

Categories