Nginx: How can I provide variable for paths in nginx configuration? - deployment

I have a web application which I test locally and deploy on EC2 instance
I am using local nginx configuration which looks like as
location /static/ { alias /home/me/code/p/python/myapp/static/;
# if asset versioning is used
if ($query_string) {
expires max;
}
} location /templates/ { alias /home/me/code/p/python/app/templates/;
# if asset versioning is used
if ($query_string) {
expires max;
}
}
On EC2 instance, the only thing that would change is the path, e.g.
/home/me/code/p/python/myapp/static/ to /User/ubuntu/code/p/python/myapp/static/
To make this happen I change the configuration to look like
~/code/p/python/myapp/static/
but this didn't work, it shows the path
/etc/nginx/~/code/p/python/myapp/static/
which is not right
Question
- Is it possible to include environment variables in nginx conf?
What I want
- Nginx conf, which can read variables on specific machines to create paths, so that I don't have to change it per machine and code is reusable
Thank you

Two ways of doing this:
As suggested above, symlinking is a really good way of making paths match on machines, while keeping code in one place. A symbolic link basically is an alias; if /link is a symlink for /file, when you ask for /link, you'll get /file.
ln -s /file /link
Using include statements. In nginx, you can include variables.conf;. E.g.
nginx.conf:
include variables.conf
...
http {
listen $port;
...
}
variables.conf:
set $foo "Something";
set $bar "Else";
set $port 80;

Related

Scala Config: Include another file.conf

Currently, I have a resources/application.conf file which has the following keys:
development {
server = www.myapp.com
aws_key = my_aws_key
aws_secret = my_aws_secret
}
I would like to remove my aws_key and aws_secret from the file.
I was thinking of creating another file called resources/credentials.conf and storing my personal authentications there.
credentials {
aws_key = my_aws_key
aws_secret = my_aws_secret
}
and then include it some way in my application.conf or merge that config to the Config object in addition to application.conf.
credentials.conf would be git ignored. A sample file would be checked in credentials-sample.conf which each developer would change according to his own credentials and rename the sample file to credentials.conf
I tried different variation of include like
include "credentials"
include "credentials.conf"
include "./credentials.conf"
include file("./credentials.conf")
and so on.
I know I can pass it via system variables but I would like to try it like mentioned above. If you know of a better way, please let me know.
Typesafe Config provide the way to fallback from one configuration to another. You can try the ConfigFactory.Load() to load different config and use withFallback to line them up in your designated order. Such as:
ConfigFactory.Load("credentials.conf") withFallback ConfigFactory.Load("application.conf")
Inside your conf file, add
include "another_file.conf"
ie: https://github.com/cicco94/scala-akka-slick-demo/blob/master/src/main/resources/application.conf

PHP Built-in Webserver and Relative Paths

TL;DR
Does PHP 5.4 built-in webserver have any bug or restriction about relative paths? Or does it need to be properly (and additionally) configured?
When I used to programming actively I had a system working under URI routing using these lines in a .htaccess file:
RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php [L]
The FrontController received the Request, find the proper route from given URI in a SQLITE database and the Dispatcher call the the Action Controller.
It worked very nicely with Apache. Today, several months later I decided to run my Test Application with PHP 5.4 built-in webserver.
First thing I noticed, obviously, .htaccess don't work so I used code file instead:
<?php
if( preg_match( '/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"] ) ) {
return false;
}
include __DIR__ . '/index.php';
And started the webserver like this:
php.exe -c "php.ini" -S "localhost:8080" "path\to\testfolder\routing.php"
So far, so good. Everything my application need to bootstrap could be accomplished by modifying the include_path like this:
set_include_path(
'.' . PATH_SEPARATOR . realpath( '../common/next' )
);
Being next the core folder of all modules inside a folder for with everything common to all applications I have. And it doesn't need any further explanation for this purpose.
None of the AutoLoader techniques I've ever saw was able to autoload themselves, so the only class manually required is my Autoloader. But after running the Test Application I received an error because my AutoLoader could not be found. o.O
I always was very suspicious about realpath() so I decided to change it with the full and absolute path of this next directory and it worked. It shouldn't be needed to do as I did, but it worked.
My autoloader was loaded and successfully registered by spl_autoload_register(). For the reference, this is the autoloading function (only the Closure, of course):
function( $classname ) {
$classname = stream_resolve_include_path(
str_replace( '\\', DIRECTORY_SEPARATOR, $classname ) . '.php'
);
if( $classname !== FALSE ) {
include $classname;
}
};
However, resources located whithin index.php path, like the MVC classes, could not be found. So I did something else I also should not be doing and added the working directory to the include_path. And again, manually, without rely on realpath():
set_include_path(
'.' . PATH_SEPARATOR . 'path/to/common/next'
. PATH_SEPARATOR . 'path/to/htdocs/testfolder/'
);
And it worked again... Almost! >.<
The most of Applications I can create with this system works quite well with my Standard Router, based on SQLITE databases. And to make things even easier this Router looks for a predefined SQLITE file within the working directory.
Of course, I also provide a way to change this default entry just in case and because of this I check if this file exist and trigger an error if it doesn't.
And this is the specific error I'm seeing. The checking routine is like this:
if( ! file_exists( $this -> options -> dbPath ) ) {
throw RouterException::connectionFailure(
'Routes Database File %s doesn\'t exist in Data Directory',
array( $this -> options -> dbPath )
);
}
The dbPath entry, if not changed, uses a constant value Data/Routes.sqlite, relatively to working directory.
If, again, again, I set the absolute path manually, everything (really) works, the the Request flow reached the Action Controllers successfully.
What's going on?
This a bug in PHP's built-in web server that is still not fixed, as of PHP version 5.6.30.
In short, the web server does not redirect to www.foo.com/bar/ if www.foo./bar was requested and happens to be a directory. The client being server www.foo.com/bar, assumes it is a file (because of the missing slash at the end), so all subsequent relative links will be fetched relative to www.foo.com/instead of www.foo.com/bar/.
A bug ticket was opened back in 2013 but was mistakenly set to a status of "Not a Bug".
I'm experiencing a similar issue in 2017, so I left a comment on the bug ticket.
Edit : Just noticed that #jens-a-koch opened the ticket I linked to. I was not awar of his comment on the original question.

In Nginx, how do you configure a split redirect?

I want to configure Nginx so that this URL:
http://www.example.com/x/...
redirects here:
http://x.example.com/...
and everything else (not http://www.example.com/x/...)
http://www.example.com/...
remains as-is:
http://www.example.com/...
How do you configure Nginx to do this?
you do os by setting up 2 location blocks inside your server config: 1 with the redirect, and 1 with the default stuff that matches anything else like so:
location / {
# directives needed to serve the regular stuff
}
location /x/ {
rewrite ^/x/(.*)$ $1 last;
}

Zend Framework 1.8+: How to automatically set the application environment?

I have been developing an application locally with an application environment setting of development. I think this is being set in the .htaccess file.
Then, I have been deploying new versions to the production server.
I don't want to have to manually change the application environment, by hand, every time I deploy a new version.
How should I do this, so I can set the application environment variable automatically (maybe based on the location that it's being hosted? i.e. myapp.com vs. myapp.local)?
You can do this in the either in the server config, virtual host, directory or .htaccess through
SetEnv SPECIAL_PATH /foo/bin
Ex.
<VirtualHost host1>
SetEnv FOO bar1
...
</VirtualHost>
<VirtualHost host2>
SetEnv FOO bar2
...
</VirtualHost>
For more readings
http://httpd.apache.org/docs/1.3/mod/mod_env.html#setenv
http://docstore.mik.ua/orelly/linux/apache/ch04_06.htm
if (false !== stripos($_SERVER['HTTP_HOST'], 'yourdomain.tld')) {
$_ENV['APPLICATION_ENV'] = $_SERVER['APPLICATION_ENV'] = 'production';
}
at the top of index.php
I do something like SM, but slight different:
$env = 'development';
if ('www.my-host-name.com' == $_SERVER['HTTP_HOST'] || 'my-server-name' == exec('hostname')) {
$env = 'production';
}
defined('APPLICATION_ENVIRONMENT') or define('APPLICATION_ENVIRONMENT', $env);
unset($env);
I use my server hostname to determine the environment. I also use my server name because some scripts are run from a cron job and I need this to do the tests.

Nginx location, alias, rewrite, root

I'm serving /foo/bar/ by way of proxypass and want to continue doing so. However, I would like to serve /foo/bar/baz.swf statically from say /var/www/mystatic/baz.swf and so forth.
I was hoping that I could do something like
location /foo/bar/(.*) {
alias /var/www/mystatic/;
}
location / {
proxy_pass ....;
...
}
And /foo/bar/ would go to the application server while /foo/bar/(.*) would be served statically.
the docs say that I can't do this and need to use a combination of root and rewrite: http://wiki.nginx.org/NginxHttpCoreModule
Adding to the complication, I would like to continue using the ancient, unsupported 0.5.33. Any help would b greatly appreciated.
Edit: moving forward, someone suggested using root instead of alias. But, it doesn't seem that I can use any regex on the location directive with my version? Here, /foo/bar/baz.swf is served by the proxy_pass! I have the file at /var/www/foo/bar/baz.swf.
location /foo/bar/(.+) {
root /var/www/;
}
You can do this; but it's slightly esoteric. Try using:
location ^~ /foo/bar {
alias /var/www/mystatic/;
}
location / {
proxy_pass ....;
}
These options are documented on the Wiki http://wiki.nginx.org/NginxHttpCoreModule#location
location = /foo/bar/baz.swf {}
will clear clear any options set to /foo/bar/baz.swf. So you can leave it
where it is as the proxy options will not be used.
You can:
# mkdir /var/www/foo
# mv /var/www/mystatic /var/www/foo/bar
then use this config:
location ~ ^/foo/bar/(.+) {
root /var/www/;
}