AWS Lambda with Single CloudFormation Template

This is just a quick snippet of CloudFormation template to deploy a Python 3.7 Lambda function embedded in the template. The source code inside ZipFile can contain up to 4KB.

# CloudFormation template
AWSTemplateFormatVersion: 2010-09-09
Type: AWS::Lambda::Function
- LambdaRole
- LambdaPolicy
ZipFile: |
import boto3
def handler(event, context):
Role: !GetAtt LambdaRole.Arn
Runtime: python3.7
Handler: index.handler

Note: the depending LambdaRole is not included, but can be found easily here .


Golang and Docker Multi-Stage Build

I have noticed a common pattern amonst some new utilities such as kubectl, kops and terraform: There’s only 1 single executable file to install, and by ‘install’ it can be put anywhere as long as it’s in $PATH. This was before I learned some Golang but it’s easy to find out that the reason behind this pattern is that they are all written in Go.

And in the containers’ realm, the new-ish multi-stage build steps of Docker released in 2017 are super beneficial to Golang containers. A TL;DR example looks like:

  1. use a 1GB Debian container with all Golang tools and build dependencies to build the Golang executable( FROM ... AS in the sample ).
  2. put the executable into a tiny run-time container such as Alpine Linux, resulting in a < 20MB container image(depending on the size of the app obviously) ( COPY --FROM in the sample )

A multi-stage ‘hello world’ Dockerfile looks like:

FROM golang:1.12.5-alpine3.9 as builder
RUN apk update --no-cache && \
apk add git
ADD ./ /app
RUN go build -o golang-test .

FROM alpine:3.9.4
RUN addgroup -g 2000 golang && \
adduser -D -u 2000 -G golang golang
USER golang
COPY --from=builder /app/golang-test .
CMD ["/app/golang-test"]

Note: To be able to use the multi-stage feature, the Docker version has to be > 17.06.


Install Nvidia 396 Driver for Ubuntu 18.04

Just some quick notes to upgrade Nvidia driver from 390 to 396 on Ubuntu 18.04. By default Ubuntu 18.04 only has Nvidia driver 390.

# add ubuntu official ppa for nvidia
# all commands below run as root
add-apt-repository ppa:graphics-drivers/ppa
apt update
# install 396 files
apt install nvidia-dkms-396 nvidia-driver-396 nvidia-compute-utils-396 libnvidia-compute-396
# reboot at the end.

After reboot, the new driver can be verified by:

| NVIDIA-SMI 396.54 Driver Version: 396.54 |
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| 0 GeForce GTX 1070 Off | 00000000:01:00.0 Off | N/A |
| 44% 67C P2 150W / 230W | 3211MiB / 8117MiB | 100% Default |


Home VPN with OpenVPN

Here are step to run a simple OpenVPN service at home, so that I can access home network easily while not at home.

First, clone the git repo for OpenVPN docker container:

git clone

I can use the pre-built docker image from docker hub but it has just been breached so I’d rather build it myself:

cd docker-openvpn && docker build -t openvpn .

Create a docker volume to persist data if the OpenVPN container to be rebuilt:

export $OVPN_DATA=ovpn_data
docker volume create --name $OVPN_DATA

Generate OpenVPN configurations, if there’s no DNS record for the server, use the public IP of the home broadband alternatively.

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM

Build a new secret key which will be used to generate user keys. I’d advise to use a strong password which can be saved in a password manager or vault. This is needed everytime when I create a new user.

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it openvpn ovpn_initpki

Then the OpenVPN server container can be run as a service:

docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN openvpn

Generate the first user profile. The password for secret key will be needed. Then retrieve the OpenVPN configuration with the 2nd command.

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it openvpn easyrsa build-client-full <username> nopass
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm openvpn ovpn_getclient <username> > <username>.ovpn

This .ovpn file can be used to configure OpenVPN client softwares on laptops or phones.

At last, ensure UDP 1194 port is forwarded to the host of the docker container. This is usually done in the home broadband router.