Daniel Purcell's Picture

Daniel Purcell

I'm Dan Purcell. I hope you enjoy my blog where I talk about my adventures in tech entrepreneurship and a myriad of other topics important to me.

St George, Utah 40 posts

Dan's 8 Tips for a Happy Marriage

In my opinion, one of the greatest sources of happiness that we can enjoy in this life comes from marriage. There's nothing else that can compare to the feeling of being in love, and being loved by someone in return. It's painful to be separated from the one you love, even for a day. You think of your spouse all day long, write love notes to your spouse, and hunger for your spouse's presence at your side.

Love in marriage adds beauty to life and gives one cause to love, work, and serve. A healthy and happy marriage requires work though. Here are nine tips I'd share to anyone looking to strengthen their marriage.

1. Draw close to God

I believe God is the source of all that which is good. He's the master at happiness in marriage and family. Through the Holy Ghost, scriptures, good examples around us, etc., I believe he can teach and lead any person on how to love their spouse and enjoy a happy marriage.

Putting God first also means striving with all your might to keep His commandments and to live a pure life. The closer we try to follow the Lord in all we do, avoid and overcome temptation, serve others, and be who God wants us to be, the more of His beautiful and positive influence we can feel in our lives.

2. Strive to be the very best person you can be, every day.

The great commandment is to love God with all your heart, might, mind, and strength. The second is like unto it, to love your neighbor as we love ourselves.

Loving ourselves is an important key to loving others. For years I confused humility with self loathing. I thought if I didn't compliment myself or if I didn't give myself much attention, it would turn into humility. I was very wrong. We need to be our #1 fan and to like ourselves, accept ourselves for who we are.

Once we accept ourselves for who we are, we can then have a healthy desire to become the best we can be. We should continually seek for ways to become better -- more patient, more selfless, more skilled in our work, a better listener, etc. In marriage, continually striving to be better is a great gift we can give our spouse.

3. Learn to love and accept your spouse for who they are

Once we develop a love for God and self, loving our spouse for who they are is the next natural step. There's a beautiful song by Bruno Mars called "Just The Way You Are", where the singer accepts and loves his wife exactly the way she is.

When our spouse knows that we love them just the way they are, criticism (one of the great poisons of marriage) fades away. We begin to appreciate the unique things about our spouse that add beauty to their character.

Another thought along this line is that once I realized that if my wife and I kept God's commandments long enough, one day we'll be perfected through Jesus Christ. One day I'll be married to a perfect person! But until then, I decided to enjoy my wife with all hers and my imperfections. In fact, I choose to celebrate our differences while we can because they won't be there forever!

4. Make intimacy (including sex) a high priority

God's given married people a wonderful, amazing gift. Sex is magical - it has a binding, cementing effect in marriage. There are fewer things I can think of that can bring as much peace, connectedness, satisfaction and joy in marriage!

But sex in marriage isn't like what the world teaches. The world's view of sex is empty and hollow, selfish and lustful. True sex in marriage is a deep connecting, mutually fulfilling, selfless loving experience that brings the very best of two people and makes them whole. It should truly be a love making experience.

My wife and I refer to each other as our "other whole" rather than her other half. Being one in marriage includes being one emotionally, spiritually, and physically.

To keep sex in marriage healthy and strong, I believe variety is important (variety is key to vitality). Try different positions, new locations, new ways to please each other. Make it romantic. Make it spontaneous. Make it fast. Make it slow. Make it more frequent. Sometimes you'll need to make a commitment to put it in your calendar.

One thing my spouse and I did to improve in this area is to come up with a pact of sorts, outlining a minimum frequency and how we plan to add variety to keep ourselves from falling into a rut.

Being romantic and keeping the spark alive in marriage is really fun too. Talk about sex often with your spouse -- share creative ideas of enjoying time together. Send love letters and text messages to each other to let the "other whole" know what you're thinking! :WINK:

One more note about this is that the best sex happens when both are fulfilled. Husbands, this might mean you let your wife come first. It begins by taking care of the dishes "just because", keeping a promise "just because", and listening to your wife share her feelings and facts about her day "just because". It's important that your wife knows you love her and care for her "just because", and that you're not expecting it to lead to anything. Emotional connectedness needs to precede physical connectedness.

When being intimate, it's important for husbands to remember that it takes most women 30 to 60 minutes to climax! Take your time and let her come first. The more enjoyable sex becomes for your wife, the more regular and higher priority it can become in your marriage.

5. Learn your spouse's love language

What is a loving act given by one spouse isn't always received the same way. For instance, I heard about a couple where every the day the husband did the dishes, helped with laundry, and many other household tasks out of love for his wife. But what his wife really wanted wasn't all of those chores done, but for her husband to sit and talk with her with no agenda. Once the husband figured this out, their marriage improved a lot!

There are many free online "discover your love language" questionnaires out there. Use Google to find one and take it with your spouse. It's interesting what you'll discover.

In my case, when I learned that giving quality time and attention to my wife makes the biggest deposits towards my wife's "emotional bank account," devoting my time and attention to her has become a regular part of our marriage. Find what matters to the other in your case and make a commitment to give more of it.

6. Schedule weekly dates

Dating after marriage is critical. Having a regularly scheduled time that you can count on will do wonders for your marriage. This became easier when our oldest child was old enough and responsible enough to be in charge of the younger kids while my wife and I went out for a few hours. My wife could count on Friday night being date night, for us to enjoy time together.

While on your date, turn off your phone's notifications, don't talk about kids (unless your spouse brings it up first), and focus on being present. If conversations get stale, prepare a list of "couple questions" to spur conversation. Share memories of fun things you've done together, and make plans for the future. Most importantly, have fun, relax, laugh, enjoy each other's company, and reconnect.

Putting effort into creative dating also goes a long way in saying "I love you". There are many blogs and websites with thousands of creative dating ideas to keep dating affordable and interesting.

7. Learn to talk and communicate

Learning how to talk about anything, including resolving problems and conflicts, is one of the greatest challenges and skills one can gain from marriage. Some marriages have little trouble in this area, while others struggle.

Learning to talk begins by making time to talk. It might be devoted to date night, or a set time every evening. Learning to talk includes learning how to listen without the intent to reply. Criticism kills communication.

Sharing your feelings and being vulnerable at times is an important aspect of couple communication. Being vulnerable means opening yourself up to your spouse about your dreams, desires, fears, wants, needs, cares, and concerns. It requires a lot of trust to be able to share your inmost feelings, as they're sensitive. Courage is required to be vulnerable. Respect is required to accept the other spouse's feelings. Over time, practicing being vulnerable while your spouse is accepting and non-judgmental builds great trust.

Sometimes a spouse wants to discuss problems, cares, concerns, fears, and so forth. The other spouse immediately counters and begins to offer suggestions to solve the problem. A problem-solving conversation sometimes isn't what the spouse wants and gets defensive quickly. Rather than jumping into problem-solving mode, just listening is what's needed most of the time. Just allowing the spouse to express concerns is enough to make things better alone.

There are times certain conflicts are best resolved in person. Text messages, for instance, don't carry the same tone of voice that speaking in person would resolve. Be sure to make time for face to face communication. Also remember that you can't force your spouse to talk or open up.

You can't force your spouse to change. The best way to "change" your spouse is to change yourself -- to selflessly love them, accept them, persuade them, be patient with them; in short to be meek and humble. If they choose to change, it would be a great blessing to both of you. If they don't want to change immediately, at least you'll still love them more than before anyway!

Communication takes serious effort. The reality is most marriages require a high level of mutual tolerance. Most marriages require a lot of effort to maintain open channels of communication. Most marriages require each spouse to make a conscious and consistent effort to bite one's tongue to refrain from criticism or defensive responses. Most marriages require a lot of patience.

8. Be Romantic

A wife wants a husband that gives her flowers, writes her love notes and hides them in places for her to find, plays love songs on the stereo, winks at her, holds her hand, takes her out, dances with her, massages her, flirts with her, texts or calls her, spends money on her, and remembers special occasions. A wife wants a husband that does romantic things "just because" -- for no other reason than that he thought of her.

With all the negative messages women receive about their appearance in magazines, movies, and social media, it's easy for women to constantly compare themselves to others. It's critical that husbands express how beautiful their wife is to him, and that he thinks his wife is amazing just the way she is.

Men like romance too. For most men, something more direct might be needed to get their attention and to feel loved by their wives. So ladies, don't be shy! Some examples include lingerie, sexts, being open and suggestive towards her husband now and then. Initiating romance, dates, and intimate moments is also very romantic for men.

In conclusion, marriages are meant to last forever. It takes work but the effort is worth it. I hope the tips above about putting God first, being the best person you can be, making lovemaking a higher priority, communicating, and being romantic are helpful in strengthening your marriage!

Using SSH Tunnels to create a poor man's Ngrok

At Velocity we use ngrok quite a bit to show some of our work to our clients before it goes live. However, there are some limitations with Ngrok -- the connection per second limit, being one of them.

So today we used some simple SSH tunneling to punch a hole through the firewall(s) to allow easy access to our clients.

In my set up, I have a publicly accessible server at avior.velocitywebworks.com. I can SSH into this server.

The first step is to edit my /etc/ssh/sshd_config file on the publicly accessible server (in this case, Avior) and add the following line:

GatewayPorts clientspecified  

This allows me to specify a publicly accessible tcp port when I tunnel in.

Next step is I created a new SSH connection to Avior like this:

ssh avior.velocitywebworks.com -R 0.0.0.0:8081:localhost:8081  

The first part after -R: 0.0.0.0:8081 is the remote address and IP I want to listen on. 0.0.0.0 is short hand for accepting a connection from anywhere. The second bit, localhost:8081 refers to my machine and port. I have a copy of the website running locally on my desktop at port 8081.

After logging in and keeping this SSH session open, I open my browser by going to http://avior.velocitywebworks.com:8081 and voila! The website on my desktop is now available for the public!

Two Concepts That Change The Way You Think about Hiring A Players

There's two books I've read that have influenced my thinking on hiring:

How To Hire A Players The book taught me a few things:

  • Always Be Interviewing. Even if you don't have an immediate position available, take the time to interview candidates that might fit. You never know if you'll need that talent at a future time. Explain to the candidate that you don't have an immediate position, but would enjoy a casual meeting at your office for a half hour to get to know them
  • Create a "farm team". The major league baseball teams have farm teams (minor leagues) where they draw from when they need talent in the major leagues. Some teams have farm teams for their farm teams. Of course you can't afford to create another company that only exists to grow talent, so you let other companies do the growing for you. Keep in touch with potential rising stars as they develop skills at other companies, and when the timing is right, invite them to join your organization.

Hire With Your Head by Lou Adler . This guy nails it -- I've had my share of hiring failures. I've hired people too much on impressive charisma rather than whether or not they're an achiever-type person that can do the job well. The book has a lot of advice on how to create useful job ads. The book also explains that only 7% of people that would be willing to make a job change are actively looking for a job, and usually it's the other 93% that have more talent anyway. He has some strategies on how to get to this group.

How To Install Your Django App on a Digital Ocean Droplet with NGINX, uWSGI, and Supervisor

Digital Ocean is a fntastic hosting platform for your Django site. In this blog post, I'll walk you through the steps I take to set up a Django site with Nginx as the front-end web server, uWSGI for the Django app, and Supervisor for managing the Django process. I'll also use MySQL for the database. We'll also use a virtual environment so that you can host multiple Django sites on the same host without running into python library version conflicts.

I'm assuming that you have a working Django project either developed locally or on another host. I'm also assuming you know what python virtual environments are (and that you're using one for your project). I'm also assuming that you use a Git repo (such as on github.com) to check your code into.

I'm also assuming you have a domain name registered that you'd like to point to your Digital Ocean droplet.

Although the tutorial below assumes Digital Ocean, the majority of the steps will work on other platforms that provide a Ubuntu Linux VM, such as Linode.

Get A Digital Ocean Droplet

First you'll need a Digital Ocean droplet. A Droplet is their term for a virtual machine. They have a few options to choose from. For beginner Django sites, a $10 / month droplet will be sufficient. I personally prefer using Ubuntu Server as my OS of choice, and the instructions below assume that option when the droplet is created.

If you're new to Digital Ocean, you're welcome to use my referral code if you want to to give yourself some free credit to try it out:

https://www.digitalocean.com/?refcode=4100c8d6bb9d

Part of the setup process requires you to give Digital Ocean your public key.

How to generate your SSH public key from a terminal (command line) in either Linux or Mac OS:

  1. Execute ssh-keygen if you don't have a file named ~/.ssh/id_rsa.pub. When it asks for a password, just hit Enter a few times (don't give it a password).
  2. To print your public key, run cat ~/.ssh/id_rsa.pub
  3. Copy and paste the output from the command above. Make sure to get the entire line, from ssh-rsa all the way to the end that has your username. Paste that into the area where you can add a key when setting up your droplet.

Less than 60 seconds later you should have a shiny new droplet you can log in to. After the VM has been created in Digital Ocean, you need to log in as root. Replace the IP below with the IP address of your new droplet:

ssh -l root 104.131.217.188

Generate Requirements.txt

The first step is to create a list of python packages needed in order to execute your Django app on Digital Ocean. After activating your virtual environment on your local copy of your Django project, do the following:

pip freeze > requirements.txt  

It's a good idea to track add requirements.txt to your git repo.

git add requirements.txt  
git commit -m "My requirements file" requirements.txt  
git push  

Install Packages

Here are the steps to install the Ubuntu packages:

add-apt-repository ppa:nginx/stable

apt update && apt upgrade

apt install nginx-full mysql-server supervisor git build-essential virtualenvwrapper python-mysqldb python-dev zlib1g-dev libjpeg-dev libmysqlclient-dev vim  

The system will ask you to set a master root password for MySQL. Remember to write down your root password for mysql, as you'll need it later on in this tutorial.

Add A User Account

Although it might be ok to be the root user when setting things up, eventually you'll want to create your own user account and perform actions as that user to be on the safe side.

Replace <username> with a username you want to use on the system:

adduser <username>  
adduser <username> www-data  
adduser <username> sudo  

become your user (test to make sure it works):

su <username>  

You can go back to being root by typing exit (or CTRL-D)

IMPORTANT: for the rest of this tutorial, I'm assuming you'll be performing these actions as your user that you created, not root. It's important to now either log out as root and log in as your user, or do the su command above to log in as your user.

Set Up Your Webroot

A webroot is where the files for your website and django site will be kept. Let's get it set up with the right permissions. I like to keep my sites in subdirectories of /var/www. The chown and chmod commands below adjust permissions.

sudo mkdir /var/www  
sudo chown www-data:www-data /var/www  
sudo chmod 775 /var/www  
sudo chmod +s /var/www  

The last line above, chmod +s, sets the sticky bit such that new subdirectories created in that directory will inherit the permissions of the /var/www directory by default.

Put Your SSH key from the Droplet VM on Github

We'll want to clone, pull, and push from the VM so now is a good time to generate a private and public SSH key you can add to your Github account (or wherever you store your git repo):

As your user, do the following. When ssh-keygen asks for a password, just hit Enter and go with the defaults.

ssh-keygen  
cat ~/.ssh/id_rsa.pub  

Copy that entire key to your Github account (under Settings->SSH Keys).

Pull Down Your Repo, set up Django

We'll pull down the files for Django project to the Droplet VM in this step. In the second step below, replace <repo> with the git clone URL from your github repository (usually looks like git@githumb.com:username/projectname.git)

cd /var/www  
git clone <repo>  

We'll now set up the Python virtual environment for your repo and install requirements. Note that we generated and checked in our requirements.txt file towards the beginning of this tutorial.

cd /var/www/REPO_NAME  
virtualenv venv  
source venv/bin/activate  
pip install -r requirements.txt  
pip install mysql-python  

If you run into errors installing python packages, it could be because the versions of the python packages and libraries used in your development environment differ from what your droplet will use. One suggestion is to make sure the requirements.txt in your development environment is fresh by doing another pip freeze. As packages get upgraded over time, old ones become discontinued and no longer available on Pypi. Updating the version number in your requirements.txt may solve the problem in those cases. When in doubt, Googling the problems one at a time may be the best way to resolve these conflicts.

It would be a good idea at this point to run a Runserver to see if your site runs. You can do a python manage.py runserver 0.0.0.0:8000 and point your browser to the public IP address of your droplet at port 8000 to see if your site comes up. Note that we haven't set up the database yet (it's the next step), so you may get some database-related errors.

Configure MySQL

First step is to create the database for your project. Replace PROJECTDATABASENAME with the database name you intend to use for your project (which you'll define in settings.py). The root password here is the MySQL root password you defined when you installed the MySQL server package earlier in this tutorial.

mysqladmin create PROJECT_DATABASE_NAME -u root -p  

Create the user account for the database that you'll use from your django app. In the example below, I used djangoproject as my username.

grant all privileges on PROJECT_DATABASE_NAME.* to 'djangoproject'@'%' identified by 'PROJECT_DB_PASSWORD';  

Now switch over to your project in /var/www and find your settings.py file. Edit your database settings accordingly:

DATABASES = {  
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'PROJECT_DATABASE_NAME',
        'USER': 'djangoproject',
        'PASSWORD': 'PROJECT_DB_PASSWORD',
        'HOST': 'localhost',
    }
}

Don't forget to migrate your database at this point. This will create the database tables. After activating your virtual environment (via the source venv/bin/activate command), run this:

python manage.py migrate  

Set up Nginx

In this tutorial, I'll use example.com for your website's domain name.

Create a /etc/nginx/sites-available/example.com.conf file. Here's a sample of what it should look like. I'm assuming my project got cloned down to /var/www/exampleproject and the actual Django project itself was also named exampleproject. I'm assuming my media and static folders are a subdirectory of the django project as well. I use vim as my text editor, but you can use nano or whatever you prefer to create this file.

server {  
        server_name example.com www.example.com;
        listen 80;

        root /var/www/exampleproject/exampleproject/media;

        location /static/ {
                alias /var/www/exampleproject/exampleproject/static/;
                expires 30d;
        } 

        location /media/ {
                alias /var/www/exampleproject/exampleproject/media/;
                expires 30d;
        } 

        location / {
                uwsgi_pass unix://tmp/example.com.nginx.sock;
                include uwsgi_params;
        } 
} 

Now we need to tell Nginx that this is a site to be enabled at startup:

cd /etc/nginx/sites-enabled/  
sudo ln -s ../sites-available/example.com.conf .  

Install uWSGI, set up uWSGI

uWSGI is a fantastic python package to run Django sites. It has many many features. We won't go into the details of uWSGI itself in this tutorial, but we'll cover how to install it and set it up.

First, make sure you've enabled your virtual environment:

cd /var/www/REPO_NAME  
source venv/bin/activate  

Then, install uwsgi into your virtual environment:

pip install uwsgi  

Once it's installed, make a note of where it installed to (while still in your virtual environment):

which uwsgi  

Write down the output. On my system, it puts it in /var/www/PROJECT_NAME/venv/bin/uwsgi. You'll need this full path in the section below when we set up Supervisor.

uWSGI can take a configuration file for adjusting command options. Create a /var/www/PROJECT_NAME/config.ini file. I use vim as my text editor, but you can use nano or whatever you prefer to create this file.

Some notes:

  • In the chdir line below, you'll want to set this to the same directory where your manage.py file lives.
  • For module: Recent Django setups generate a wsgi.py file for you automatically. You'll set this to your django project's foldername, "dot", wsgi, as in the example below:
[uwsgi]
home=/var/www/PROJECT_NAME/venv  
chdir=/var/www/PROJECT_NAME/DJANGO_PROJECT_NAME  
socket=/tmp/crminal.co.nginx.sock  
chmod-socket=777  
chown-socket=www-data  
module=djangoproject.wsgi  
vacuum=true  
master=true  
max-requests=2000  
touch-reload=config.ini  
workers=2  
harakiri-verbose=true  
harakiri=180  
stopsignal=TERM  

Set Up Supervisor

Supervisor is a program that starts other programs and makes sure they stay running. If the program exits for any reason, it will restart it. It's a nifty and solid way to execute your Django apps. You'll eventually want one configuration file in Supervisor for every Django app you want to run from your site.

We'll be creating a /etc/supervisor/conf.d/example.com.conf file (replace example.com with your domain name of your django project). Where it says command, put in the full path to your uwsgi executable we jotted down in the previous section (when we ran the which uwsgi command). Also, after program:, you give your program a name. I don't think it can contain dots, so I just put the domain name without the .com or whatever ending you have for your domain.

[program:website]
command = /var/www/PROJECT/venv/bin/uwsgi --ini /var/www/PROJECT/config.ini --uid=www-data --gid=www-data  

We'll want to make sure Supervisor starts automatically if the VM ever gets rebooted. Execute this command to tell Ubuntu to start the supervisor service at bootup:

sudo update-rc.d supervisor defaults  

Start It Up!

This is the most exciting step. This is when we're going to execute everything we've set up:

sudo service supervisor restart  
sudo service nginx restart  

Get Static Files Ready

You may already have this in your settings.py, but just to be safe, make sure you have your STATICROOT setting defined correctly in settings.py. Be sure to have it pointing to the full path to where STATICROOT is on your server.

If you haven't, create a static directory in your project root (same directory where manage.py lives). Note that the path to this static folder should match the line in your nginx.conf, as it will be Nginx (not uwsgi) that serves your static files.

Then, collect static files:

python manage.py collectstatic  

MISC Tips

How to reload Nginx after a configuration change:

sudo /etc/init.d/nginx reload  

How to restart uWSGI via Supervisor:

sudo supervisorctl  
restart <program name>  

After making a change to your Django app, you can restart it via the supervisor command above or do this cool trick to reload it:

touch /var/www/DJANGO_PROJECT/config.ini  

Conclusion

It's rewarding to set up and run your own Django apps on Digital Ocean (or any VM). If there are some steps that aren't clear or errors above, please leave a note in the comments and I'll see if I can clarify the steps above.

The One Thing (Book Review)

I'm reading (listening) to a book called The One Thing. Here are the nuggets I've learned from this book so far:

  • Getting one thing done well is better than having many things undone or not done well. This means needing to ignore other demands to focus on the one and most important thing.
  • The Domino Effect. There's leverage. Doing one thing can lead to another, and then to another. Find the dominos and put them in order.
  • The Prado Principle. 80% of your success comes from 20% of your efforts. Discover what the "20%" is and focus on just that.
  • Not everything you do has equal impact. The message of the book is to focus hard on the things that make the biggest impact towards achieving your goals, and let the other things go. This applies to your career. For family life, health, and other things, you need to keep those things going though.
  • I liked the concept of blocking 4 hours a day on focusing on the high impact items.
  • You need to think big. You can only grow as large as you let your mind expand to.