How to use php deployer? - php-deployer

I want to deploy a PHP project with Deployer.
I have this code:
task('deploy', [
'deploy:prepare',
'deploy:lock',
'deploy:release',
'deploy:update_code',
'deploy:shared',
'deploy:writable',
'deploy:vendors',
'deploy:clear_paths',
'deploy:symlink',
'deploy:unlock',
'cleanup',
'success'
]);
I want to deploy on a preview.domain.com and run acceptance tests.
After that I want to read the report.xml.
When everything is clear I want to link to the current folder.
How can I do that?

To do the deploy you have to configurate your host in the deploy.php file (in the root of your project), like:
host('domain.com')
->stage('production')
->set('deploy_path', '/var/www/domain.com');
you can create task that you can hook after some other task, like:
task('my_task', function () {
<code>
});
after('deploy', 'my_task');
with this tools you can do everything
To execute the deploy use the comand:
dep deploy domain.com

Related

Change Symfony public directory to fit website

I want to create directory called 'app' in my public directory and make it root of my application instead of 'public' dir. What should I do except adding:
"extra": {
"public-dir": "public/app/",
...
}
I got a vue app that should be placed in 'app' directory and a wordpress instance that will be placed in 'public' directory so when I enter www.mywebsite.com I get wordpress website, and when I enter www.mywebsite.com/app I got my symfony/vue app.
So far I edited my webpack.config.js with:
.setOutputPath("public/app/build/")
.setPublicPath("/build/")
And it think it works on dev env but in prod env when i hit www.mywebsite.com/app I got:
<script src="/build/app.js"></script>
Which wrongly points to: www.mywebsite.com/build/app.js instead of www.mywebsite.com/app/build/app.js
But whenever I change webpack.config.js to:
.setOutputPath("public/app/build/")
.setPublicPath("/app/build/")
It works on production but not on dev env.
What am I doing wrong here?
Going by your problem description I'm assuming your application is accessed at / in your dev environment, but /app in your prod environment as explained. So you have to take that into account when calling .setConfigPath() by checking the environment you are running in your webpack config:
.setPublicPath(Encore.isProduction() ? '/app/build' : '/build')

Firebase Hosting: Function not working with ServerMiddleware (Vue/ Nuxt)

I am building a project that utilises ServerMiddleware to render some pages client side only (I can't find another way of getting this working well without ServerMiddleware. Problems on refreshing pages and so on...)
The problem: Unfortunately every time I try and deploy to my Firebase Function through 'firebase deploy' I get an error:
Error: Cannot find module '~/serverMiddleware/selectiveSSR.js'
The function builds OK if I exclude the following line. Nuxt/ Vue is not including ~/serverMiddleware/ as part of its build as far as I can see.
Here is the code in nuxt.config.js to reference my serverMiddleware:
serverMiddleware: ['~/serverMiddleware/selectiveSSR.js']
Adding either the directory or path (as above) to the file itself within Build in nuxt.config.js does not help either. Maybe I am doing it wrong?
Everything works perfectly when testing (Not building) locally.
Any ideas on how I can resolve this please?
Thanks!
Ok so for anyone else who hits this, here is how I got around it.
Firstly, I don't know if this is the fault of Firebase Hosting or Nuxt (I would guess Nuxt but I stand to be corrected), but here is what to do....
1) Remove any reference to ServerMiddleware from nuxt.config.js
2) Add the following to nuxt.config.js
modules: [
'~/local-modules/your-module-name'
],
3) Create directory ~/local-modules/your-module-name in your project root
4) In the new directory, create a package.json:
{
"name": "your-module-name",
"version": "1.0.0"
}
and index.js - key thing, this.addServerMiddleware allows you to call middleware server-side
module.exports = function(moduleOptions) {
this.addServerMiddleware('~/serverMiddleware/')
}
5) Create directory ~/serverMiddleware
6) Add your middleware function to index.js in the new directory:
export default function(req, res, next) {
// YOUR CODE
next() // Always end with next()!
}
7) Update package.json with your new local module under "dependencies":
"your-module-name": "file:./local-modules/your-module-name"
Don't forget you need to do this within the functions directory too or Firebase will complain it can't find your new module

Hosting Symfony 4 app with EasyDeployBundle on server without /usr/local/bin/composer

For a Symfony 4 app I have chosen a Web Cloud plan from the hosting provider OVH.
For the deployment I have decided to use the EasyDeployBundle which looks very promising. This is my config file:
<?php
use EasyCorp\Bundle\EasyDeployBundle\Deployer\DefaultDeployer;
return new class extends DefaultDeployer
{
public function configure()
{
return $this->getConfigBuilder()
->server('ovh')
->deployDir('directory/path/at/server')
->repositoryUrl('git#github.com:foo/bar.git')
->repositoryBranch('master')
;
}
}
I have .ssh/config file with the following entry:
Host ovh
Hostname sshcloud.foobar.hosting.ovh.net
Port 12345
User foobar
Note: all values are dummies, just for illustrational purposes.
When I run:
php bin/console deploy --dry-run -v
everything goes fine, but when I actually try to deploy I get the following error:
The command "ssh ovh 'which /usr/local/bin/composer'" failed.
The problem is that I have no write-access to the directory /usr/local/bin/ on the server. The composer.phar is in my home directory and I can't move it to the provisioned destination.
Is there any possibility to tell EasyDeployBundle to look for composer in another directory?
I should really read the manuals, in particular when I'm linking them in my question.
There is a method remoteComposerBinaryPath that accepts custom path to composer. I have amended the method configure like this:
public function configure()
{
return $this->getConfigBuilder()
->server('ovh')
->deployDir('directory/path/at/server')
->repositoryUrl('git#github.com:foo/bar.git')
->repositoryBranch('master')
->remoteComposerBinaryPath('composer.phar')
;
}
On the server I created .bashrc in my home folder and added the line:
export PATH=$PATH:/home/foobar
and now the deployment is passing this hurdle.
I have now another problem, but at least this one is solved and maybe the answer can help other people too.

Where to put secret keys in Netlify? [duplicate]

I'm trying to set an environment variable for an API key that I don't want in my code. My source javascript looks something like this :
.get(`http://api-url-and-parameters&api-key=${process.env.API_KEY}`)
I'm using webpack and the package dotenv-webpack https://www.npmjs.com/package/dotenv-webpack to set API_KEY in a gitignored .env file and it's all running fine on my local. I'd like to also be able to set that variable when deploying through Netlify, I've tried adding it through to GUI to the 'build environment variables', and also to set it directly in the build command, but without success.
Any idea what might be the issue ?
WARNING: If this is a secret key, you will not want to expose this environment variable value in any bundle that gets returned to the client. It should only be used by your build scripts to be used to create your content during build.
Issue
dotenv-webpack expects there to be a .env file to load in your variables during the webpack build of your bundle. When the repository is checked out by Netlify, the .env does not exist because for good reason it is in .gitignore.
Solution
Store your API_KEY in the Netlify build environment variables and build the .env using a script prior to running the build command.
scripts/create-env.js
const fs = require('fs')
fs.writeFileSync('./.env', `API_KEY=${process.env.API_KEY}\n`)
Run the script as part of your build
node ./scripts/create-env.js && <your_existing_webpack_build_command>
Caveats & Recommendations
Do not use this method with a public facing repository [open] because any PR or branch deploy could create a simple script into your code to expose the API_KEY
The example script above is for simplicity so, make any script you use be able to error out with a code other than 0 so if the script fails the deploy will fail.
You can set Dotenv-webpack to load system environment variables as well as those you have declared in your .env file by doing the following:
plugins: [
new Dotenv({
systemvars: true
})
]
I.e Setting the systemvars attribute of your webpack dotenv plugin to true.
Note that system environment variables with the same name will overwrite those defined in your .env file.
Source: https://www.npmjs.com/package/dotenv-webpack#properties
if you go to corresponding site's settings in Netlify, under build&deploy you can find a section called environment variables you can easily add your environment variables from there. if you add MY_API_KEY variable to environment variables you will be able to access it inside your project via process.env.MY_API_KEY.
If you're using Nuxt JS there is a more "straight forward" approach.
Just edit the nuxt.config.js like so:
module.exports = {
env: {
GOOGLE_API_KEY: process.env.GOOGLE_API_KEY
},
// ...
Then add the GOOGLE_API_KEY to Netlify through the build environment variables as usual.
Credit goes to yann-linn and his answer on github.
What you can also do is also to define a global constant in Webpack. Netlify environment variables defined in UI will work with it. You don't need dotenv or dotenv-webpack.
webpack.config.js
const webpack = require("webpack");
module.exports = {
plugins: [
new webpack.DefinePlugin({
"process.env.API_KEY": JSON.stringify(process.env.API_KEY)
}),
]
}
However again, of course you shouldn't do it just inputting enviornmental variables in the frontend if your API key is confidential and project public. The API key will appear in the source code of the website and will be easily accessible for everyone visiting it. Lambda function would be a better option.
You can use the Netlify's config file also ...
You can find documentation here.
Also i wanted to have the same ENV variables with with different values per branch/environment.
This workaround worked for me:
Create a netlify.toml file like:
[build]
NUXT_ENV_BASE_API = "/api"
NUXT_ENV_HOST_DOMAIN = "https://your-domain.gr"
[context.branch-deploy]
environment = { NUXT_ENV_BASE_API = "/dev-api", NUXT_ENV_HOST_DOMAIN = "https://dev.your-domain.gr" }
[context.production]
environment = { NUXT_ENV_BASE_API = "/api", NUXT_ENV_HOST_DOMAIN = "https://your-domain.gr" }
And deploy in Netlify ...

Meteor: how to load different files based on CLI parameter?

In my Meteor (1.2) app I've separated files for development and production
e.g.
client/lib/appVars.config.PROD.js
client/lib/appVars.config.CONFIG.js
Ideally the "twin" files have the same variables, functions etc. with little differences but (global) variables and functions which are common to debug and production have the same name.
Is there a way to call meteor run with a command line parameter DEBUG_MODE = true | false so that I cad load either one or the other file, depending on the current mode (debug, production)?
Set different environmental variables and run via CLI with meteor run --settings settings.json
Then you just need a development and production (and staging?) settings.json
Example of a settings file:
{
"awsBucket": "my-example-staging",
"awsAccessKeyId": "AABBCCddEEff12123131",
"awsSecretKey": "AABBCCddEEff12123131+AABBCCddEEff12123131",
"public": {
"awsBucketUrl": "https://my-meteor-example.s3.amazonaws.com",
"environment": "staging"
},
"googleApiKey": "AABBCCddEEff12123131"
}
EDIT ADD:
To access your environmental keys, just select
Meteor.settings.awsBucket
Security Update (thanks Dave Weldon)
See https://docs.meteor.com/#/full/structuringyourapp
Re production vs development, you should have two settings.json files, the standard one for production (.config/settings.json) and a development one (.config/development/config.json) and when you boot outside of production you boot meteor --settings .config/development/settings.json
Re client side, note that if you make the key public e.g.
{
"service_id":"...",
"service_secret":"...",
"public":{
"service_name":"..."
}
}
Then only Meteor.settings.public.service_name will be accessible on the client

Resources