9

I currently have a php application in development on an AWS EC2 instance but I've decided to move it to Elastic Beanstalk to take advantage of the autoscaling functionality.

While most of the application migrated to the new Elastic Beanstalk EC2 instances flawlessly, I'm running into an issue regarding php sessions. It seems that the php session save path is unwritable, according to the following message generated by php:

 Warning: Unknown: open(/var/lib/php/5.5/session/sess_uc1dpvmoq5fikcv0q2kogker15, O_RDWR)
 failed: Permission denied (13) in Unknown on line 0 Warning: Unknown: Failed to write
 session data (files). Please verify that the current setting of session.save_path is
 correct (/var/lib/php/5.5/session) in Unknown on line 0

Is there any way around this without modifying PHP.ini or CHMODing? I would like to have my application run on the default Elastic Beanstalk EC2 instances without using custom AMIs. I would hope that such a simple use of php sessions should be allowed by default!

Sean
  • 309
  • 1
  • 3
  • 10
  • 1
    By default, php.ini sets the session directory to /tmp but the latest PHP containers on Elastic Beanstalk started pointing it at /var... mentioned above, without proper permissions. This is a known bug that AWS has said they'll fix in a future update. For the time being your best bet (for local sessions) is to set it early in your app using session_save_path() but you will run into issues with multiple servers as mentioned by @hek2mgl below. – James Alday Feb 21 '14 at 15:18
  • is there a link to where AWS acknowledges this issue? – Justin Feb 24 '15 at 17:36

4 Answers4

20

Moving your application to Elastic Beanstalk means that from now on your application will possibly run on multiple physical web server instances. (That's what you're paying for.) This means that a request with a valid session ID could be forwarded to a server which does not possess that session file on disk (you seem to be using the file-based session handler as shown in the question).

Solution A (preferred)
You need to store sessions in a shared location where they can be accessed by all of your web server instances. Amazon typically recommends DynamoDB for this, but it could also be MySQL or Redis or even the Elastic Cache provided by AWS.

Solution B (slower, unreliable, needs SSL termination at load balancer)
Configure your load balancer in a way that it uses "sticky" sessions. This means that the L.B. will unwrap HTTP(S) packets, look for the session cookie and then forward the request to the correct web server where the session lives.

Simon East
  • 55,742
  • 17
  • 139
  • 133
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • See also: http://docs.aws.amazon.com/aws-sdk-php/guide/latest/feature-dynamodb-session-handler.html – Ryan Parman Dec 09 '13 at 21:53
  • @RyanParman Hey! :) nice to see one of the AWS guys below my answer.. May I ask if it is preferable to use a dynamo db instances instead of an elastic cache instance? (And if yes, why?) – hek2mgl Dec 09 '13 at 23:24
  • It definitely depends on the use case, so it's hard to say which would work better in general. The link Ryan provided does include a section of best practices with the DynamoDB session handler though. If your application does not allow you to follow those, then using ElastiCache might be a better choice. – Jeremy Lindblom Dec 10 '13 at 20:18
  • @JeremyLindblom Thanks, will go trough that doc. I'm relatively new to AWS and it is still hard to choose the best out of all available services.. :) – hek2mgl Dec 10 '13 at 21:04
0

You can also add this to your elastic beanstalk project.config file:

"/etc/httpd/conf.d/php.conf" :
   content: |
     php_value session.save_path "/tmp"

that will just set the session save path for you

tobias_k
  • 81,265
  • 12
  • 120
  • 179
0

If you intend to use autoscaling, it means that the application will be copied to different machines/instances and the load balancer will be distributed between them.

Therefore, you will NOT be able to use PHP's default sessions feature or any solutions that write to local disk.

Check if your PHP framework has built-in database sessions. CakePHP has this feature and it works great.

https://book.cakephp.org/4/en/development/sessions.html#database-sessions

But from my own experience, I can say that this database solution doesn't work well if you have a lot of content inside each session or if you have a lot of open sessions. The number and volume of requests to the database can become so high that it can exceed the IOPS limit of the RDS's disk.

William
  • 166
  • 1
  • 4
-2

Actually I've found a very easy solution with 2 lines of PHP-code only that worked for me:

http://technosophos.com/2013/10/09/getting-php-sessions-work-aws-elastic-beanstalk.html

Add that your php and you are done.

<?php
$dir = sys_get_temp_dir();
session_save_path($dir);
?>
  • 1
    To clarify, while this works when you have only 1 server, it may fail once your service scales up - right?? – Nathan H Feb 20 '14 at 15:55
  • 2
    Yes, this will use file base sessions in the /tmp directory (by default). If a user hits another server without that file the won't have a session. I'm currently seeing this in a setup I have - with 4 servers I can reload and get logged in/out on each reload depending on what server loads the page. – James Alday Feb 20 '14 at 20:18