-
Damn I Love Docker: OpenVPN Server
Table of Contents
Installing OpenVPN
AMD64
NOTE: The following quick start install is from kylemanna’s documentation1 and uses his docker image.2
-
Pick a name for the
$OVPN_DATA
data volume container. It’s recommended to use theovpn-data-
prefix to operate seamlessly with the reference systemd service. Users are encourage to replaceexample
with a descriptive name of their choosing.OVPN_DATA="ovpn-data-example"
-
Initialize the
$OVPN_DATA
container that will hold the configuration files and certificates. The container will prompt for a passphrase to protect the private key used by the newly generated certificate authority.docker volume create --name $OVPN_DATA docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn ovpn_initpki
-
Start OpenVPN server process
docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
-
Generate a client certificate without a passphrase
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
-
Retrieve the client configuration with embedded certificates
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
ARMhf
NOTE: The following is the same install instructions as the AMD64, but use an armhf image for the Raspberry Pi.
-
Pick a name for the
$OVPN_DATA
data volume container. It’s recommended to use theovpn-data-
prefix to operate seamlessly with the reference systemd service. Users are encourage to replaceexample
with a descriptive name of their choosing.OVPN_DATA="ovpn-data-example"
-
Initialize the
$OVPN_DATA
container that will hold the configuration files and certificates. The container will prompt for a passphrase to protect the private key used by the newly generated certificate authority.docker volume create --name $OVPN_DATA docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm tigerj/rpi-ovpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it tigerj/rpi-ovpn ovpn_initpki
-
Start OpenVPN server process
docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN tigerj/rpi-ovpn
-
Generate a client certificate without a passphrase
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it tigerj/rpi-ovpn easyrsa build-client-full CLIENTNAME nopass
-
Retrieve the client configuration with embedded certificates
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm tigerj/rpi-ovpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
References
-
-
Reformatting Disk Drive on Linux to ext4: parted command
Table of Contents
Introduction
This walkthrough for reformatting a drive (already formatted) to
ext4
on Linux is inspired heavily from the sources found in the reference section. The only difference is some added clarity and detail for the reformatting processWalkthrough
What follows is a short walkthrough for finding a disk connected to the system, removing a partition, and making a new partition.
Find Device Name
First, physically connect the drive to the system, either through USB (for external drives like on the RPi) or through SATA on the motherboard (i.e. for PCs). Once connected, the device can be found using the
lsblk
command like so:$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 4.6T 0 disk └─sda1 8:1 0 4.6T 0 part mmcblk0 179:0 0 59.6G 0 disk ├─mmcblk0p1 179:1 0 41.8M 0 part /boot └─mmcblk0p2 179:2 0 59.6G 0 part /
The above example output was taken from a Raspberry Pi 2. The device labeled
sda
is a Seagate 5TB External Hard Drive, whereas themmclk0
is the micro SD card that is formatted with the Raspibian OS. The important thing here, is we now know which device is our Hard Drive.If we do a quick
ls /dev
, we can see ALL devices connected to the system:$ ls /dev autofs loop6 ram5 tty18 tty43 uhid block loop7 ram6 tty19 tty44 uinput bsg loop-control ram7 tty2 tty45 urandom btrfs-control mapper ram8 tty20 tty46 vchiq bus mem ram9 tty21 tty47 vcio cachefiles memory_bandwidth random tty22 tty48 vc-mem char mmcblk0 raw tty23 tty49 vcs console mmcblk0p1 rfkill tty24 tty5 vcs1 cpu_dma_latency mmcblk0p2 sda tty25 tty50 vcs2 cuse mqueue sda1 tty26 tty51 vcs3 disk net serial0 tty27 tty52 vcs4 fb0 network_latency sg0 tty28 tty53 vcs5 fd network_throughput shm tty29 tty54 vcs6 full null snd tty3 tty55 vcs7 fuse ppp stderr tty30 tty56 vcsa gpiochip0 ptmx stdin tty31 tty57 vcsa1 gpiomem pts stdout tty32 tty58 vcsa2 hwrng ram0 tty tty33 tty59 vcsa3 initctl ram1 tty0 tty34 tty6 vcsa4 input ram10 tty1 tty35 tty60 vcsa5 kmsg ram11 tty10 tty36 tty61 vcsa6 log ram12 tty11 tty37 tty62 vcsa7 loop0 ram13 tty12 tty38 tty63 vcsm loop1 ram14 tty13 tty39 tty7 vhci loop2 ram15 tty14 tty4 tty8 watchdog loop3 ram2 tty15 tty40 tty9 watchdog0 loop4 ram3 tty16 tty41 ttyAMA0 zero loop5 ram4 tty17 tty42 ttyprintk
Without going into great detail about what all these “devices” are, we can see that in the third column our device
sda
is located. WARNING: If you have more than one drive connected, the label they are given may change. This means that you cannot count on the drive to always be labeledsda
. If there are two drives connected, one will be labeledsda
and the othersdb
, BUT there is no guarantee which will get which label … it can change between reboots etc … Always check withlsblk
or other commands (i.e.sudo fdisk -l
) which drives have been labeled which device files.Now we can move on to using the
parted
command.Parted Command1
Now that we are clear we have the right drive, fire up an interactive parted session by launching the following (using the device file name we found for our drive earlier):
$ sudo parted /dev/sda GNU Parted 3.2 Using /dev/sda Welcome to GNU Parted! Type 'help' to view a list of commands. (parted)
If we type help we can see the potential reformatting options:
(parted) help align-check TYPE N check partition N for TYPE(min|opt) alignment help [COMMAND] print general help, or help on COMMAND mklabel,mktable LABEL-TYPE create a new disklabel (partition table) mkpart PART-TYPE [FS-TYPE] START END make a partition name NUMBER NAME name partition NUMBER as NAME print [devices|free|list,all|NUMBER] display the partition table, available devices, free space, all found partitions, or a particular partition quit exit program rescue START END rescue a lost partition near START and END resizepart NUMBER END resize partition NUMBER rm NUMBER delete partition NUMBER select DEVICE choose the device to edit disk_set FLAG STATE change the FLAG on selected device disk_toggle [FLAG] toggle the state of FLAG on selected device set NUMBER FLAG STATE change the FLAG on partition NUMBER toggle [NUMBER [FLAG]] toggle the state of FLAG on partition NUMBER unit UNIT set the default unit to UNIT version display the version number and copyright information of GNU Parted
Remove Partition
We can see that
rm NUMBER
will delete a partition, but how do we know what are the partitions? Simple, we runprint
like so:(parted) print Model: Seagate Expansion Desk (scsi) Disk /dev/sda: 5001GB Sector size (logical/physical): 512B/4096B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 5001GB 5001GB ext4 primary
Here we see that we have one partition. To remove it simply type:
(parted) rm 1
Simply repeat this with all partitions you want to remove (i.e.
rm 2
,rm 3
). Now let us look at adding a new partition.Adding Partition2
First to add a new partition, we can exit the interactive session and simply call
parted
and pass the commands to it. We will do this to set the new partition standard (this assumes you have a fresh drive, or have already removed all the partitions before usingrm NUMBER
):$ sudo parted /dev/sda mklabel gpt
Now we can create a new partition spanning the whole disk:
$ sudo parted -a opt /dev/sda mkpart primary ext4 0% 100%
This will create one primary partition with the
ext4
format (which parted does not support formatting). Now we are ready to add anext4
file system to this partition.Formatting ext4
Finally we only need to run a simple command to complete the reformatting of the drive, with a new partition in the
ext4
format:$ sudo mkfs.ext4 -L OPTIONAL_DISK_NAME /dev/sda1
This will create the
ext4
file system on the partition at/dev/sda1
we created earlier. The-L
flag will set the label of the partition to whatever you set asOPTIONAL_DISK_NAME
. This is optional and not necessary.Summary
The drive is now completely reformatted with a fresh partition. You can now mount this drive:
$ sudo mount -t ext4 /dev/sda1 /mnt/DISK_NAME
At last, your new drive is ready to use!
References
-
Damn I Love Docker: UniFi Controller
Table of Contents
Installing UniFi Controller
AMD64
docker create \ --name=unifi \ -v <path to data>:/config \ -e PGID=<gid> -e PUID=<uid> \ -p 3478:3478/udp \ -p 10001:10001/udp \ -p 8080:8080 \ -p 8081:8081 \ -p 8443:8443 \ -p 8843:8843 \ -p 8880:8880 \ -p 6789:6789 \ linuxserver/unifi
ARMhf
To run the dockerized UniFi Controller on an armhf device (like a Raspberry Pi),
docker create \ --name=unifi \ -v <path to data>:/config \ -e PGID=<gid> -e PUID=<uid> \ -p 3478:3478/udp \ -p 10001:10001/udp \ -p 8080:8080 \ -p 8081:8081 \ -p 8443:8443 \ -p 8843:8843 \ -p 8880:8880 \ -p 6789:6789 \ lsioarmhf/unifi
References
-
Damn I Love Docker: Plex Media Server
Table of Contents
- Introduction
- Plex Media Server
- Installing Plex
- Running Plex
- Accessing Plex
- Initial Configurations
- Advanced Configurations
- References
Introduction
When you begin to research “how” to stream your media collection to your devices, you will find one simple conclusion is unavoidable: the most common way to stream media to your devices is Plex.
Plex is everywhere, and it is used ALL the time !!!
Installing Plex
In the below sections, you will find the commands for creating a docker container of the LinuxServer.io1 Plex Media Server.2 Thanks to the introduction of
docker manifest
you do not need to worry about the architecture of your docker host (e.g. amd64 vs. arm), just execute the following commands on your docker host.3Before looking at the command, it is useful to clarify and briefly explain some of the options and variables passed to the
docker create
4 command:--net=host
- Shares host networking with container, required.-v /config
- Plex library location. This can grow very large, 50gb+ is likely for a large collection.-v /data/xyz
- Media goes here. Add as many as needed e.g./data/movies
,/data/tv
, etc.-e VERSION=latest
- Set whether to update plex or not - see Setting up application section.-e PGID=
for for GroupID - see below for explanation-e PUID=
for for UserID - see below for explanation-e TZ
- for timezone information eg Europe/London, Asia/Shanghai, etc
Sometimes when using data volumes (
-v
flags) permissions issues can arise between the host OS and the container. This can be avoided by specifying the user PUID and group PGID. Ensure the data volume directory on the host is owned by the same user you specify and it will “just work.”To find yours use
id $USER
as below:$ id $USER uid=1001(dockeruser) gid=1001(dockergroup) groups=1001(dockergroup)
So from this information, we can see that
uid=1001
, andgid=1001
. Hence when we run thedocker create
command below, we will setPUID=1001
andPGID=1001
.What follows is the docker command for pulling the LinuxServer.io1 docker image and creating a container to run the Plex Media Server.
docker create \ --name=plex \ --net=host \ -e PUID=<UID> -e PGID=<GID> \ -v </path/to/library>:/config \ -v <path/to/tvseries>:/data/tvshows \ -v </path/to/movies>:/data/movies \ linuxserver/plex
NOTE: As an example for the Raspberry Pi, we will likely want to consider using an external drive to store the Movies and the Plex configuration directories. This is due to the more robust I/O capabilities of a Hard Disk Drive vs. a micro SD card.5 More information on the formatting process of the drive can be found in another post6 devoted to reformatting a hard disk drive in ext4.
Once we have our external drive ready (in this case mounted to
/mnt/PIDRIVE
), we can create the container as follows:docker create \ --name=plex \ --net=host \ -e VERSION=latest \ -e PUID=1001 \ -e PGID=1001 \ -e TZ='America/Chicago' \ -v /mnt/PIDRIVE/plex_config:/config \ -v /mnt/PIDRIVE/movies:/data/movies \ linuxserver/plex
Notice here that we have
PUID=1001
andPGID=1001
,TZ=America/Chicago
,/mnt/PIDRIVE/plex_config:/config
, and/mnt/PIDRIVE/plex_config:/data/movies
. Basically, the results of theid $USER
showeduid=1001
andgid=1001
, hence the user setPUID=1001
andPGID=1001
, the user set the timezone toAmerica/Chicago
, and has created their Plex config dir on their external drive at/mnt/PIDRIVE/plex_config
with all of their media on the same external drive at/mnt/DATADRIVE/movies
.Running Plex
Now that our docker container has been created, we can simply run it with:
$ docker start plex
This will start the container, and run it as a daemon (i.e. in the background).
Accessing Plex
Now that the docker container for Plex has been built and is running on your server, you can access it. The most basic way to access the Plex application is through the WebUI by navigating in your browser to the following URL:
HOST_IP_ADDRESS:32400/web
This could be something like:
raspberrypi.local:32400/web
Or maybe:
gnosis.local:32400/web
Or simply use the local IP address of the host:
192.168.10.20:32400/web
Initial Configuration
Without going into too much detail, the initial setup will require two parts:
- 1: You will be prompted to login or create a Plex account
- 2: You must select where the media is stored that will be used with Plex
Basically after creating a Plex account, or logging in to an existing account just make sure to add a Movie library, and use the path to
/data/movies
as the path to where the media are located. More detailed information can be found in the official Plex post7Advanced Configurations
In this section we will discuss the various advanced features of both Plex, and the host operating system for configuring your system for various needs (e.g. backing up your media, downloading subtitles automatically, etc …)
Backing Up Media and Data
One of the best ways to backup any Unix-like system is through a utility known as
cron
. While we will not discuss in detail how to edit acrontab
, we will refer you to a previous post on the subject.Instead we will show you an example of a
crontab
entry that will backup the external drive containing all your media files and Plex data to another external drive:$ sudo crontab -e ... ... ... # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,$ # | | | | | # * * * * * user-name command to be executed # backup PIDRIVE to PIBACKUP 01 01 * * * sudo rsync -havP /mnt/PIDRIVE/ /mnt/PIBACKUP/
What the above example shows, is that the
rsync
command will run withsuper user
privileges at 01:01 am or one minute past one in the morning (or late at night if you are not a morning person). When it runs it will backup the contents of the drive at/mnt/PIDRIVE
to/mnt/PIBACKUP
. This will ensure that every night at one minute past one in the morning, the drive with all your Plex data and media, will be copied to the drive at/mnt/PIBACKUP
References
-
Meta Solution: The Structure of Problem Solving
Table of Contents
Introduction
In my personal experience with problem solving I have found that time and time again, there is no real “philosophy” of problem solving.1 And with that lack of literature, I have been tasked with defining my own philosophy of sorts for understanding, and thinking about problem solving.
To that purpose, I have frequently found my self thinking most determinedly on a singular question: Is there such a process that will ensure, know matter what is known or unknown to you, the acquisition of the solution to the problem you are faced with? The short answer is yes: structure. The long answer is where we shall focus our explication.
The Nature of Problems
Searching Algorithms
References