As I’ve got a few minutes now I’m just trying to get started and remember what I did to get my Surf Deployment up and running at Mittwald.
First of all I’ll describe my environment:
for a lack of different servers I’ve set up three different “Projects/URLs” at Mittwald.
- a test-“server” where the current develop branch is deployed. This is just used to test my latest developments by me and my colleague.
- a staging-“server” where the latest release branch is deployed. This is used to do final tests by ourselves as we are in this case our “customers”. So if both of us have tested everything that needs to be tested manually there. After this has been done it’s deployed to the live server.
- live server where we’re deploying the latest master branch
In general as this should be about a best practice regarding different hosters I’ll now start to describe what is needed to deploy things to Mittwald.
In general one thing that is not so easy currently is using Symlinks at Mittwald. The resource publishing doesn’t work without problems the default way.
The resource publishing only worked for me if I use following settings.
They are deployed together with the Settings.yaml via Surf.
For TYPO3 Flow 2.x
TYPO3:
Flow:
resource:
publishing:
fileSystem:
mirrorMode: copy
For Flow 3.x
TYPO3:
Flow:
# Definition of the basic resource publication targets.
resource:
targets:
# Target for publishing static resources to the local web directory
localWebDirectoryStaticResourcesTarget:
target: 'TYPO3\Flow\Resource\Target\FileSystemTarget'
targetOptions:
path: '%FLOW_PATH_WEB%_Resources/Static/Packages/'
baseUri: '_Resources/Static/Packages/'
localWebDirectoryPersistentResourcesTarget:
target: 'TYPO3\Flow\Resource\Target\FileSystemTarget'
targetOptions:
path: '%FLOW_PATH_WEB%_Resources/Persistent/'
baseUri: '_Resources/Persistent/'
Below you find my example Surf Deployment configuration that I’m using for Mittwald.
One Package that was really helpful is Famelo.SharedHosting by mneuhaus because it does all necessary patches of flow.bat and flow e.g.
If you want to have a more detailed look - here’s the github-Repository: https://github.com/mneuhaus/Famelo.Surf.SharedHosting
I’m also using rsync as transferMethod because composer caused some problems and I found it a lot easier to do everything locally and copy the whole thing to the server via rsync afterwards. That way it’s also easier to add new nodes because you have to care less about the target server configuration.
At least that’s what I found out - if anyone thinks different I’d be happy to discuss it.
<?php
use \TYPO3\Surf\Domain\Model\Node;
use \TYPO3\Surf\Domain\Model\SimpleWorkflow;
$application = new \Famelo\Surf\SharedHosting\Application\Flow();
$workflow = new SimpleWorkflow();
/* ---------------------------------------------------------------
*
* DEFINE GENERAL SETTINGS - Start
*
* ---------------------------------------------------------------
*/
// path where the Surf folders are created on the target servers
$application->setDeploymentPath('/html/passcreator-live');
$application->setOption('repositoryUrl', 'git@bitbucket.org:username/my.repository.git');
// checkout master branch
$application->setOption('branch', 'master');
// path to composer on the current machine
$application->setOption('composerCommandPath', '/usr/local/bin/composer');
$application->setOption('transferMethod', 'rsync');
$application->setOption('packageMethod', 'git');
$application->setOption('updateMethod', NULL);
$application->setOption('keepReleases', 3);
$application->setHosting('Mittwald');
/* ---------------------------------------------------------------
*
* DEFINE GENERAL SETTINGS - End
*
* ---------------------------------------------------------------
*/
/* ---------------------------------------------------------------
*
* DEFINE TARGET SERVER - Start
*
* ---------------------------------------------------------------
*/
$node = new Node('my-node-name');
$node->setHostname('passcreator.de');
$node->setOption('username', 'myUsername');
/* ---------------------------------------------------------------
*
* DEFINE TARGET SERVER - End
*
* ---------------------------------------------------------------
*/
/* ---------------------------------------------------------------
*
* CUSTOM COMMANDS - Start
* - add context and pkpass type to .htaccess file
* - flush cache
* - warmup cache
*
* ---------------------------------------------------------------
*/
// Add context and pkpass type to .htaccess
$editHtaccessCommandOptions = array(
'command' => 'echo -e "\nSetEnv FLOW_CONTEXT Production \n\nAddType application/vnd.apple.pkpass .pkpass\n\n" >> {releasePath}/Web/.htaccess'
);
$workflow->defineTask('brainswarm.passcreator:editHtaccess', 'typo3.surf:shell', $editHtaccessCommandOptions);
$workflow->addTask('brainswarm.passcreator:editHtaccess', 'finalize');
// flush cache after everything is ready
$workflow->defineTask('brainswarm.passcreator:cacheFlush',
'typo3.surf:shell',
array('command' => 'cd {releasePath} && FLOW_CONTEXT=Production ./flow flow:cache:flush')
);
// warmup cache to make everything prepared for go-live
$workflow->defineTask('brainswarm.passcreator:cacheWarmup',
'typo3.surf:shell',
array('command' => 'cd {releasePath} && FLOW_CONTEXT=Production ./flow flow:cache:warmup')
);
// add cache flush and warmup task to finalize stage because otherwise smoke tests won't be able to run.
$workflow->addTask(array(
'brainswarm.passcreator:cacheFlush',
'brainswarm.passcreator:cacheWarmup'
), 'finalize');
/* ---------------------------------------------------------------
*
* CUSTOM COMMANDS - End
*
* ---------------------------------------------------------------
*/
/* ---------------------------------------------------------------
*
* SMOKE TESTS - Start
*
* ---------------------------------------------------------------
*/
$smokeTestOptions = array(
'url' => 'http://portal-next.passcreator.de',
'remote' => TRUE,
'expectedStatus' => 200
);
$workflow->defineTask('brainswarm.passcreator:smoketest-startpage', 'typo3.surf:test:httptest', $smokeTestOptions);
$workflow->addTask('brainswarm.passcreator:smoketest-startpage', 'test', $application);
$smokeTestOptions = array(
'url' => 'http://portal-next.passcreator.de/login',
'remote' => TRUE,
'expectedStatus' => 200
);
$workflow->defineTask('brainswarm.passcreator:smoketest-login', 'typo3.surf:test:httptest', $smokeTestOptions);
$workflow->addTask('brainswarm.passcreator:smoketest-login', 'test', $application);
/* ---------------------------------------------------------------
*
* SMOKE TESTS - End
*
* ---------------------------------------------------------------
*/
$deployment->setWorkflow($workflow);
$application->addNode($node);
$deployment->addApplication($application);
?>
That’s what I have right here as I’m not at my normal work laptop right now.
If you think anything’s missing or should be explained in more detail or is plain wrong - just let me know 
One thing that I think could be explained better on the Surf page is how to get started with it for dummies like I was when I started with it. It took me some time to get to this setup.