Toon posts:

Opzet van staging omgeving CMS

Pagina: 1
Acties:

Onderwerpen

In een door ons ontwikkeld cms lopen we tegen een probleem aan: alle aanpassingen binnen het cms zijn direct doorgevoerd op een live omgeving. Dat is niet altijd wenselijk. Grote veranderingen aan de site wil je soms eerst netjes aanmaken, laten controleren door een verantwoordelijke om vervolgens het geheel in een keer te publiceren.

Er zijn verschillende bestaande mogelijkheden, maar nooit helemaal toepasbaar op bovenstaand probleem:
  1. Gebruik maken van versioning: versie x op productie en y op staging. Problemen: hoe werk je met ongepubliceerde content & hoe ga je om met wijzigingen in je pagina-boomstructuur? (NB. nested set bij ons)
  2. Gebruik maken van publicatie-data: pas live zetten op datum x. Probleem: dit zie je vaak bij ongepubliceerde content, maar wat doe je met wijzigingen in content?
  3. Twee databases: op basis van domain/url je database selecteren. Probleem: niet alles moet je staging/live splitsen. Users & gebruikersgroepen zijn hetzelfde, ook het permissiesysteem moet juist overkoepelend zijn. Je wilt liever niet data gaan overhevelen/synchroniseren.
Ik heb geen andere opties meer :p Hoe kan je dit voor elkaar krijgen? Liefst wil je zelfs per-user een snapshot kunnen ontwikkelen en live zetten. Hierdoor kan user A werken aan een grote overhaul en user B ondertussen wel content blijven publiceren. Maar misschien maakt dat het systeem zodanig ingewikkeld dat zoiets beter achterwege kan blijven...

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Een staging omgeving (of in ieder gevel een preview mode) is een must have tegenwoordig.

Hoe ziet je publish model eruit? Compleet disconnected van de backend? Kan je daar iets meer over vertellen?

Sundown Circus

RedRose schreef op dinsdag 21 juni 2011 @ 12:13:
Hoe ziet je publish model eruit? Compleet disconnected van de backend? Kan je daar iets meer over vertellen?
Wat bedoel je hiermee? Het cms is een php, op Zend Framework gebaseerde applicatie. In principe is er geen publish model, datgene wat juist nu wel wenselijk is :p

Op dit moment is er een directe koppeling met wat je in je formulier opstuurt (vanuit het cms) en wat er wordt weggeschreven in de database. Het is dus meteen zichtbaar voor bezoekers (een preview mode kan helpen, maar is nog geen oplossing voor bovenstaand probleem). Door nieuwe ontwikkelingen* willen we ons bestaande systeem omschrijven, meteen rekening houdend met een staging en live omgeving.

*) Doctrine2, php5.3 & introductie 5.4, nieuw Zend Framework 2, nieuwe ervaringen in gebruik van ons systeeem

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Ok, in dat geval zou ik een heel simpel publish model maken om mee te beginnen. Je zou je content metadata kunnen meegeven met een waarde waar die content is gepubliceerd, bijvoorbeeld "Staging / Live". Dan kan je daar je invoer formulier mee uitbreiden (of een extra "Publish" formuliertje er bij hangen). Op de voorkant haal je dan alleen je content op per "publish target". Dus bijvoorbeeld:

live.site.com => alle content die geflagged is als: "Live" en stating.site.com => content geflagged met "Staging".

Eventueel kan je dan later dit uitbreiden met scheduled publishing etc. Vergeet ook niet om content te kunnen "Unpublishen" ;)

Sundown Circus

Interessante gedachte om het vanuit een metadata perspectief te bekijken. In weze stel je versioning voor met een state voor elke versie, die zowel "staging" als "live" kan zijn.

Je kan hiermee dan nieuwe content maken die slechts versies heeft in staging state en dus niet op live staat. Echter, wat doe je met wijzigingen in een paginastructuur? Je gaat reorganiseren en wilt de complete sitemap omgooien. Dat wil je uiteraard pas publiceren wanneer je de sitemap weer op orde hebt en de nieuwe content is geschreven. Je zal dan toch op een of andere manier een state van entries in een nested set (of MPTT) moeten bijhouden?

  • Priet
  • Registratie: Januari 2001
  • Laatst online: 14:46

Priet

To boldly do what no one has..

Gekke gedachte: wat als je een mirror omgeving maakt? Wannneer de mirror OK bevonden is sync je deze terug naar de live omgeving.

Probleem: tussentijdse wijzigingen in de live omgeving zullen dan verwijderd worden...

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

mithras schreef op woensdag 22 juni 2011 @ 10:12:
Interessante gedachte om het vanuit een metadata perspectief te bekijken. In weze stel je versioning voor met een state voor elke versie, die zowel "staging" als "live" kan zijn.

Je kan hiermee dan nieuwe content maken die slechts versies heeft in staging state en dus niet op live staat. Echter, wat doe je met wijzigingen in een paginastructuur? Je gaat reorganiseren en wilt de complete sitemap omgooien. Dat wil je uiteraard pas publiceren wanneer je de sitemap weer op orde hebt en de nieuwe content is geschreven. Je zal dan toch op een of andere manier een state van entries in een nested set (of MPTT) moeten bijhouden?
Veel hangt af van je content model en hoe je je structuur bijhoudt / aanbrengt, dus daar kan ik niet zoveel over zeggen. In ieder geval zie ik versioning niet als iets dat gelijk staat aan een publish state. Een bepaalde versie heeft een bepaalde publish state, maar de twee zijn niet afhankelijk van elkaar. Meerdere versies kunnen dezelfde publish state hebben en je hoeft niet per se een nieuwe versie te creeeren als de publish state verandert.

Als je MPTT gebruikt zou je kunnen overwegen om of 2 tables te gebruiken (als je je staging / live publish targets wil hardcoden) of je zou gewoon een extra veld in je table kunnen zetten met een flag voor elke publish state. Als je dan van staging naar live wil publishen, kan je dat per individuele node doen, of per hele table. Maar let op: dat hangt er van af hoe je je structuur koppelt aan content (pages / entries). In principe is het het best om content zoveel mogelijk te scheiden van structuur en die loose te koppelen vanuit de content. Een ander principe is om met 'single source' content te blijven werken in verschillende omgevingen (staging / live) en afhankelijk van hoe je je structuur koppelt aan je content, zou dit mogelijk moeten blijven.
Priet schreef op woensdag 22 juni 2011 @ 12:37:
Gekke gedachte: wat als je een mirror omgeving maakt? Wannneer de mirror OK bevonden is sync je deze terug naar de live omgeving.

Probleem: tussentijdse wijzigingen in de live omgeving zullen dan verwijderd worden...
Das een gekke gedachte. :) Het is een rommelige manier van werken en laat zien dat er niet nagedacht is over een wat meer sophisticated mechanisme om dit te doen. Het is ook totaal niet gebruikersvriendelijk en kan nogal wat foute content opleveren. Je weet nooit wanneer een staging omgeving 100% klaar is om live te gaan en als dat wel zo is, kan iemand tussentijds natuurlijk gewoon op de staging omgeving blijven werken met als gevolg dat er test content op de live omgeving staat. En zoals je zelf zegt: atomaire updates zijn dan gewoon niet mogelijk.

Sundown Circus


  • Anoniem: 241683
  • Registratie: November 2007
  • Niet online
mithras schreef op woensdag 22 juni 2011 @ 10:12:
Interessante gedachte om het vanuit een metadata perspectief te bekijken. In weze stel je versioning voor met een state voor elke versie, die zowel "staging" als "live" kan zijn.

Je kan hiermee dan nieuwe content maken die slechts versies heeft in staging state en dus niet op live staat. Echter, wat doe je met wijzigingen in een paginastructuur? Je gaat reorganiseren en wilt de complete sitemap omgooien. Dat wil je uiteraard pas publiceren wanneer je de sitemap weer op orde hebt en de nieuwe content is geschreven. Je zal dan toch op een of andere manier een state van entries in een nested set (of MPTT) moeten bijhouden?
Je zou dit ook als een soort van queuetabel met acties kunnen toepassen. Dus dat je met acties werkt die op een bepaald tijdstip getriggerd worden. Dit betekent wel dat je dus de logica wel goed gescheiden moet hebben van je views.

VB van een actie:
Page/changeTitle Nieuwe titel 23-07-2011 12:12:!2


Zou alleen nog niet weten hoe dit makkelijk op te slaan is :+. Maar dan ben je qua pagina verandering wel iets flexibeler.

[Voor 3% gewijzigd door Anoniem: 241683 op 22-06-2011 15:41. Reden: Verduidelijking]


  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Even voor de begripsvorming: wat wil je nu versionen, de code of de content?

https://oneerlijkewoz.nl
I have these thoughts / so often I ought / to replace that slot / with what I once bought / 'cause somebody stole my car radio / and now I just sit in silence


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 20:28

mulder

ik spuug op het trottoir

With ^^, het gaat toch alleen om code, wat maak het uit als je acceptatieomgeving een andere database er achter heeft hangen?

oogjes open, snaveltjes dicht


  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Als ik het verhaal nog eens zo doorlees lijkt het toch om de content te gaan. Je zit natuurlijk met het dilemma dat je eigenlijk geen aparte omgeving wil, want als gebruiker A bezig is met een nieuwe menustructuur op staging en gebruiker B is ondertussen leuk artikelen aan het toevoegen aan de productiedatabase, dan kun je dus niet de database van staging naar productie zetten als gebruiker A klaar is.

Ik denk dat je in dat geval toch niet ontkomt aan een staging-vlaggetje, waar je in iedere query dan rekening mee moet houden. Het kan in dat geval wel op dezelfde codebase en database.

https://oneerlijkewoz.nl
I have these thoughts / so often I ought / to replace that slot / with what I once bought / 'cause somebody stole my car radio / and now I just sit in silence


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 02-06 11:16
Content: Dit wil je in je software, dus bijvoorbeeld versioned records waarvan je 1 versie op public kan zetten.

Hier heb je inderdaad 2 onderdelen: 1. Een specifiek record, een tekst die je wijzigt bijvoorbeeld. 2. Een structuur wijziging.

Voor 1 is het simpel, gewoon versie records bijhouden.
Voor 2 hangt het heel erg van je applicatie af. Als je het over een paginaboom hebt zou je kunnen overwegen om een kopie van de boom te maken, deze aan te passen en deze vervolgens te publiceren. Dit soort zaken worden al heel snel complex, vraag je af of je niet beter punt 1 + de onderstaande punten aan kan pakken.

Code: Hiervoor zijn voldoende standaarden, denk aan versiebeheer met GIT, Subversion etc. Branches is interessant op dit vlak.

Database: Migrations zijn het meest eenvoudig, database wijzigingen voer je dus nooit direct uit maar script je in migraties. Op het moment dat de nieuwe branche van software live gaat run je dat script. Zie bijvoorbeeld: http://guides.rubyonrails.org/migrations.html als voorbeeld.

Code zal toch niet werken zonder de juiste database structuur dus die migraties horen bij software versies.

In migraties kan je ook content migraties doen, bijvoorbeeld: Een veld wat nu 0,55 bevat kan je splitsen naar veld 1 = 0 veld 2 = 55 etc. Ook je migratie naar versioned records doe je op deze manier.
Lange post, eerst reacties op posts, daarna uitleg over ons systeem, tot slot weer eigen plannetjes. Voor TL:DR: klik hier ;)
Excuses voor het lange wachten. Ik ben naast ondernemer nog student en heb ook tentamens te maken :|
Priet schreef op woensdag 22 juni 2011 @ 12:37:
Gekke gedachte: wat als je een mirror omgeving maakt? Wannneer de mirror OK bevonden is sync je deze terug naar de live omgeving.
Dit is eigenlijk optie #3 uit mijn TS, met bijbehorende problemen. Het lijkt me ook erg lastig om dit goed bij te houden.
RedRose schreef op woensdag 22 juni 2011 @ 13:36:
[...]

Veel hangt af van je content model en hoe je je structuur bijhoudt / aanbrengt, dus daar kan ik niet zoveel over zeggen.
Oké, zie onderaan mijn post eea over onze opzet van het CMS. Wellicht dat het verheldert wat ik nu precies zoek.
In ieder geval zie ik versioning niet als iets dat gelijk staat aan een publish state. Een bepaalde versie heeft een bepaalde publish state, maar de twee zijn niet afhankelijk van elkaar. Meerdere versies kunnen dezelfde publish state hebben en je hoeft niet per se een nieuwe versie te creeeren als de publish state verandert.
Klopt. Mijn post was meer bedoeld dat ik state + version beide zag als meta-data, niet dat beide onderdelen een directe, onderlinge koppeling hebben; meer vanuit het idee dat beide aanwezig zijn en gekoppeld aan een stukje content.
Anoniem: 241683 schreef op woensdag 22 juni 2011 @ 15:39:
[...]

Zou alleen nog niet weten hoe dit makkelijk op te slaan is :+. Maar dan ben je qua pagina verandering wel iets flexibeler.
Ik denk dat je hier de spijker op de kop slaat ;) Het is zeker een goed idee om met diff te werken, maar je zal ook een staging omgeving met de goede prestaties willen zien. Je moet dan niet elke keer een heel diff doorlopen en parsen.
CodeCaster schreef op woensdag 22 juni 2011 @ 15:45:
Even voor de begripsvorming: wat wil je nu versionen, de code of de content?
Het gaat om content :) De code is nog relatief simpel, met versioning systemen en een goede deployment strategie ben je er wel. Daar is ook juist veel over te vinden: ik open dit topic omdat ik bar weinig informatie kon vinden over versioning van content in cms systemen en een productie + volledige preview omgeving.
djluc schreef op vrijdag 24 juni 2011 @ 12:21:
Content: Dit wil je in je software, dus bijvoorbeeld versioned records waarvan je 1 versie op public kan zetten.

Hier heb je inderdaad 2 onderdelen: 1. Een specifiek record, een tekst die je wijzigt bijvoorbeeld. 2. Een structuur wijziging.

Voor 1 is het simpel, gewoon versie records bijhouden.
Voor 2 hangt het heel erg van je applicatie af. Als je het over een paginaboom hebt zou je kunnen overwegen om een kopie van de boom te maken, deze aan te passen en deze vervolgens te publiceren. Dit soort zaken worden al heel snel complex, vraag je af of je niet beter punt 1 + de onderstaande punten aan kan pakken.
Het managen van losse records, ben ik ondertussen achter, is inderdaad nog relatief simpel. Ik ben nu verder aan het denken of het mogelijk is een gehele sitemap (pagina-structuur, indeling, boom; nieuwe pagina's maken, oude verwijderen etc) staging te veranderen en ineens live te publiceren. Jouw #2 dus. Met het kopiëren van de boom zat ik ook te spelen, meer info onderaan :)
Code / Database:
Hier gaat het wel mee lukken. Versioning zijn we mee bezig (ie, svn etc gebruiken we al vanaf start, we werken nu al aan een deployment/update strategie voor dit probleem.

Architectuur

Hier een stukje uitleg over onze opbouw. Allereerst pagina's:
Page:
  id: int
  type: varchar
  uri: varchar
  lft: int
  rgt: int
Hierbij is de paginaboom gebouwd met een MPTT/Nested set methode. De pagina's hebben elk een bepaald type, die we achterhalen via een xml bestand:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<pages>
    <page type="standard">
        <modules>
            <module name="text">
                <!-- Hier wat module settings-->
            </module>
        </modules>
    </page>

    <page type="blog" route=":action/:id/:title/*">
        <modules>
            <module name="blog">
                <!-- Hier wat module settings-->
            </module>
        </modules>
    </page>

    <page type="contact">
        <modules>
            <module name="text">
                <!-- Hier wat module settings-->
            </module>
            <module name="contact">
               <!-- Hier wat module settings-->
            </module>
        </modules>
    </page>
</pages>
Het type veld uit de db verwijst hier naar een van de type pagina's. Deze geeft een koppeling tussen modules ("content providers") en pagina's. In de module settings staat hoe deze koppeling tot stand komt. Verder bestaat er nml nog een tabel:
PageParams:
  id: int
  page_id: int
  name: varchar
  value: varchar
Zo vraagt de pagina "standard" om een content-id. De pagina A koppelt zich aan content X door in de params te vermelden dat page_id A een naam content-id heeft met value X.

Tweede voorbeeld: de pagina "twocolumn" (niet in XML weergegeven) bevat tweemaal de "text" module, een keer met een left-id, een keer een right-id. Teksten Y en Z koppelen aan pagina B door twee entries in de params op te nemen. Een keer een page=B, name=left-id, value=X, de tweede keer een page=B, name=right-id, value=Z.

Deze methode koppelt dus de losse content aan de sitemap, waardoor we nog relatief eenvoudig content kunnen versionen los van de pagina's zelf.

En dan...!?

Als je met de gegeven reacties wat gedachte-experimenten gaat doen kom je wel tot een mogelijkheid :)

Allereerst is dus content te managen door versioning toe te passen en daarbij een state te introduceren. Dit is nog makkelijk te doen voor gewone tekstblokjes. Bij Doctrine zullen we versionable licht moeten aanpassen om ook een state (staging|live) op te nemen. Hoe we het verder precies uitwerken moet ik nog even kijken.

Ten tweede de paginastructuur. Voor Doctrine's Nested Set is het mogelijk meerdere sets in een tabel op te nemen, met behulp van een root_id. Hierdoor kunnen twee boomstructuren binnen een site staan: een voor live, een voor staging.

Het laatste denkwerk wat dan nog verricht moet worden is hoe de parameter-mapping van pagina <> content bijgehouden moet worden. Het is waarschijnlijk het meest eenvoudige om te kiezen voor een oplossing waar:
1) als in een van beide bomen een pagina voorkomt, staat de entry al/nog in de params tabel (bv. bij het verwijderen of aanmaken van een pagina)
2) als in beide bomen de pagina niet meer voorkomt, wordt de entry verwijderd (bv bij verwijderen van pagina op staging en vervolgens staging publiceren naar live).

Zit ik zo een beetje op het juiste pad?
Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee