<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://ulrik.co/feed.xml</id>
    <link href="https://ulrik.co/feed.xml"/>
    <title>ulrik.co</title>
    <updated>2026-02-08T16:50:12+00:00</updated>
    <entry>
        <title>Chat Control 2025 - eller totalitær overvågning?</title>
        <link rel="alternate" href="https://ulrik.co/posts/chat-control-2025-eller-totalitaer-overvagning/"/>
        <id>https://www.ulrik.co//posts/chat-control-2025-eller-totalitaer-overvagning/</id>
        <updated>2025-09-15T16:26:30+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p><a href="https://en.wikipedia.org/wiki/Regulation_to_Prevent_and_Combat_Child_Sexual_Abuse">CSAM</a> kaldes det egentlig - det er et forslag, der skal gøre det sikkert for børn &quot;online&quot;, men det minder i langt højere grad om masseovervågning af alle borgere og de &quot;beskeder&quot; de sender til hinanden.</p>
<p>Tanken er nobel nok, forhindre misbrug af børn - hvem vil ikke gerne støtte det?</p>
<p>Prisen? Total overvågning af alle beskeder (video, billede og tekst), sendt mellem os alle, via alle tjenester - krypterede eller ej.</p>
<p>Det virker da som en fair pris, gør det ikke? ... Ikke?? ... Nej, vel!</p>
<p>Så det de siger er, at for at fange potentielle børne-udnyttere, skal vi alle ca 450mil europæere have vores private kommunikation gennemgået - inden den forlader vores enheder.</p>
<p>En hage er, hvordan finder man noget i krypterede beskeder? Det gør man ikke....</p>
<p>Altså skal der lægges et lag ind imellem den rå besked og den krypterede der sendes til modtageren. - Men hvem er det så der skal lytte med i det lag før? Hvem skal vi betro vores hemmeligheder - legitime eller ej? Google og Apple? - dem der levere de fleste af vores lommekommunikationsenheder? Dem der allerede i dag har pligt til at udlevere data til den amerikanske stat, hvis spurgt?</p>
<p>Jeg er ikke jurist, ej heller er jeg politiker - men jeg er en bekymret borger, der ikke har lyst til at leve i et samfund, hvor vi alle er skyldige indtil andet er bevist.</p>
<p>Så jeg har skrevet til de af vores politikere der i dag står til at stemme for forslaget, eller ikke har taget stilling endnu. - <a href="https://fightchatcontrol.eu/">Du kan gøre det samme her</a>.</p>
<p>Jeg troede egentlig det var enden på den historie, men så skrev <a href="https://www.europarl.europa.eu/meps/en/257020/STINE_BOSSE/home">Stine Bosse</a> (eller i hvert fald hendes stab) tilbage.</p>
<blockquote>
<p>Kære Borger</p>
<p>Jeg tillader mig at svare på dansk.</p>
<p>Mange tak for din mail, og for at dele dine bekymringer om Europa-Kommissionens Child Sexual Abuse Material (CSAM)-forslag.</p>
<p>Jeg har fået rigtig mange henvendelser på netop dette område, og jeg tager det bestemt alvorligt, når vi lige om lidt går i gang med den politiske sæson i Bruxelles.</p>
<p>Moderaterne og den danske regering mener, at formålet med forslaget er rigtigt: At opdage og forebygge seksuelt misbrug af børn online. Desværre er det et stødt stigende problem i hele Europa. I 2023 var der over 36,2 millioner indberetninger om mistanke om seksuelt misbrug af børn online, hvilket var et historisk højt tal, og det skal vi simpelthen gøre noget ved.</p>
<p>Men jeg mener selvfølgelig samtidig, at det er vigtigt at finde den rette balance i teksten.</p>
<p>Vi skal være helt bevidste om, at overvågning både kan bruges til gode formål, ligesom det i den grad også kan misbruges - det skal vi tage alvorligt, og vi må ikke være naive i forhold til, hvad overvågning desværre kan bruges til politisk. I dag overvåges alle borgere for eksempel konstant af techgiganterne, hvilket jeg også kan se problemer i.</p>
<p>Når vi vil komme problemer med seksuelt misbrug af børn til livs, så skal vi sikre, at det sker på en ordentlig måde, hvor det stadig er muligt at beskytte privatlivsrettigheder. Som vi også har set det med GDPR, så har beskyttelsen af privatlivet og den enkelte borger gennem lang tid været en mærkesag i EU, og det skal det fortsætte med at være.</p>
<p>Jeg sidder ikke selv i nogle af de relevante udvalg, som skal arbejde med teksten, men jeg kan anbefale dig at følge min kollega MEP Hilde Vautmans, som forhandler forslaget på vegne af min gruppe Renew Europe.</p>
<p>Om processen fremadrettet: hvis de 27 EU-landenes regeringer kan blive enige om deres fælles tilgang til forslaget, vil forhandlinger om lovteksten (mellem Europa-Parlamentet og Rådet) starte som tidligst i oktober/november 2025.</p>
<p>Endnu en gang tak for at skrive og for at være engageret i debatten, det er altid godt, når borgerne holder øje, følger med og kommer med sine meninger.</p>
<p>De bedste hilsner,</p>
<p>Stine Bosse</p>
<p>Medlem af Europa-Parlamentet for Moderaterne</p>
</blockquote>
<p>Ok.. Tak, det var da rart at hører tilbage, problemet er bare at det er mere af samme pose. At vi lige får det med at techgiganterne også er et problem er lidt sjovt, set i lyset af at Google, Apple og Microsoft uden tvivl bliver en brik i det spil der bliver &quot;løsningen&quot; for at få scannet vores data.</p>
<p>Nu har jeg svaret.</p>
<blockquote>
<p>Hej Stine,</p>
<p>Den holder altså ikke.</p>
<p>Vi har heller ikke installeret kameraer i soveværelserne, for at forebygge partnervold eller overgreb.</p>
<p>Vi giver heller ikke bøder til trafikanter, fordi &quot;de muligvis kunne køre for stærkt&quot;.</p>
<p>Vi forbyder ikke rygning i det private rum, fordi det netop er privat.</p>
<p>Vi læser heller ikke private (eller offentlige personers) dagbøger og overstreger tekster vi er uenige med.</p>
<p>Det vi gør, er at overvåge og / eller indsamler data om mistænkte individer, ikke masseovervågning som dette er.</p>
<p>En sådan kontrol af hhv. billeder, video og tekst (alt efter hvordan man læser forslaget) skal altså &quot;scannes&quot; ud fra regler, men ude af kontekst - som man jo af gode grunde ikke kan have.</p>
<p>De regler tænker jeg heller ikke vil blive offentliggjort - men gennemsigtighed i sådan noget her er altså ret væsentlig, da alt i den her verden er kontekstafhængigt!</p>
<p>Sender jeg eks. et billede af min datter i bad (fordi det er sødt) til min kone er alt godt - men samme billede sendt til nogen andre ... Udfordringen her er, at en løsning aldrig vil kunne se forskel på min kones nummer og en eller anden random person.</p>
<p>Det virker helt hen i vejret - bare det at der i forslaget også står at politikere er undtaget ... for I er altid helt &quot;rene&quot; eller hvordan er det nu lige det er?</p>
<p>Det lyder mere som om I (Moderaterne og den danske regering) er ude på at opbygge systemer som mere minder om en totalitær værktøjer - og sidst jeg tjekkede, var Danmark (og EU) et demokratisk samfund og her hører sådan noget altså ikke hjemme!</p>
<p>Igen (og denne gang på dansk) så er jeg ikke modstander af, at vi skal forebygge misbrug af børn, men det her er alt for indgribende og altså ikke løsningen!</p>
<p>Mvh Ulrik</p>
</blockquote>
<p>Så må vi jo se om jeg hører mere, eller jeg nu er røget i kategorien over sølvparpirshatte der ikke skal bruges mere tid på. Kommer der nyt, skal jeg nok opdatere posten her.</p>
<p>Hvis du er interesseret i at læse mere, så er her noget at starte med.</p>
<ul>
<li><a href="https://fightchatcontrol.eu/">https://fightchatcontrol.eu/</a></li>
<li><a href="https://chatcontrol.dk/da/">https://chatcontrol.dk/da/</a></li>
<li><a href="https://radar.dk/holdning/dtu-eksperter-advarer-i-kronik-csam-forslag-vil-foere-til-uhoert-overvaagning-af-vores-private">https://radar.dk/holdning/dtu-eksperter-advarer-i-kronik-csam-forslag-vil-foere-til-uhoert-overvaagning-af-vores-private</a></li>
<li><a href="https://www.altinget.dk/digital/artikel/it-politisk-forening-hummelgaards-udsagn-om-chatkontrols-muligheder-kan-vaere-staerkt-vildledende">https://www.altinget.dk/digital/artikel/it-politisk-forening-hummelgaards-udsagn-om-chatkontrols-muligheder-kan-vaere-staerkt-vildledende</a></li>
<li><a href="https://stopscanningme.eu/en/">https://stopscanningme.eu/en/</a></li>
</ul>

            </div>
        </content>
    </entry>
    <entry>
        <title>The Last of Us - 12 år senere...</title>
        <link rel="alternate" href="https://ulrik.co/posts/the-last-of-us-12-ar-senere/"/>
        <id>https://www.ulrik.co//posts/the-last-of-us-12-ar-senere/</id>
        <updated>2025-06-05T19:16:55+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <img src="./assets/the-last-of-us.webp" title="The Last of Us poster." >
<p>Jeg har haft <a href="https://www.playstation.com/da-dk/games/the-last-of-us-part-i/" title="The Last of Us på playstation.com">The Last of Us</a> spillet liggende rigtig rigtig længe, først til PlayStation - og langt senere også til PC. Men... Jeg har ikke kunnet spille det, jeg er så pisse dårlig til jump scares og de der lyde især Clickers laver, nnngh - jeg kan dem altså ikke.</p>
<p>Så kom TV serien på MAX og jeg syntes alligevel at jeg ville gennemføre spillet <em>inden</em> jeg så serien - bare for at ha' en ordentlig reference.</p>
<p>Jeg fik startet på Part 1 .... shit det er et fedt spil, med en helt igennem fantastisk historie, lydside og gameplay - og så er det pisse flot, selv her i 2025.</p>
<p>Det er ikke så tit jeg lister i kælderen for at spille, og især ikke her i forsommeren, hvor vejret tit er til noget helt andet. Men damn, det har været svært at holde sig væk. Jeg har været helt væk i universet, og ret så investeret i karakterene.</p>
<p>Nu mange timere senere - så har jeg gennemført bådet Part 1 og Part 2 - og er nu fanget i en &quot;last of us blues&quot;, hvor jeg ikke rigtig ved hvad lejr jeg skal stå i - men til gengæld, så har jeg lyttet ret meget til <a href="https://youtu.be/-colBB5EvI8" title="Part 2 Covers playliste på Youtube">soundtracket</a> fra især Part 2.</p>
<p>Abby eller Ellie.</p>
<p>Hvem er skurken - ikke rigtig noget, men der er i hvert fald ingen tvivl om, at der ikke er nogen vindere her - og på den måde er det et meget uamerikansk spil. Ikke noget med happy endings. Kun hvor langt vi som mennesker er villige til at gå, tab - eller i hvert fald følelsen af det. Og hvad det koster at midste og at hævn meget sjældent er den rigtige løsning på noget.</p>
<p>Jeg tror ikke, jeg før har spillet noget med historie så godt fortalt og med så mange detaljer og nuancer - det er ret imponerende hvor godt det er lavet. Kæmpe cadeau til holdet hos <a href="https://www.naughtydog.com/">Naughty Dog</a> der har stykket det her sammen.</p>
<img src="./assets/the-last-of-us-complete.webp" title="The Last of Us, Ellie upside down." >
<p>Tak for gys, grin og gråd!</p>

            </div>
        </content>
    </entry>
    <entry>
        <title>Hvad er jeres onlinebudget?</title>
        <link rel="alternate" href="https://ulrik.co/posts/hvad-er-jeres-onlinebudget/"/>
        <id>https://www.ulrik.co//posts/hvad-er-jeres-onlinebudget/</id>
        <updated>2025-01-27T20:07:24+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Det er måske lidt et underligt spørgsmål, men her er det altså.</p>
<p>Jeg kunne godt tænke mig at høre hvad I bruger på &quot;online&quot; hver måned. Hvis ikke i kr/øre - så måske bare i hvilke tjenester I benytter jer af, for jeg syntes det er svært.</p>
<h2>Her abonnere vi pt. på</h2>
<ul>
<li><a href="https://dr.dk/">DR</a> (via skatten)</li>
<li><a href="https://www.zetland.dk/">Zetland</a></li>
<li><a href="https://taenk.dk/">Tænk</a></li>
<li><a href="https://play.tv2.dk/">TV2 Play</a></li>
<li><a href="https://netflix.com/">Netflix</a></li>
<li><a href="https://www.max.com/">HBO Max</a> - eller hvad de nu fortiden kalder sig.</li>
<li><a href="https://spotify.com/">Spotify</a></li>
<li><a href="https://mofibo.dk/">Mofibo</a></li>
</ul>
<p>Men. Er det bare mig der er bag ud? Skal jeg bare ta' mig sammen og skrive mig op til nogen flere abonnementer, eller hvad? Egentlig vil jeg gerne følge med flere steder, dog syntes jeg at de ca. 1000,-/mdr. vi allerede bruger er rigeligt - og guderne skal vide at SoMe ikke er det rigtige sted.</p>
<p>Det er jo ikke fordi man mangler noget at bruge sine penge på, priser på fødevarer og hvad der ellers skal til at holde et lille hus i gang er stigende - og det ser ikke ud til at det kommer til at falde lige foreløbig...</p>

            </div>
        </content>
    </entry>
    <entry>
        <title>Skal man nu gøre alt selv?</title>
        <link rel="alternate" href="https://ulrik.co/posts/skal-man-nu-gore-alt-selv/"/>
        <id>https://www.ulrik.co//posts/skal-man-nu-gore-alt-selv/</id>
        <updated>2024-12-27T21:20:55+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Om man skal gøre alt selv, det ved jeg ikke - men i hvert fald, så har jeg gjort denne blog selv.</p>
<p>Altså, gjort det der egentlig ikke er grund til.
Jeg har skrevet den kode der bygger og offentliggøre denne blog om og helt fra bunden.</p>
<p>Q: Var jeg ikke tilfreds med <a href="https://gohugo.io/">hugo</a>?<br>
A: Jo, jo - det var jeg sådan set.</p>
<p>Q: Findes der ikke et hav af static site generators allerede?<br>
A: Jo, jo - <a href="https://github.com/myles/awesome-static-generators">det gør der</a>.</p>
<p>Q: Har du for meget fritid?<br>
A: Njah, det tror jeg sådan set ikke.</p>
<p>Q: Hvorfor så?</p>
<p>Ja, det er vel egentlig et godt spørgsmål... Svaret er vel egentlig relativt simpelt. Fordi man kan - og fordi man lærer noget af at bygge noget forfra en gang i mellem.</p>
<p>Primært har jeg gjort det for at have kontrol over platformen og forstå alle dele. Også fordi <a href="https://gohugo.io/">hugo</a> er skrevet i <a href="https://go.dev">go</a> - og det forstår jeg ikke en dyt af.</p>
<p>Det kunne jo så ha' været det projekt - altså lære <a href="https://go.dev">go</a> - men det har jeg ikke fritid nok til, så det må blive en anden gang.</p>
<p>Men... hvad er så stumperne?</p>
<p>Altså, der er ikke ændret på hvor jeg hoster min hjemmeside - det er stadig hos Hetzner. Ikke sponsoreret eller noget, men det er altså en ret go' service de har sig.</p>
<p>Systemet der samler trådene er skrevet i PHP med hjælp fra en række composer pakker.</p>
<ul>
<li><a href="https://commonmark.thephpleague.com/">league/commonmark</a> - Bruges til at lave html ud af markdown.</li>
<li><a href="https://symfony.com/doc/current/components/console.html">symfony/console</a> - Bruges til at bygge de færdige html filer og samle stumperne.</li>
<li><a href="https://symfony.com/doc/current/components/finder.html">symfony/finder</a> -  Bruges til at finde de markdown filer der skal bygges.</li>
<li><a href="https://twig.symfony.com/">twig/twig</a> - Er til templating, bruges både til selve bloggen men også til at generere <a href="/feed.xml">rss feedet</a>.</li>
</ul>
<p>Pt. består systemet af et par cli kommandoer, til at oprette nye &quot;skeletter&quot; til blogindlæg og til at bygge de færdige output filer, når jeg er færdig med at skrive dem.</p>
<p>Der er også en kommando til at uploade til serveren. Denne del kunne man nok automatisere i en <a href="/posts/gitlab-pipeline-php-deployer/">Gitlab pipeline</a>, men det må blive senere - pt. er rsync en fin fin løsning.</p>
<p>&quot;Er du så færdig nu Ulrik?&quot; - Næ, det er jeg ikke, der er masser af forbedringer jeg gerne vil ha' lavet. Og de kommer helt sikkert også her de næste måneder.</p>
<p>Jeg overvejer om det skal laves til en serie her, så I kan følge lidt med - og grine af, hvor underligt det er - eller hvor pinlige de fejl jeg får lavet er. Men nu vi se. Det kræver jo at jeg får dokumenteret tingene undervejs.</p>

            </div>
        </content>
    </entry>
    <entry>
        <title>Deploying a PHP project via GitLabs pipeline</title>
        <link rel="alternate" href="https://ulrik.co/posts/gitlab-pipeline-php-deployer/"/>
        <id>https://www.ulrik.co//posts/gitlab-pipeline-php-deployer/</id>
        <updated>2024-04-14T13:30:00+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I have a <a href="https://symfony.com/" title="Home of the Symfony project">Symfony</a> project on <a href="https://gitlab.com/">GitLab</a>, I wanted to deploy to a server over ssh via <a href="https://deployer.org/" title="Home of the Deployer project">deployer</a> - and I found some minor issues with, the guides I found online - so, here is my take on how to go about it.</p>
<img src="./assets/pipeline.png" title="Up 'n running - pipeline in process." >
<p>All deployment steps will be executed on the target server, so the server needs a <code>deployer</code> user, with sufficient rights to do whatever steps you need it to do.
The steps I need are pretty basic, so I don't have spedial permissions set up on the server.</p>
<h3>Setting up the target server</h3>
<p>On the server, add the <code>deployer</code> user.</p>
<pre><code class="language-bash">sudo adduser --disabled-password --create-home deployer
</code></pre>
<p>Fill in what ever information you want - or just hit <code>Enter</code>.</p>
<p>Then generate ssh-keys for that user and add the public key to the users <code>authorized_keys</code> file - The later is needed for the ssh connection from GitLab.</p>
<pre><code class="language-bash">sudo su - deployer
ssh-keygen -t ed25519 -C &quot;deployer@example.com&quot;
cat ~/.ssh/id_ed25519.pub &gt;&gt; ~/.ssh/authorized_keys
</code></pre>
<h3>The php project</h3>
<h4>deployer.php</h4>
<p>Here you need to add deployer as a <code>dev</code> dependency.</p>
<pre><code class="language-bash">php composer require --dev deployer/deployer
</code></pre>
<p>The content of the file will wary a lot - based on your projects needs - but here are a basic example - this one is build on the <a href="https://deployer.org/docs/7.x/recipe/symfony" title="Symfony deploy recipe for Deployer">Symfony recipe</a>.</p>
<pre><code class="language-php">&lt;?php
namespace Deployer;

require 'recipe/symfony.php';

set('repository', 'git@gitlab.com:xyz/project.example.com.git');
set('application', 'project.example.com');
set('git_tty', true);
set('keep_releases', 3);
set('writable_mode', 'acl');
set('http_user', 'www-data');
set('default_stage', 'prod');
set('allow_anonymous_stats', false);
set('ssh_multiplexing', true);

set('bin/php', function() {
    return which('php8.2');
});

set('env', [
    'APP_ENV' =&gt; 'prod',
]);

host('project.example.com')
    -&gt;setHostname('project.example.com')
    -&gt;setRemoteUser('deployer')
    -&gt;set('identity_file', '/root/.ssh/id_ed25519')
    -&gt;set('labels', ['stage' =&gt; 'prod'])
    -&gt;set('branch', 'main')
    -&gt;set('deploy_path', '/var/www/project.example.com');

task('asset-map-compile', function () {
    writeln('Compiling asset map');
    run('cd {{release_or_current_path}} &amp;&amp; {{bin/php}} bin/console asset-map:compile');
});

after('deploy:publish', 'database:migrate');
after('database:migrate', 'asset-map-compile');
after('deploy:failed', 'deploy:unlock');
</code></pre>
<h4>.gitlab-ci.yml</h4>
<p>You also need a <code>.gitlab-ci.yml</code> file. This file will contain the different steps you want your pipeline to execute.</p>
<p>Mine is set up to only trigger the deployment step when pushing to the <code>main</code> branch - and only if all tests have passed.</p>
<pre><code class="language-yaml">variables:
  COMPOSER_ALLOW_SUPERUSER: 1
  COMPOSER_DEFAULT_OPTIONS: '--optimize-autoloader --classmap-authoritative --no-progress --no-suggest --prefer-dist'
  DOCKER_IMAGE_PHP: 'registry.gitlab.com/xyz/project.example.com:latest'

stages:
  - build
  - test
  - deploy

build:
  stage: build
  image: ${DOCKER_IMAGE_PHP}
  script:
    - composer install ${COMPOSER_DEFAULT_OPTIONS}
  variables:
    APP_ENV: test
  artifacts:
    paths:
      - vendor/
      - bin/

phpunit:
  stage: test
  image: ${DOCKER_IMAGE_PHP}
  script:
    - php vendor/bin/phpunit
  variables:
    APP_ENV: test
  dependencies:
    - build

deploy_prod:
  stage: deploy
  image: ${DOCKER_IMAGE_PHP}
  only:
    - main
  before_script:
    - mkdir ~/.ssh
    - chmod 700 ~/.ssh
    - cp $DEPLOYER_SSH_KEY ~/.ssh/id_ed25519
    - ssh-keyscan -t rsa,ed25519 &quot;${DEPLOYER_SSH_HOST}&quot; &gt;&gt; ~/.ssh/known_hosts
    - chmod 600 ~/.ssh/*
    - eval $(ssh-agent -s)
    - ssh-add ~/.ssh/id_ed25519
  script:
    - php vendor/bin/dep deploy --revision=&quot;${CI_COMMIT_SHA}&quot;
  dependencies:
    - build
  when: on_success
</code></pre>
<p>The <code>DEPLOYER_SSH_KEY</code> and <code>DEPLOYER_SSH_HOST</code> variables are set as secrets in your pipeline.</p>
<p>Please note that the <code>DEPLOYER_SSH_KEY</code> is your private key for the deployer user - and must be set up as a <code>File</code> variable on your project - and when you paste the private key into the input file, you must be sure to end the file with a newline (don't ask)!</p>
<p>The variables can be found under <code>Settings -&gt; CI/CD -&gt; Variables</code> on the project.</p>
<img src="./assets/cicd-variables.png" title="Setting up CI/CD variables." >
<h4>DOCKER_IMAGE_PHP</h4>
<p>Yes, you need to build your own docker image to run your build/test/deployment on - and add that one to GitLabs repository.</p>
<blockquote>
<p>Note! It is important that the image is named the same as your project - otherwise it will be rejected by GitLab.</p>
</blockquote>
<p>Building the image is again up to your needs, but the Dockerfile could look like this.</p>
<pre><code class="language-dockerfile">FROM php:8.2-fpm

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod +x /usr/local/bin/install-php-extensions \
    &amp;&amp; install-php-extensions amqp gd zip pdo_mysql igbinary intl

RUN apt-get -y update \
    &amp;&amp; apt-get -y --no-install-recommends install git libzip-dev \
    zip unzip wget curl rsync openssl openssh-client libicu-dev

COPY --from=composer /usr/bin/composer /usr/bin/composer
</code></pre>
<p>You need to log in to registry.gitlab.com in order to upload the image. You use your email and a password/access token to login.</p>
<pre><code class="language-bash">docker login registry.gitlab.com
</code></pre>
<p>The Access Token must be set up with the following permissions <code>read_api, read_registry, write_registry</code> - and it must have an expirey date set.
You can setup Access Tokens under <code>Settings -&gt; Access Tokens</code></p>
<img src="./assets/access-tokens.png" title="Setting up Access Tokens" >
<p>The build and push the image.</p>
<pre><code class="language-bash">docker build -t registry.gitlab.com/xyz/project.example.com .
docker push registry.gitlab.com/xyz/project.example.com
</code></pre>
<h3>Done and ready - I hope</h3>
<p>All the pieces should be in place now - so the next push to the main branch, should tigger the <code>build -&gt; test -&gt; deploy</code> pipeline.</p>
<p>If any of your tests fail, the pipeline should fail and the deploy step should be skipped. If all tests pass, the the code should be deployed to the server.</p>
<p>Pushes to any other branch will only trigger the <code>build -&gt; test</code> part of the pipeline.</p>
<h3>Credits where credits due</h3>
<p>I based my guide on these articles</p>
<ul>
<li><a href="https://docs.gitlab.com/ee/ci/pipelines/">https://docs.gitlab.com/ee/ci/pipelines/</a></li>
<li><a href="https://dev.to/jszutkowski/how-to-automate-deploys-with-gitlab-ci-cd-and-deployer-28pb">https://dev.to/jszutkowski/how-to-automate-deploys-with-gitlab-ci-cd-and-deployer-28pb</a></li>
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-continuous-deployment-pipeline-with-gitlab-on-ubuntu">https://www.digitalocean.com/community/tutorials/how-to-set-up-a-continuous-deployment-pipeline-with-gitlab-on-ubuntu</a></li>
</ul>
<p>Some resources on the other tools can be found here</p>
<ul>
<li><a href="https://deployer.org/">https://deployer.org/</a></li>
<li><a href="https://symfony.com/">https://symfony.com/</a></li>
<li><a href="https://github.com/mlocati/docker-php-extension-installer/">https://github.com/mlocati/docker-php-extension-installer/</a></li>
</ul>

            </div>
        </content>
    </entry>
    <entry>
        <title>Tokuni</title>
        <link rel="alternate" href="https://ulrik.co/posts/tokuni/"/>
        <id>https://www.ulrik.co//posts/tokuni/</id>
        <updated>2024-02-16T21:34:34+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Ser man på mit Spotify review fra 2023, så har jeg lyttet til godt 1000 genre - og det er nok korrekt, der flyder rigtig meget blandet musik igenne.</p>
<p>Et af de numre, jeg lige pt. er ret pjattet med er Tokumi af Eivør.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"><iframe src="https://www.youtube.com/embed/pqnMkUcTmys" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video"></iframe></div>
<p>Jeg fatter ikke en brik af hvad hun synger, men det kan altså et-eller-andet.</p>

            </div>
        </content>
    </entry>
    <entry>
        <title>1 Milliard Linier</title>
        <link rel="alternate" href="https://ulrik.co/posts/1-milliard-linier/"/>
        <id>https://www.ulrik.co//posts/1-milliard-linier/</id>
        <updated>2024-01-05T22:33:10+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Yup, du læste rigtigt!
Det her er en historie om at læse og behandle store datamængder i et sprog som alle mener er dødt.</p>
<p>Jeg blev inspireret til at lave et eksperiment, efter at ha' læst <a href="https://www.morling.dev/blog/one-billion-row-challenge/">en udfordring</a> til Java udviklere.</p>
<p>Hvor hurtigt kan dit program læse og behandle en fil på 1.000.000.000 linjer? - Altså du skal skrive et program der kan læse og beregne på ret store datamængder.</p>
<p>&quot;Men, hvor meget kan 1.000.000.000 linjer fylde?&quot; Tænker du sikkert - well ... ca. 17GB viser det sig - og det er ikke eneste overraskelse jeg støder på.</p>
<p>Filen er en csv fil, med bynavne og temperaturer a la det her:</p>
<pre><code class="language-txt">Miami;0.12
Houston;12.2
Dallas;-12.98
Philadelphia;-1.2
Atlanta;59.21
Houston;-3.2
Washington;
Miami;12.12
</code></pre>
<p>Programmet skal læse filen og generere en linje pr. by med minimum, gennemsnit og maksimum temperatur ud fra indholdet i filen.
Der vil maksimum være 10.000 forskellige byer.</p>
<h2>Generering af testdata sæt</h2>
<p>Jeg lavede et super simpelt script der kan generere testdata i sæt, så jeg kan se forskellen på hvad størrelser gør ved tid.</p>
<p>Genereringen tager som følger:</p>
<pre><code class="language-bash">─&gt; time php data-generator.php 100000 &gt; data-100-000.csv
php data-generator.php 100000 &gt; data-100-000.csv  0,16s user 0,08s system 98% cpu 0,238 total

─&gt; time php data-generator.php 1000000 &gt; data-1-000-000.csv
php data-generator.php 1000000 &gt; data-1-000-000.csv  1,52s user 0,55s system 99% cpu 2,076 total

─&gt; time php data-generator.php 10000000 &gt; data-10-000-000.csv
php data-generator.php 10000000 &gt; data-10-000-000.csv  16,33s user 5,98s system 99% cpu 22,358 total

─&gt; time php data-generator.php 100000000 &gt; data-100-000-000.csv
php data-generator.php 100000000 &gt; data-100-000-000.csv  244,82s user 88,48s system 99% cpu 5:34,04 total

─&gt; time php data-generator.php 1000000000 &gt; data-1-000-000-000.csv
php data-generator.php 1000000000 &gt; data-1-000-000-000.csv  2110,31s user 781,45s system 99% cpu 48:16,22 total
</code></pre>
<p>Som det kan ses af tallene, så tog det lige over 35 minutter at generere det største dataset - viklet egentlig overraskede mig.
Jeg tror måske det skyldes at php er singeltrådet, og derfor kun kan makse den ene af min laptops kerner ud. Måske jeg skal prøve at lave et multi-trådet eksempel, for at se om jeg kan få den til at skrive hurtigere...</p>
<p>Mht. størrelserne på filerne, så kom de ud sådan her:</p>
<pre><code class="language-bash">-rw-rw-r--+ 1 un un  17G Jan  5 22:35 data-1-000-000-000.csv
-rw-rw-r--+ 1 un un 1,7G Jan  5 21:45 data-100-000-000.csv
-rw-rw-r--+ 1 un un 165M Jan  5 21:39 data-10-000-000.csv
-rw-rw-r--+ 1 un un  17M Jan  5 21:39 data-1-000-000.csv
-rw-rw-r--+ 1 un un 1,7M Jan  5 21:38 data-100-000.csv
</code></pre>
<h2>Processering af filerne</h2>
<p>Det script jeg lavede til at parse filerne, var igen ret simpelt - der skal egentlig ikke så meget til. Det spændende er om jeg nu efterfølgende kan finde en måde at gøre det hurtigere på - for her igen, er min test begrænset til at makse en kerne ud - så kan det ikke gå hurtigere.</p>
<pre><code class="language-bash">─&gt; time php data-parser.php 100-000 &gt; result-100-000.csv
php data-parser.php 100-000  0,17s user 0,01s system 99% cpu 0,178 total

─&gt; time php data-parser.php 1-000-000 &gt; result-1-000-000.csv
php data-parser.php 1-000-000  1,58s user 0,01s system 99% cpu 1,589 total

─&gt; time php data-parser.php 10-000-000 &gt; result-10-000-000.csv
php data-parser.php 10-000-000  15,66s user 0,09s system 99% cpu 15,755 total

─&gt; time php data-parser.php 100-000-000 &gt; result-100-000-000.csv
php data-parser.php 100-000-000  168,54s user 0,67s system 99% cpu 2:49,24 total

─&gt; time php data-parser.php 1-000-000-000 &gt; result-1-000-000-000.csv
php data-parser.php 1-000-000-000  1529,97s user 3,15s system 99% cpu 25:33,34 total
</code></pre>
<p>Her var overraskelse 2 - det var hurtigere at læse og behandle data, end det var at generere dem - selvom processen i at generere data er meget simplere end at parse dem efterfølgende.</p>
<p>Jeg har planer om at udfordre mine kollegaer til at skrive parsere, og så teste dem på én af vores servere - og på den måde lave en lille konkurrence. Men det er så også grunden til at der er meget lidt kode i det her indlæg. Det er jo sjovere, hvis de selv skal tænke :)</p>
<p>Og dog - lidt kode skal der vel være, så</p>
<pre><code class="language-php">function randomFloat($min = -99_999, $max = 99_999): float
{
    return number_format(random($min, $max) / 1_000, 2);
}
</code></pre>
<p>I PHP 8.3 kommer der en ny <a href="https://www.php.net/manual/en/random-randomizer.getfloat.php">Random generator</a> som kan det pis, men før den - hvad er så den bedste måde at lave random floats på? Som ovenstående, eller ...?</p>

            </div>
        </content>
    </entry>
    <entry>
        <title>Veggebøffer</title>
        <link rel="alternate" href="https://ulrik.co/posts/veggeboeffer/"/>
        <id>https://www.ulrik.co//posts/veggeboeffer/</id>
        <updated>2023-07-02T17:58:10+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Har efterhånden snakket med en del, om opskrifter på gode plantebøffer - så her er mit bud på en god bøf, der er godkendt af alle her på matriklen - selv teenagedrengen, der mener, at kød og brød er eneste rigtige mad.</p>
<img src="./assets/bøfstakken.jpg" title="En bunke bøffer, klar til at spise 😊" >
<p>Nu har jeg bygget de her burgere de sidste par år - og her i huset er det vores go-to bøf, når vi laver burgers om det er på panden eller ude på grillen.</p>
<p>Vi er ikke (som sådan) vegetarer, men prøver at spise mere og mere grønt, og lige her er det ret let - alle er enige om at denne bøf er mindst lige så god som én af oksekød.</p>
<h2>Hvad skal der i?</h2>
<table>
<thead>
<tr>
<th align="right">Mængde</th>
<th>Ingridienser</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">2</td>
<td>små løg, eller et stort</td>
</tr>
<tr>
<td align="right">3</td>
<td>fed hvidløg</td>
</tr>
<tr>
<td align="right">1 ds.</td>
<td>kikærter</td>
</tr>
<tr>
<td align="right">2 dl.</td>
<td>edemammebønner</td>
</tr>
<tr>
<td align="right">1 dl.</td>
<td>sorte bønner</td>
</tr>
<tr>
<td align="right">1 bnt.</td>
<td>persille</td>
</tr>
<tr>
<td align="right">1/2</td>
<td>revet squash</td>
</tr>
<tr>
<td align="right">3</td>
<td>æg</td>
</tr>
<tr>
<td align="right">2 spsk.</td>
<td>spidskommen</td>
</tr>
<tr>
<td align="right">1/2 - 1 tsk.</td>
<td>chiliflager</td>
</tr>
<tr>
<td align="right">1 - 2 dl.</td>
<td>Pankorasp</td>
</tr>
<tr>
<td align="right"> </td>
<td>salt</td>
</tr>
<tr>
<td align="right"> </td>
<td>peber</td>
</tr>
</tbody>
</table>
<p>Det &quot;sagt&quot; - så bliver mine aldrig ens, da opskrifter jo som alle ved, ikke er regler - men gudelines, så Improvisation er helt på sin plads.</p>
<p>Hak løg og hvidløg groft og kom så hele molevitten (pånær rasp) i en foodprocessor - det skal blive til grød, der må godt være lidt struktur i dejen.
Vend nu Pankorasp i, til det har en &quot;god konsistens&quot; - hvad end det er, de bliver aldrig lige så faste som en kød-bøf.</p>
<p>Steg bøffer, sat med en ske på en pande i noget smør eller olie. Har du en <a href="https://www.hwl.dk/kageforme-og-springforme/form-rund-rf-oe160-mm-h-50-mm" title="Eksempelvis en som denne her.">stålform</a>, er det ret let, at lave pæne runde bøffer.</p>
<p> </p>
<img src="./assets/resultatet.jpg" title="Her til aften kom resultatet til at se sådan her ud." >

            </div>
        </content>
    </entry>
    <entry>
        <title>Gi&#039; Noget!</title>
        <link rel="alternate" href="https://ulrik.co/posts/gi-noget/"/>
        <id>https://www.ulrik.co//posts/gi-noget/</id>
        <updated>2023-04-24T18:09:20+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Vi tager og tager, men vi bør altså også gi' noget tilbage, det gør vi altså - ellers er vi ikke ordentlige mennesker!</p>
<p>Inden for min branche - den der IT bobbel, hvor vi i de sidste mange år, er blevet forvendt med, at &quot;alt er gratis&quot; - i hvert fald de byggeklodser vi bygger vores forretning på.</p>
<p>Her bruger vi rask væk software, artikler, dokumenter, dokumentation, ideér osv. Vi kalder der for <a href="https://opensource.com/resources/what-open-source" title="En forklaring på hvad Open Source er for en størrelse">Open Source</a>, <a href="https://creativecommons.org/about/" title="Forklaring på hvda Creative Commons dækker over">Creative Commons</a> - eller noget helt 3. - men det dækker over meget det samme, at nogen stiller deres arbejde/tid tilrådighed for andre at bruge, uden det koster noget.</p>
<p>Men vi har rigtig svært ved at gi' noget tilbage, og det er altså et problem.</p>
<p>Hvis vi ikke vil give vores egen tid, penge, kommentarer, ris/ros - en kop kaffe, eller noget som helst andet - end kravet om at ressurcen følger med tiden, så man selv kan fortsætte med at løft sit eget produkt (der selv sagt ikke er gratis) ind i det næste århundrede.</p>
<p>Det duer altså ikke - vi får folk til at stoppe, stoppe med at lægge deres tid og kræfter i de ressurcer vi er blevet afhængige af, for at få vores egen forretning til at fungere.</p>
<blockquote>
<p>Vi kan jo bare lave det selv, skulle de stoppe!
— Randm Product Owner</p>
</blockquote>
<p>Err, joo da - men det kan i nogen (mange) tilfælde løbe op i årsværk af arbejde, og det kommer jo ikke til at ske.</p>
<p>Vi <em>bør</em> gøre noget, noget godt for resourcerne - og ja, jeg ved godt at der sikkert er mange - men hvor mange timers arbejde har du ikke sparet på at bruge nettop dums-nummer-x ?</p>
<p>Start eventuelt med at se på din &quot;stack&quot; - hvad bruger du? Eksemplet fra mig selv, kunne være bloggen her - den er bygget på noget, så lad os analysere den og finde ud af om der er stede det ville være på sin plads at gi' noget!</p>
<ul>
<li>Bloggen er lavet med <a href="https://gohugo.io/" title="En platform til at bygge statiske websites skrevet i go">Hugo</a> - en platform til at lave websites.</li>
<li>Temaet på bloggen har <a href="https://themes.gohugo.io/themes/hugo-theme-cactus-plus/" title="Det Hugo-tema jeg har her på siden">nodejh</a> lavet - har pillet lidt, det gør man jo.</li>
<li>Ikonerne som så fint præcentere de sociale platforme kommer fra <a href="https://icons.getbootstrap.com/" title="En svg ikon samling til fri afbenyttelse">Bootstrap</a>.</li>
<li>Den drives af en webserver - hos mig er det <a href="https://www.nginx.com/" title="En af verdens mest benyttede webservere">nginx</a>.</li>
<li>Editoren jeg bruger til at skrive indlæggene i hedder <a href="https://code.visualstudio.com/" title="Gratis kodeværktøj fra Microsoft">vscode</a> i daglig tale.</li>
</ul>
<p>Man kunne godt med rimelighed sige, at laver en &quot;leverandør&quot; penge på det de tilbyder, så bliver de allerede godtgjort gennem deres forretning. I denne liste drejer det sig om vscode og nginx, der begge har kommacielle forretninger i ryggen.</p>
<p>Men det lader os alligevel tilbage med 3 projekter, der alle drives og produceres af frivillige, der giver og deres tid og kreativitet - uden det koster os en rød reje.</p>
<p>Hvordan skal vi så fordele vores tilbagebetaling? De forventer jo ikke at vi giver dem noge, så hvorfor skulle vi?</p>
<p>Vi skal betale tilbage efter evne og gevinst mener jeg.</p>
<p>Jeg skal selv ud og finde ud af hvad jeg kan give tilbage til de 3 projekter, om det skal være noget hjælp med dokumentation, måske oversættelser, kode - eller penge.</p>
<p>Kode kan godt blive en personlig udfordring, da jeg ikke kender en dyt til <a href="https://go.dev/" title="Udviklingssproget go">go</a> - men det kan jo være en god anledning til at dykke ned i det. Bootstrap ... Her skal jeg vidst holde mig til dokumentation og/eller oversættelser, da jeg ikke er nogen ørn til <code>css</code> - eller design generelt.</p>
<p>Testing kunne også være en måde at give tilbage på. I hvert fald kunne det være en af de muligheder jeg har for at hjælpe.</p>
<p>Penge er altid en lidt ømtålelig ting. Især når man som privat person benytter sig af Open Source ting. Ens privatøkonomi er måske ikke altid til, at smide x-antal kroner efter x-antal projekter hver måned - men så må man se på hvad der giver en mest, og så sætte ens penge på det.</p>
<p>Det har jeg gjort.</p>
<ul>
<li>Jeg lever af PHP, jeg betaler til <a href="https://thephp.foundation/" title="Lær mere om PHP Foundation">The PHP Foundation</a>, en lille donation hver måned.</li>
<li>Jeg benytter mig (næsten) dagligt af <a href="https://xdebug.org/" title="Lær mere om Xdebug">xdebug</a>, så dem har jeg også valgt at støtte financielt.</li>
</ul>
<p>Der er også <a href="https://phpunit.de/" title="Lær mere om PHPUnit">phpunit</a>, som godt kunne bruge en hånd, men i første omgang er det her mine slanter er lagt.</p>
<p>Ellers prøver jeg efter bedste evne at give tilbage, og hjælpe de steder jeg kan og frem for alt prøver jeg at være ydmyg når jeg kommunikere med de udviklere der sidder i den anden ende - at give dem en masse røg for, at de ikke har løst netop mit problem, hjælper ikke en dyt - tværtimod!</p>
<p>Så min bøn til virksomheder der benytter sig af Open Source projekter i jeres virksomhed. Gi' noget - et eller andet.</p>
<ul>
<li>En <a href="https://www.buymeacoffee.com/" title="Donner lidt via en kop kaffe">kop kaffe</a> er et sted at starte.</li>
<li>Opret et issue, hvor du i stedet for at fortælle om noget der ikke virker, fortæller dem at de gør en forskel for dig.</li>
<li>Giv feedback i andres issues, hvis du har viden.</li>
</ul>
<p>Hvis vi gerne som branche, vil blive ved med at nyde godt af den tid og de ressourcer de her mennesker pumper i projekterne - så blive vi nødt til at hværne om dem.</p>
<p>Passer vi godt på dem, passer de godt på os.</p>

            </div>
        </content>
    </entry>
    <entry>
        <title>A New Life</title>
        <link rel="alternate" href="https://ulrik.co/posts/a-new-life/"/>
        <id>https://www.ulrik.co//posts/a-new-life/</id>
        <updated>2023-04-12T17:57:44+00:00</updated>
        <author><name>Ulrik Nielsen></name></author>
        <content type="xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Egentlig skulle jeg jo ikke starte!</p>
<p>Jeg har altid godt kunne li' ideen om at blogge, men har aldrig rigtig fået gjort noget ved det - men nu skulle det så være. Det er alligevel begrænset hvad der kan stå i et toot/tweet.</p>
<p>Hvorfor det så lige skal være nu, det er et godt spørgsmål.</p>
<p>Jeg tror egentlig det kommer af, at jeg jo alligevel har holdninger til alt muligt - og hvorfor så ikke skrive dem ned, og dele dem..?</p>
<p>Bloggen kommer til, at være en god blanding af random ord og teknologinørderi.</p>
<p>Jeg tænker de fleste sikkert syntes indholdet er af svingende kvaliet - og ved du hvad? Det er det garanteret, for det her med at udtrykke mig i skrift - det er altså ikke noget jeg har gjort særlig meget i, så det er også en platform, hvor jeg kan øve mig på det.</p>

            </div>
        </content>
    </entry>
</feed>
