<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[trangelier.dev]]></title><description><![CDATA[Personal thoughts, opinions and code.]]></description><link>https://trangelier.dev/</link><image><url>https://trangelier.dev/favicon.png</url><title>trangelier.dev</title><link>https://trangelier.dev/</link></image><generator>Ghost 4.17</generator><lastBuildDate>Thu, 07 May 2026 13:07:25 GMT</lastBuildDate><atom:link href="https://trangelier.dev/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[AutoSSH for persistent tunnels]]></title><description><![CDATA[Have you ever created a docker image or other service on a remote machine but want to access that service on your local machine as it was local? Well this post is for you!]]></description><link>https://trangelier.dev/autossh-for-persistent-tunnels/</link><guid isPermaLink="false">61dca8aef095df03b25b2bf4</guid><category><![CDATA[ssh]]></category><dc:creator><![CDATA[Tyler Angelier]]></dc:creator><pubDate>Mon, 10 Jan 2022 21:48:38 GMT</pubDate><content:encoded><![CDATA[<p>Have you ever created a docker image or other service on a remote machine but want to access that service on your local machine as it was local? Well this post is for you!</p><p>I recently bought a M1 Mac mini for use at Oracle as the provided machine was not up to par.. M1 is <em>amazing</em> but while ARM is not fully supported I&apos;ve found having a linux box remotely to build &amp; run services is a nice stop-gap until more ARM support is made. The big motivation for this was that I wanted to be able to keep the same &quot;localhost&quot; developer productivity as when running the services locally. Thankfully many great tools have been written around SSH to make this super easy!</p><h1 id="auto-ssh">Auto SSH</h1><p><code>autossh</code> is a great tool for restarting SSH sessions and tunnels for you. This is perfect for our use case so we don&apos;t have to deal with managing the tunnel or SSH connection</p><h2 id="macos">MacOS</h2><pre><code class="language-bash">brew install autossh</code></pre><p>Just that easy.</p><h2 id="windows">Windows</h2><p>Ummm.. <a href="https://www.google.com/search?q=install+autossh+on+windows+subsystem+for+linux&amp;client=safari&amp;rls=en&amp;sxsrf=AOaemvIEBztTrHLHe97I6Qfq4gPllstCkQ%3A1641833265552&amp;ei=MWPcYYOgIaaUwbkPoeaGiAk&amp;oq=install+autossh+on+windows+subsy&amp;gs_lcp=Cgdnd3Mtd2l6EAMYADIFCCEQoAEyBQghEKABOgcIABBHELADOgYIABAWEB46CAghEBYQHRAeSgQIQRgASgQIRhgAUPsGWMcUYPsZaANwAHgAgAFziAGzBZIBAzcuMZgBAKABAcgBCMABAQ&amp;sclient=gws-wiz">Good luck</a>? &#xAF;\_(&#x30C4;)_/&#xAF;</p><h1 id="forwarding-a-service">Forwarding a service</h1><p>Okay so lets say we have a machine running the cloud or a server locally (doesn&apos;t matter) we want to forward ports locally to. First, lets create a SSH config to make our setup a bit cleaner.</p><p>Add a SSH profile to your ssh config file (<code>~/.ssh/config</code>) such as the one below:</p><pre><code class="language-Bash">Host tangelie
	Hostname &lt;hostname-or-ip&gt;
	IdentityFile &lt;path-to-keyfile&gt;
	User &lt;user&gt;
	Port 22</code></pre><p>Now we can easily connect to the server with this command!</p><pre><code class="language-Bash">ssh tangelie</code></pre><p>And the configuration we wrote above will fill everything else in. Awesome!</p><p>Next lets say we have a service running on port <code>8080</code> on our remote server that we want to access locally also at port <code>8080</code>. We need to create an autossh command to keep this tunnel open for us:</p><pre><code class="language-Bash"># -M specifies the base monitoring port to use.
# -f causes autossh to drop to the background before running ssh.
# -N Do not execute a remote command.  This is useful for just forwarding ports.
# -o ssh options
# -L Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side.
# &lt;local-port&gt;:&lt;hostname&gt;:&lt;remote-port&gt;
# ssh connection details
autossh -M 0 -f -N -o &quot;ServerAliveInterval 60&quot; -o &quot;ServerAliveCountMax 3&quot; -L 8080:localhost:8080 tangelie</code></pre><p>Great!! Now if we run this <code>autossh</code> command it will maintain an SSH tunnel to our machine and port forward <code>8080</code> to our <code>localhost</code>!</p><p>Last thing we can do to make this much easier to run is to create an bash or ZSH alias:</p><p>Now from a terminal you can simply enter <code>tangelie_tunnel</code> and the tunnel will be created for you!</p><pre><code class="language-Bash">alias tangelie_tunnel=&quot;autossh -M 0 -f -N -o \&quot;ServerAliveInterval 60\&quot; -o \&quot;ServerAliveCountMax 3\&quot; -L 8080:localhost:8080 tangelie&quot;</code></pre><h2 id="forward-on-startup">Forward on startup</h2><p>Stay tuned to my blog for a future article on creating these tunnels on startup!</p>]]></content:encoded></item><item><title><![CDATA[OCI ATP Nginx Reverse Proxy in Kubernetes!]]></title><description><![CDATA[<p>When Oracle first announced all of the <a href="https://www.oracle.com/cloud/free/" rel="nofollow">free-tier resources</a> they offer I immediately jumped on the offer. Thankfully, <a href="https://twitter.com/dgielis?lang=en" rel="nofollow">Dimitri Gielis</a> had already started on his AMAZING <a href="https://dgielis.blogspot.com/2019/09/best-and-cheapest-oracle-apex-hosting.html" rel="nofollow">Best and Cheapest Oracle APEX hosting: Free Oracle Cloud</a> blog post series. While I don&apos;t use things like APEX Office Print -</p>]]></description><link>https://trangelier.dev/oci-atp-nginx-reverse-proxy-in-kubernetes/</link><guid isPermaLink="false">6199f33c539d0503baaf4777</guid><dc:creator><![CDATA[Tyler Angelier]]></dc:creator><pubDate>Sun, 21 Nov 2021 07:25:23 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1510915228340-29c85a43dcfe?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDIzfHxjb2RlfGVufDB8fHx8MTYzNzQ3OTY4Mg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1510915228340-29c85a43dcfe?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDIzfHxjb2RlfGVufDB8fHx8MTYzNzQ3OTY4Mg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="OCI ATP Nginx Reverse Proxy in Kubernetes!"><p>When Oracle first announced all of the <a href="https://www.oracle.com/cloud/free/" rel="nofollow">free-tier resources</a> they offer I immediately jumped on the offer. Thankfully, <a href="https://twitter.com/dgielis?lang=en" rel="nofollow">Dimitri Gielis</a> had already started on his AMAZING <a href="https://dgielis.blogspot.com/2019/09/best-and-cheapest-oracle-apex-hosting.html" rel="nofollow">Best and Cheapest Oracle APEX hosting: Free Oracle Cloud</a> blog post series. While I don&apos;t use things like APEX Office Print - his guides on using a compute instance as a nginx reverse proxy were super helpful.</p><p>Now that I&apos;ve configured an <a href="https://www.oracle.com/cloud-native/container-engine-kubernetes/" rel="nofollow">OKE</a> cluster (on ARM for free!) and use an <a href="https://docs.oracle.com/en-us/iaas/Content/Balance/Concepts/balanceoverview.htm" rel="nofollow">OCI Load Balancer</a> to route my OCI traffic - I wanted to move the simple Nginx reverse proxy into Kubernetes. This repo is quite simple and creates a nginx service with a custom config file. I also use <a href="https://traefik.io/traefik/" rel="nofollow">Traefik</a>, so it creates a Traefik IngressRoute for my subdomain.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wxfDF8YWxsfDZ8fHx8fHwyfHwxNjM3NDc5MjY0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" class="kg-image" alt="OCI ATP Nginx Reverse Proxy in Kubernetes!" loading="lazy" width="6016" height="4016" srcset="https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wxfDF8YWxsfDZ8fHx8fHwyfHwxNjM3NDc5MjY0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=600 600w, https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wxfDF8YWxsfDZ8fHx8fHwyfHwxNjM3NDc5MjY0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=1000 1000w, https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wxfDF8YWxsfDZ8fHx8fHwyfHwxNjM3NDc5MjY0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=1600 1600w, https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wxfDF8YWxsfDZ8fHx8fHwyfHwxNjM3NDc5MjY0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2400 2400w" sizes="(min-width: 720px) 720px"><figcaption>Photo by <a href="https://unsplash.com/@xps?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">XPS</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Unsplash</a></figcaption></figure><p>Once you have the infrastrucutre (OCI Load balancer &amp; OKE cluster) setup it is quite simple to get this up and running. I will be creating a blog post and how to use all OCI Free Tier resources to spin up your own managed kubernetes cluster soon!</p><p>To use <a href="https://github.com/trangelier/atp-reverse-proxy-k8">my repo</a> you will need to make a two changes:</p><ol><li>Cutomize the <code>nginx.conf</code> with your URL to your ATP instance</li><li>Customize <code>deployment/ingress-route.yaml</code> with your <code>match</code> rule</li></ol><p>And that&apos;s it! Just run follow the <a href="https://github.com/trangelier/atp-reverse-proxy-k8#how-to-use">How to use</a> section of the readme and you&apos;ll have a scalable nginx reverse proxy running in kubernetes!</p>]]></content:encoded></item><item><title><![CDATA[Spring Boot, Testcontainers, Oracle XE]]></title><description><![CDATA[In this blog post I will be showing the bare bones code you need to run an Integration test using Testcontainers in a Spring Boot application.]]></description><link>https://trangelier.dev/spring-boot-testcontainers-oracle-xe/</link><guid isPermaLink="false">61594d58fbd14ce852c908d3</guid><category><![CDATA[spring-boot]]></category><category><![CDATA[oracle-database]]></category><category><![CDATA[testing]]></category><dc:creator><![CDATA[Tyler Angelier]]></dc:creator><pubDate>Sun, 03 Oct 2021 15:35:43 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1566837945700-30057527ade0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDExfHxjb2RlfGVufDB8fHx8MTYzMzI0NDAxNg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1566837945700-30057527ade0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDExfHxjb2RlfGVufDB8fHx8MTYzMzI0NDAxNg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Spring Boot, Testcontainers, Oracle XE"><p>In this blog post I will be showing the bare bones code you need to run an Integration test using Testcontainers in a Spring Boot application. I won&apos;t go into detail about how testing with the same database as you use in production is something you should do if you truly care about your software. I am using an Oracle XE database (not suprising I suppose) but you can subsitute that freely for any of Testcontainers supported databases.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHRlc3R8ZW58MHx8fHwxNjMzMjQyNjU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" class="kg-image" alt="Spring Boot, Testcontainers, Oracle XE" loading="lazy" width="7360" height="4912" srcset="https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHRlc3R8ZW58MHx8fHwxNjMzMjQyNjU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=600 600w, https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHRlc3R8ZW58MHx8fHwxNjMzMjQyNjU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=1000 1000w, https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHRlc3R8ZW58MHx8fHwxNjMzMjQyNjU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=1600 1600w, https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fHRlc3R8ZW58MHx8fHwxNjMzMjQyNjU5&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2400 2400w" sizes="(min-width: 720px) 720px"><figcaption>Photo by <a href="https://unsplash.com/@homajob?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Scott Graham</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Unsplash</a></figcaption></figure><p>Let&apos;s start off with the <code>pom.xml</code>. Update your <code>&lt;properties&gt;</code>versions as you need. I am using an Oracle XE database for my tests so update that dependency for whichever database you&apos;re using.</p><pre><code class="language-xml">	&lt;properties&gt;
        &lt;junit.jupiter.version&gt;5.4.2&lt;/junit.jupiter.version&gt;
        &lt;testcontainers.version&gt;1.16.0&lt;/testcontainers.version&gt;
    &lt;/properties&gt;
    &lt;dependencies&gt;
				...
        &lt;!--    Test    --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
            &lt;artifactId&gt;oracle-xe&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
            &lt;artifactId&gt;testcontainers&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
            &lt;artifactId&gt;junit-jupiter&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.junit.jupiter&lt;/groupId&gt;
            &lt;artifactId&gt;junit-jupiter&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
				...
    &lt;/dependencies&gt;

		&lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.junit&lt;/groupId&gt;
                &lt;artifactId&gt;junit-bom&lt;/artifactId&gt;
                &lt;version&gt;${junit.jupiter.version}&lt;/version&gt;
                &lt;type&gt;pom&lt;/type&gt;
                &lt;scope&gt;import&lt;/scope&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
                &lt;artifactId&gt;testcontainers-bom&lt;/artifactId&gt;
                &lt;version&gt;${testcontainers.version}&lt;/version&gt;
                &lt;type&gt;pom&lt;/type&gt;
                &lt;scope&gt;import&lt;/scope&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;
</code></pre><p>Create a <code>@TestConfiguration</code> class to overwrite the <code>DataSource</code> bean. This needs to be manually imported because Spring Boot does not do component scanning on classes annotated with <code>@TestConfiguration</code>. Also notice we need to import the container (<code>oracle</code>) from its definition. This is the simplest override possible as Liquibase will also pickup on the <code>DataSource</code> and run your migrations with that connection information. While we could assume the username and password the port will always be random so it is best to just set your <code>DataSource</code> manually.</p><pre><code class="language-java">@TestConfiguration
public class OracleDbConfiguration {
    @Bean
    DataSource dataSource() {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(oracle.getJdbcUrl());
        hikariConfig.setUsername(oracle.getUsername());
        hikariConfig.setPassword(oracle.getPassword());
        return new HikariDataSource(hikariConfig);
    }
}
</code></pre><p>Lets look at an example test file:</p><ul><li><code>@Import(OracleDbConfiguration.class)</code> is required to overwrite the datasource</li><li><code>@@ActiveProfiles(&quot;oracle&quot;)</code> - is optional but a nice idea to do since container startup is not the quickest</li></ul><pre><code class="language-java">@SpringBootTest
@Testcontainers
@Import(OracleDbConfiguration.class)
@ActiveProfiles(&quot;oracle&quot;)
public class OracleTestContainerTest {
    @Autowired
    MyService service;
    @Autowired
    MyRepository repository;

    @Container
    static final OracleContainer oracle = new OracleContainer(&quot;gvenzl/oracle-xe:18.4.0-slim&quot;).withEnv(&quot;ORACLE_PASSWORD&quot;, &quot;oracle&quot;);

    @Test
		public void myFancyTest(){
			assertThat(repository.findAll().size()).isEqualTo(0);
		}
}
</code></pre><p>And that&apos;s it! Now you can startup a full database container to run your integration tests with. If your database is specialized (ie requires users with certain permissions or objects installed organization wide) a great next step is to create your own docker image from the <code>gvenzl/oracle-xe:18.4.0-slim</code> with all your setup already done and the database created. This will speed up the start of your tests <em>greatly.</em></p><p>References:</p><ul><li><a href="https://www.testcontainers.org/quickstart/junit_5_quickstart/">https://www.testcontainers.org/quickstart/junit_5_quickstart/</a></li><li><a href="https://www.testcontainers.org/modules/databases/oraclexe/">https://www.testcontainers.org/modules/databases/oraclexe/</a></li><li><a href="https://reflectoring.io/spring-boot-testconfiguration/">https://reflectoring.io/spring-boot-testconfiguration/</a></li></ul>]]></content:encoded></item></channel></rss>