Proper way to handle htaccess files in each environment

I’m currently symlinking the web root to “current.” However, since the .htaccess is part of the .gitignore, it is never sync’d. Currently, that means I need to recreate the htaccess file with each deployment. Is this the intended behavior or am I configuring this incorrectly?

After doing a bit of research, it seems the best method would be to add .htaccess to linked_files in deploy.rb.

1 Like

That’s correct about using linked_files. .htaccess should probably be removed from Git ignore now that I think about it.

1 Like

I just submitted a very minor pull request deleting htaccess (in lieu of a larger move of utilizing a symlinked version instead). As well, I added some lines representing the themes directory.

Note: I tried pasting the github url, but since there’s a “4 link” limit for new posters, once your system converted the github link, it became 4+ links and wouldn’t let me publish the reply.

For anyone that finds this by googling later:

Add .htaccess to the linked_files line, so it looks something like this…

set :linked_files, %w{.env .htaccess}

Make sure you create an .htaccess file in your shared directory along with your .env file.

2 Likes

ahh, thanks. Been puzzling about how to deal with .htaccess.

Hi all, we’ve added .htacces to the linked_files, it now lives in shared/.htaccess in prod and staging where we deploy to. It seems that WP expects to find this file in current/web/.htaccess, it’s not in our project git as WP should write to it as it likes. Any suggestions? Thanks

Have you redeployed? The symbolic link should be created based on that linked_files directive.

in config/deploy.rb I have set :linked_files, %w{.env .htaccess}, re-deployed.
In production:

root@liberty vhosts/bedrock$ ls -la shared/
total 8
drwxr-xr-x 3 deploy deploy     43 Jul 26 19:36 .
drwxr-xr-x 5 deploy www-data 4096 Jul 26 20:35 ..
-rw-r--r-- 1 deploy deploy    993 Jul 26 17:11 .env
-rw-rw-r-- 1 deploy www-data    0 Jul 26 19:36 .htaccess
drwxr-xr-x 3 deploy deploy     16 Jul 24 14:16 web
root@liberty vhosts/bedrock$ ls -la current/w
web/        wp-cli.yml
root@liberty vhosts/bedrock$ ls -la current/web/
total 16
drwxr-xr-x 4 deploy deploy   61 Jul 26 20:35 .
drwxr-xr-x 7 deploy deploy 4096 Jul 26 20:35 ..
drwxr-xr-x 5 deploy deploy   64 Jul 26 20:35 app
-rw-r--r-- 1 deploy deploy  125 Jul 26 19:27 index.php
drwxr-xr-x 5 deploy deploy 4096 Jul 26 20:35 wp
-rw-r--r-- 1 deploy deploy  502 Jul 26 19:27 wp-config.php

.htaccess should be placed in current/web/ right? It’s where WP/Apache2 expects it to be. Localy (on the dev host which deploys) where should this file be? In the root, like .env, thanks?

It’s all about not losing .htaccess on each deploy, and it should not be in git cause each environment handles it for itself.

Try this:

set :linked_files, %w{.env web/.htaccess}

and move .htaccess accordingly

1 Like

seems fine:

root@liberty vhosts/bedrock$ ls -la current/web/
total 16
drwxr-xr-x 4 deploy deploy   77 Jul 26 21:25 .
drwxr-xr-x 7 deploy deploy 4096 Jul 26 21:24 ..
drwxr-xr-x 5 deploy deploy   64 Jul 26 21:25 app
lrwxrwxrwx 1 deploy deploy   44 Jul 26 21:24 .htaccess -> /var/www/vhosts/bedrock/shared/web/.htaccess
-rw-r--r-- 1 deploy deploy  125 Jul 26 19:27 index.php
drwxr-xr-x 5 deploy deploy 4096 Jul 26 21:25 wp
-rw-r--r-- 1 deploy deploy  502 Jul 26 19:27 wp-config.php

now I try to modify .htaccess from WP, re-deploy and check if data is still there.
Thanks @etc I let you know

after deploy:

root@liberty vhosts/bedrock$ less current/web/.htaccess

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    
    # END WordPress

so all seems OK, thanks, great! I check staging now, should work the same.

Added a note about this in the default deploy.rb file: https://github.com/roots/bedrock/blob/master/config/deploy.rb

@swalkinshaw perfect, thanks. I think this is useful to most Apache2 users out there. After deploy to staging and production I now have:

% vhosts/bedrock$ find . -name .htaccess -exec ls -la {} \;
-rw-rw-r-- 1 deploy www-data 236 Jul 27 10:09 ./shared/web/.htaccess
lrwxrwxrwx 1 deploy deploy 44 Jul 26 21:24 ./releases/20140726192459/web/.htaccess -> /var/www/vhosts/bedrock/shared/web/.htaccess
lrwxrwxrwx 1 deploy deploy 44 Jul 26 21:28 ./releases/20140726192848/web/.htaccess -> /var/www/vhosts/bedrock/shared/web/.htaccess
lrwxrwxrwx 1 deploy deploy 44 Jul 27 10:06 ./releases/20140727080630/web/.htaccess -> /var/www/vhosts/bedrock/shared/web/.htaccess
lrwxrwxrwx 1 deploy deploy 44 Jul 27 10:10 ./releases/20140727081003/web/.htaccess -> /var/www/vhosts/bedrock/shared/web/.htaccess

which seems quite OK to me, can you confirm? shared/web/.htaccess is touched by ansible during the first set up of a new vhost, I do the same with shared/.env but as template to be sure this file exists and is in the right place for new vhosts.

I’ve tested .htaccess adding a deny from all on the top and it works fine. Thanks @etc and @swalkinshaw!

P.S. I’m still getting a blank page when I view the stage or prod site but I think this must be something different now, is there away to print out what PHP does or if it throws errors? Cause Apache2 error log for the vhost does not give me any infos, thanks.

Found, DB_HOST was missing in .env, my fault;)

Just as note, also with DB_HOST in .env completely missing, the wp-admin backend was working anyway.

Yes that’s fine.

Although I think you could make the argument that .htaccess should be checked into your Git repo. Shared dirs/files are for things that should persist across deploys also meaning that nothing about them is release specific. A .htaccess file could easily be release/deploy specific and if you wanted to rollback a deploy there’s a chance something in the latest .htaccess could conflict (not work) with older code.

1 Like

For me at least, .htaccess rules are distinct between environments, not necessarily releases/deploy. It’s really context specific. I’ve used projects I keep the .htaccess in VCS and others where I create on in each environment. On some larger projects, I actually pull in an .htaccess from a gist as part of the server prep scripts.

Wouldn’t it make more sense to write a script that will update the .htaccess as part of deployment routine? Something similar to Rail’s migrations?

Good point. It really depends on the situation.

I’m not sure it’s worth abstracting out the .htaccess file into some sort of “migrations”. Completely different from a DB since there’s no hard schema and it’s just plain text code as well.