Deployment of a Vapor Application

Deployment of a server side swift app, really a different game, not like creating a release build for an iOS.
At least no issues with provisioning profiles, codesign and the other niceties Xcode throws at you when creating a release build. There are other issues, though…

Today I set up the Ubuntu server to host the server side Vapor build app.  So after kicking off the VPS, I first opted to start with Ubuntu 1804 LTS. Let’s see where it takes me. Well, after the normal hardening of the any server:

  • Disable SSH root login
  • Setup UFW
  • Setup SSH Key Based Authentication
  • Nginx setup as reverse-proxy to the application.
  • Hardened TLS setup for Nginx.

I installed Swift, checked out the code, and tried to build the project. Sadly no luck, a quick search revealed that Ubuntu 1804 LTS will hold support for Swift 4.2. Since that one is in Beta, better not go there just yet.. So re-start the VPS installation and this time with Ubuntu 1604 LTS. Probably better luck there…

So after the same steps, this time the compilation works, and when I run the application, it works!. Cool let’s test the API calls, using Paw, and yeah it really works. Now we need to make sure are able to run the app unattended.  Thanks to this post, I figured out that I needed to add Supervisor to the equation.  Installed supervisor as advised.  Trying to start the supervisor application. Now the problem started… The Vapor does want start. I keep on getting the same error: “FATAL Exited too quickly (process log may have details)”. Sadly the log files do not really help..  After some digging I realised that the Vapor app by default is running under localhost, could this be the culprit? How can we start the Vapor app so it is not bound to localhost but to 0.0.0.0 instead.

So I created this config for Vapor:

services.register(Server.self) { container -> NIOServer in 
   var serverConfig = try container.make() as NIOServerConfig 
   serverConfig.port = 8080 
   serverConfig.hostname = "0.0.0.0" 
   let server = NIOServer( config: serverConfig, container: container ) 
   return server 
}

Now it starts and runs properly.  Bonus of this config is that you also easily change the port of the App.

 

All in all a nice exercise in getting the Vapor 3 based app deployed.

Change in career

This month, June 2018, I started working for Pro Warehouse. An Apple Enterprise Reseller in the Netherlands.

When working for this company I get to combine my two areas of expertise:

  • Development
  • Apple System Engineering

When attending the WWDC’08, ten years ago, I made the conscious move from System Engineering to full-time development. Started as a junior developer in ’10, and increased my skills as a developer over the past years. I learned a lot and keep on learning every day. I just love the challenges development throws at me.

I noticed that a lot of times developers accept, in some form, to do repetitive work. Whether it is about creating the release builds or testing their work. For me that was slightly a strange experience, I spent the better part of 25 years automating the shit out every thing I could think of. We as humans are not made to do repetitive work. Let a computer do that, that platform excels in doing repetitive work.

In the past years I always seem to become the guy responsible for the Continuous Integration Server, however it always was something to do on the side. Which is a shame, since when done properly, setting up and maintaining an CI/CD server is not something to do on the side. It is an equal part of work that needs to be done in a professional Development team. Sadly a lot of times management did not realise the importance of this part of the development process. Luckily this is changing and more understand and realise the need of such an environment.

When talking to Pro Warehouse I realised that there is a need for people like me, those that understand servers and understand the needs of a developer. So I’m happy that I get to bring my two areas of expertise together. System Engineering on the platform I love and building In-House applications that support the Digital Transformation that is happening in the Enterprise. In effect I turned into a DevOps engineer. One that is specialised in building native  platform applications. Wether they are iOS, tvOS, macOS or adding extensions to the Watch.

 

 

tvOS app version 2

Currently the app has some hard-coded URL’s to make it work when using the Seagate Wireless HD. It works, and when on holiday that is fine. However to improve the project I feel that I need to do some re-factoring.  And having some improvements to implement is also a nice way to improve my Swift skills.
As improvements I’ve come up with the following:

  • Capability to choose backend server
  • Remove Storyboard
  • Add XIB’s as interface files
  • Replace notifications with delegate (protocol) implementation.

The last three point I have already done, it turned out way easier then anticipated and I’m glad that I succeeded.

On the first item, it was a quick search on the interweb, to decide to use Swift as the language to use. And that turned out to be a real joy. Found a very nice book on the subject: “Server-Side Swift”. I really recommend it. The main reason to enjoy is that I’m able to develop the server app using Xcode, can easily run a debug build and best of set breakpoints! Very nice. I’ll post about the server app and points I encountered at a later date.

 

Moving into DevOps

For the last eleven months I was part of the team that worked on Philips HUE 2.0 app for iPhone. (While being employed by Sogeti)

We worked using TDD for this project. I did have some experience with writing Unit test, however that was still in iOS 6/7 so really some time ago. And there we only wrote them to test some business logic, like sorting of account number.

The TDD in this project is whole other ballgame. It is way harder to do TDD, the biggest pitfall is making your test case too big, so you lose context. Make your test small, so it is clear why you write the test.

Another problem I saw happening is that developers tend to try to test UIKit objects, in my opinion  you should test that piece of code that you wrote. The moment you try to recreate a complete UITableView in the setup of your test, you need to reconsider. Maybe place this test in the UI test framework, wether that is Apple’s or another i.e Calabash.

While doing the TDD, I was wondering about the release process and the troubles we always seem to encounter. Wether this release was for a sprint demo, or for a beta test does not matter. The problems I saw where always the same:

  • “Is this the right commit to use for the demo / release?”
  • “Shoot, the signing is again not working!! Why, oh why does Apple do this to me?”
  • “I hate releasing?
  • “Shoot, still some regression on this build and the demo is in, like, 10 minutes”
  • Big panic every time a release is needed.

In ending up doing the build needed on some developers Mac, who has the most chance of luck in getting the release build. Sound familiar? Well, to it was sounding more and more familiar. And I started to think about a solution to this, it should be possible to setup a work flow where can make releasing a non-issue, so we, the team, can focus on what we do best, create and improve features in your beloved app.  DevOps to the rescue! Thanks to the experience I have in System Engineering I was able to come up with a Continuous Delivery plan, that will make releasing easy peasy!

There are a lot of different tools available that help releasing easy. For iOS specific there is Fastlane, Fastlane can really help and provides a lot of different sub-tools. It is really easy in setting up and using it results in on simple command.

However I do feel that there is a lot of overlap in what the different tools do. And you really have to think about what you want to achieve and what tool (sub-tool of the tool) fits the bill best. Trying to use all sub-tools is a waste of time, in my opinion, since it will most likely not fit for 100%. It is better to have the overlap, then trying and failing to get the last step in that one tool.

I’m thinking in writing a couple of pieces on this subject, where I can merge all the different issues that needed to be solved in order in getting the releasing easier, without loosing measurable quality.