WEBVTT

00:00:00.001 --> 00:00:05.140
Today we explore the wild world of Python deployment with my friend Calvin Hendryx-Parker from 6 Feet Up.

00:00:05.760 --> 00:00:16.960
We'll tackle some of the biggest challenges in taking a Python app from "it works on my machine" to production, covering inconsistent environments, conflicting dependencies, and sneaky security pitfalls.

00:00:17.740 --> 00:00:25.760
Along the way, Calvin shares how containerization with Docker and Kubernetes can both simplify and complicate deployments, especially for smaller teams.

00:00:26.040 --> 00:00:34.980
Finally, we'll introduce Scaf, a powerful project blueprint designed to give developers a rock-solid start on Python web projects of all sizes.

00:00:35.600 --> 00:00:42.040
This is Talk Python To Me, episode 496, recorded Tuesday, January 21st, 2025.

00:00:43.330 --> 00:00:45.240
Are you ready for your host, please?

00:00:45.790 --> 00:00:48.720
You're listening to Michael Kennedy on Talk Python To Me.

00:00:49.220 --> 00:00:52.560
Live from Portland, Oregon, and this segment was made with Python.

00:00:55.640 --> 00:00:58.520
Welcome to Talk Python To Me, a weekly podcast on Python.

00:00:58.860 --> 00:01:00.700
This is your host, Michael Kennedy.

00:01:01.140 --> 00:01:13.960
Follow me on Mastodon, where I'm @mkennedy, and follow the podcast using @talkpython, both accounts over at fosstodon.org, and keep up with the show and listen to over nine years of episodes at talkpython.fm.

00:01:14.400 --> 00:01:18.440
If you wanna be part of our live episodes, you can find the live streams over on YouTube.

00:01:18.860 --> 00:01:24.820
Subscribe to our YouTube channel over at talkpython.fm/youtube and get notified about upcoming shows.

00:01:25.480 --> 00:01:29.160
This episode is sponsored by Posit Connect from the makers of Shiny.

00:01:29.680 --> 00:01:33.680
Publish, share, and deploy all of your data projects that you're creating using Python.

00:01:34.160 --> 00:01:40.320
Streamlit, Dash, Shiny, Bokeh, FastAPI, Flask, Quarto, Reports, Dashboards, and APIs.

00:01:41.140 --> 00:01:42.740
Posit Connect supports all of them.

00:01:43.000 --> 00:01:48.380
Try Posit Connect for free by going to talkpython.fm/posit, P-O-S-I-T.

00:01:49.540 --> 00:01:52.600
And it's brought to you by my new book, Talk Python in Production.

00:01:53.120 --> 00:02:00.680
I've long felt that most guidance and marketing about how we need to run Python apps in production has been overly complex and expensive.

00:02:01.100 --> 00:02:07.280
This book is both a look at the history of Talk Python To Me and an antidote to this overly complex cloud world.

00:02:07.920 --> 00:02:12.480
Read it online and get the full book at talkpython.fm/devopsbook.

00:02:14.000 --> 00:02:16.720
This episode has something unique and special.

00:02:17.430 --> 00:02:29.980
I thought it'd be fun if I could come up with a song that was about deploying code, about Kubernetes, about the cloud, all the different things that Calvin's gonna come on and tell us all about.

00:02:30.560 --> 00:02:33.760
I turned that into a song and I stuck it at the end of the show.

00:02:33.880 --> 00:02:40.120
I wanted to put it at the beginning, but it's three minutes or so long and I think it might take away from getting right into the episode.

00:02:40.700 --> 00:02:44.840
So if you're interested in that, you can check out the song, it's called "Deploy the Dream".

00:02:45.040 --> 00:02:50.700
It's at the very end, almost the end, that lasts maybe another 45 seconds after that.

00:02:51.100 --> 00:02:58.080
And you'll find the link to the standalone song and MP3 file right on the episode page in the link section or in your podcast player show notes.

00:02:58.460 --> 00:02:59.140
I hope you love it.

00:02:59.200 --> 00:03:02.320
It was a lot of fun to create and I think it'll make a lot of you smile out there.

00:03:03.060 --> 00:03:05.180
Quick announcement before we jump into the show.

00:03:05.780 --> 00:03:12.720
I recently completely re-imagined and rewrote the effective PyCharm course.

00:03:13.360 --> 00:03:26.400
So if you wanna be effective with an IDE and use professional tools to build your Python applications, you should give my new and updated course, Effective PyCharm, a look.

00:03:27.040 --> 00:03:28.560
You'll find it at talkpython.fm.

00:03:28.840 --> 00:03:31.420
Just click on courses in the menu at the top.

00:03:31.700 --> 00:03:36.720
And if you were already in the prior version of the course, it's been automatically updated for you.

00:03:36.900 --> 00:03:39.420
So you'll have access to the new course right away.

00:03:39.730 --> 00:03:40.780
Head on over and check it out.

00:03:41.500 --> 00:03:46.660
And if you have one of our everything bundles that gives you access to all of our courses in the library.

00:03:47.160 --> 00:03:51.740
Well, you also have access to this course, assuming the original was in your bundle.

00:03:52.200 --> 00:03:54.720
Thanks to everyone who's taking courses over there and checking it out.

00:03:54.840 --> 00:03:55.900
This is a really fun course.

00:03:56.010 --> 00:03:58.580
I think you'll get a ton out of it if you haven't taken it yet.

00:03:58.910 --> 00:04:00.560
And with that, let's jump into the show.

00:04:01.380 --> 00:04:03.420
Alvin, welcome to Talk Python To Me.

00:04:03.720 --> 00:04:05.460
Great to finally have you on the show.

00:04:05.560 --> 00:04:06.880
What have you been doing all this time?

00:04:07.440 --> 00:04:09.060
- I don't know, not being on your show, I guess.

00:04:09.160 --> 00:04:17.100
I actually was super excited when you asked that I could be on here, This has been like a life goal, at least a goal since Talk Python To Me has ever existed.

00:04:17.269 --> 00:04:18.959
>> I really appreciate that. That's very kind.

00:04:19.239 --> 00:04:23.680
Well, it's great to have you on here and I am all about DevOps and deployment these days.

00:04:23.680 --> 00:04:28.440
I think it's another superpower that I think people can really have.

00:04:28.960 --> 00:04:33.760
You've got an idea, you want to deploy the dream as the song that we'll play later, we'll say.

00:04:34.040 --> 00:04:37.020
If you're not familiar with this stuff, it's a huge roadblock.

00:04:37.280 --> 00:04:41.120
I built this thing, but how do I get it up there and how can I keep it running?

00:04:41.980 --> 00:04:42.120
- Yeah.

00:04:42.440 --> 00:04:49.260
- And so what we're gonna talk about is a framework you all have created to make this much more automated and easy and packaged up, if you will.

00:04:49.560 --> 00:04:49.860
- Yeah, I agree.

00:04:49.980 --> 00:04:58.440
I mean, part of the developer experience, not just the deployment story, but how do I make a developer be productive from day one?

00:04:58.720 --> 00:05:01.680
Like I get super obsessed about the experience.

00:05:01.740 --> 00:05:02.760
Like, is it smooth?

00:05:02.900 --> 00:05:03.480
Is it easy?

00:05:03.620 --> 00:05:07.180
Can developers like join your organization and be productive right away?

00:05:07.320 --> 00:05:11.020
Like that's important to me as a owner of a business who produces software.

00:05:11.900 --> 00:05:12.560
We'll start there.

00:05:13.400 --> 00:05:13.740
Who are you?

00:05:13.940 --> 00:05:14.420
What is your business?

00:05:14.500 --> 00:05:14.980
What do you do?

00:05:15.280 --> 00:05:16.420
Set the stage for everyone.

00:05:16.680 --> 00:05:16.940
- All right.

00:05:17.400 --> 00:05:18.540
So my name's Calvin Hendryx-Parker.

00:05:18.780 --> 00:05:20.960
I am CTO and co-founder of Six Feet Up.

00:05:21.200 --> 00:05:30.140
We are a Python and AI for good software agency based out of the Midwest here in Indiana, but we have folks all across the country and a few folks across the globe.

00:05:30.720 --> 00:05:34.200
We help impactful tech leaders level up their game.

00:05:34.420 --> 00:05:39.780
Like if you've got an idea and you can see the future, our part of our goal is to make that happen.

00:05:39.940 --> 00:05:44.360
Like we love tackling the super hard software problems.

00:05:44.720 --> 00:05:47.580
The harder the better and the more unique and the more impactful the better.

00:05:48.020 --> 00:05:55.340
Part of our goal has been to do 100 impactful projects by 2033 and those impactful projects are things that are making the world a better place.

00:05:55.900 --> 00:06:04.160
So some of our projects do actually impact climate or energy, done some stuff with NASA on space travel.

00:06:04.520 --> 00:06:08.840
So it's cool stuff like that that the people who work at Six Feet Up get super excited about.

00:06:09.020 --> 00:06:12.520
And like part of what drives me to do what we do every day for sure.

00:06:12.840 --> 00:06:12.940
Yeah.

00:06:13.180 --> 00:06:14.500
And to get to work on space travels.

00:06:14.860 --> 00:06:15.220
Oh man.

00:06:16.160 --> 00:06:17.860
It's like, I'm getting up early today.

00:06:17.880 --> 00:06:18.360
I'm going to work on space travels.

00:06:18.360 --> 00:06:19.220
It's literally rocket science.

00:06:19.340 --> 00:06:20.160
Literally rocket science.

00:06:20.460 --> 00:06:20.800
Yeah.

00:06:21.180 --> 00:06:21.580
How amazing.

00:06:21.680 --> 00:06:23.540
And you've been doing Python for a long time.

00:06:23.600 --> 00:06:25.880
You've been involved since the early days, right?

00:06:26.000 --> 00:06:26.280
Yeah.

00:06:26.460 --> 00:06:30.200
I first adopted or touched Python in literally the year 2000.

00:06:30.620 --> 00:06:31.440
I started working on it.

00:06:31.660 --> 00:06:39.460
I was in a startup in the Bay Area and the guy sitting next to me was like, check out this Python based application server called Zope.

00:06:39.680 --> 00:06:42.160
And at that point in time in my life, I had just graduated college.

00:06:42.160 --> 00:06:46.340
I think I understood the three words in between all the other words that he just said.

00:06:46.620 --> 00:06:49.040
And so that was a whole new world that got opened up to me.

00:06:49.360 --> 00:06:55.140
And so I started out my journey in Python really with Zope as the kind of the first thing that got me in.

00:06:55.420 --> 00:07:00.720
But back in that day, like Zope and BitTorrent were kind of the killer apps for Python.

00:07:01.360 --> 00:07:06.640
Folks remember there were like Zope tracks at PyCon And my keynotes were like around Zope.

00:07:06.680 --> 00:07:07.680
It was the thing.

00:07:07.720 --> 00:07:13.460
And I still attribute that community to really bringing me into Python and getting me engaged.

00:07:13.580 --> 00:07:19.000
It's some of the smartest people I've ever worked with who are part of that open source community who made that a thing.

00:07:19.000 --> 00:07:20.380
And I'm still friends with those people today.

00:07:20.480 --> 00:07:22.660
You know, people like Paul Everett and Trey Seaver.

00:07:22.940 --> 00:07:26.840
And those folks were really part of my upbringing into the Python community.

00:07:26.920 --> 00:07:28.580
And I can't thank them enough.

00:07:28.820 --> 00:07:29.140
That's awesome.

00:07:29.240 --> 00:07:29.440
You

00:07:29.440 --> 00:07:47.740
know, there's a really interesting fact that was shown at least amongst survey respondents in the PSF JetBrains survey, I can't pull out of it, that, that I would say 40% of the people who are doing Python these days are two years or less into it, which is an incredible statistic.

00:07:48.850 --> 00:07:51.480
I think 30%, 30% or so is this is their first year.

00:07:51.700 --> 00:07:53.700
And then, you know, the rest of the second year.

00:07:54.020 --> 00:07:57.860
So we're amongst the rare birds, but the reason I bring that up 25

00:07:57.860 --> 00:07:59.380
years later, we're still here doing it.

00:07:59.880 --> 00:08:00.120
Exactly.

00:08:00.600 --> 00:08:05.920
the reason I bring that up is, you know, I suspect people who've been at this for three or four years, maybe don't know what ZOPE is.

00:08:05.920 --> 00:08:10.560
They probably heard the word, but they're like, yeah, is that, is that like a thing that Django does?

00:08:11.800 --> 00:08:13.140
Tell people what ZOPE is like.

00:08:13.880 --> 00:08:19.480
I mean, the application framework space back in the, in the 2000s was not a crowded space.

00:08:19.600 --> 00:08:20.800
There weren't many options.

00:08:20.860 --> 00:08:24.220
And I think the beauty of what the app, the ZOPE was an application framework.

00:08:24.530 --> 00:08:26.300
It had some interesting opinions.

00:08:26.880 --> 00:08:36.260
One of them being the ZODB, which I still do love to this day, which is an object graph database that enabled you to build applications quickly.

00:08:36.479 --> 00:08:39.860
And I think initially one of their goals was through the web even.

00:08:40.140 --> 00:08:46.940
Like if you remember Z-classes, you could build and rapid prototype through the web in your browser.

00:08:47.220 --> 00:08:48.300
I mean, this is the year 2000.

00:08:48.940 --> 00:08:51.560
This is not last year where people were like, "Wow, cool.

00:08:51.580 --> 00:08:54.840
This is a low-code thing." This was that 25 years ago.

00:08:54.840 --> 00:08:55.900
>> This was ahead of its time.

00:08:55.940 --> 00:08:57.120
- He's way ahead of his time.

00:08:57.340 --> 00:08:59.900
Now, granted, I don't think that was not the future.

00:08:59.960 --> 00:09:00.880
That shouldn't be the future.

00:09:01.140 --> 00:09:06.400
I'm actually hoping to give some conference talks this year about low code, no code, in my opinions on that.

00:09:06.880 --> 00:09:09.940
Especially, I should frame it in my context of Zope and Z-Classes.

00:09:10.900 --> 00:09:12.580
But maybe that's too much of an inside joke.

00:09:12.620 --> 00:09:16.040
I don't know if enough people would even understand what I'm talking about there.

00:09:16.760 --> 00:09:20.020
Because like you said, so many people are new to the community, which I think is awesome.

00:09:20.220 --> 00:09:22.800
I think that shows it's a vibrant, growing community.

00:09:23.580 --> 00:09:29.140
If you're in a community and you're wondering where the new next generation is gonna come from, there's a problem.

00:09:29.360 --> 00:09:30.920
And I don't think Python has that problem.

00:09:31.680 --> 00:09:34.380
Python has an incredible traction with new people.

00:09:34.959 --> 00:09:36.800
And I've always loved it because of the simplicity.

00:09:37.240 --> 00:09:40.460
I love it because the language is predictable in its patterns.

00:09:41.880 --> 00:09:48.400
It's not a cognitive overhead to remember all the various ways to call things in Python 'cause typically they're pretty consistent.

00:09:48.760 --> 00:09:48.860
- Yeah,

00:09:49.120 --> 00:09:50.660
but Python's slow, we can't use it for stuff.

00:09:51.399 --> 00:09:51.800
(laughing)

00:09:52.300 --> 00:09:54.020
I do not believe that for a second.

00:09:54.240 --> 00:09:54.460
- No.

00:09:54.960 --> 00:10:03.940
If you're doing maybe mathematical simulations or certain types of really, really intense low level things maybe, but as a general application framework, it applies, it's fine.

00:10:04.190 --> 00:10:04.300
Yeah.

00:10:04.620 --> 00:10:19.400
And that's the problem too is that if you go off right now and you ask your ChatGPT or your cloud about like, you know, maybe what are some disadvantages of Python, it's going to mention these kind of broad old opinions about it because it only knows the average of all the knowledge has ever been on the internet.

00:10:19.730 --> 00:10:20.860
And it's learned

00:10:20.860 --> 00:10:22.600
a bunch of like trash talk as well.

00:10:23.340 --> 00:10:25.140
and which is mostly inaccurate.

00:10:25.780 --> 00:10:27.560
But if you ask it to dig deeper, and

00:10:27.560 --> 00:10:28.440
someday

00:10:28.440 --> 00:10:31.740
we'll be able to ask it I think a little more critically, you'll probably dig in and get the truth.

00:10:31.940 --> 00:10:32.940
- Yeah, a bit of a side note.

00:10:32.970 --> 00:10:37.080
I recently, for a couple things I needed, got the Chat GPT Pro.

00:10:37.440 --> 00:10:39.680
Not the paid version, but the insane pro version.

00:10:39.840 --> 00:10:40.620
- Oh, the $200?

00:10:41.539 --> 00:10:43.340
- Yeah, $200 a month, and I laughed at myself.

00:10:43.460 --> 00:10:47.700
Like, this is the stupidest thing I've ever done, but I need it, so I'm gonna do it for a little few days, turn it off.

00:10:47.880 --> 00:10:49.100
It's incredible, I'm not turning it off.

00:10:49.380 --> 00:10:53.380
It's like my side buddy, I can ask anything.

00:10:53.760 --> 00:10:55.219
And it's so good.

00:10:56.420 --> 00:10:58.720
The future is here, it's just not evenly distributed.

00:10:59.500 --> 00:11:08.180
- It's not evenly distributed because it's hard for most folks to have the right mindset, I think, to approach to get that level of value out of it.

00:11:08.400 --> 00:11:10.640
I think you have to know how to talk to it.

00:11:10.860 --> 00:11:16.760
And I've said this before, it's the same problem with people who aren't good at using Google, just plain old search.

00:11:17.160 --> 00:11:24.200
Like, you know, the people who have to say, let me Google that for you, are the ones who understand how to like, use the search engine, you know, well.

00:11:24.820 --> 00:11:25.460
Some people-- - You know,

00:11:25.540 --> 00:11:27.700
that can be answered in an exact phrase if you

00:11:27.700 --> 00:11:29.980
just say the phrase, just say the

00:11:29.980 --> 00:11:31.040
phrase, you know what I mean, you know?

00:11:31.200 --> 00:11:32.780
And it's also a mindset, right?

00:11:32.840 --> 00:11:43.520
Like, I started thinking like, instead of this is a cost or something, like, this is like another employee that I can just give jobs and five minutes later, I'll come back and it's done pretty thorough research.

00:11:43.620 --> 00:11:44.200
You know, it's--

00:11:44.200 --> 00:11:47.900
- Yeah, especially with the new scheduling feature, where you can actually schedule tasks to happen.

00:11:48.160 --> 00:11:56.160
I'm getting kind of excited about, everyone's talking about agents, and I know this isn't the AI show we're here to talk about, but I think agents are interesting, but we're not there yet.

00:11:57.100 --> 00:12:01.340
They're about the level of maybe interns and what you would trust them to do for you.

00:12:01.640 --> 00:12:02.520
- Yeah, I totally agree.

00:12:02.640 --> 00:12:06.060
I'm a little worried about what all this stuff is gonna do to the industry

00:12:06.060 --> 00:12:06.460
in

00:12:06.460 --> 00:12:07.140
a broad sense.

00:12:07.360 --> 00:12:08.260
My main concern is

00:12:08.260 --> 00:12:08.640
I

00:12:08.640 --> 00:12:15.140
think it'll sort of carve out that gap between early dev and senior dev, and it's gonna be harder for folks to cross that.

00:12:15.640 --> 00:12:15.660
but

00:12:15.660 --> 00:12:19.820
it's also an incredible technology and I think it's also silly to pretend it doesn't exist.

00:12:20.040 --> 00:12:25.200
So anyway, you're right, it's not the AI show, but boy is it, is it top of mind for a lot of us, right?

00:12:25.620 --> 00:12:26.340
- Yeah, for sure.

00:12:26.600 --> 00:12:30.280
- Yeah, okay, so let's talk Python deployment.

00:12:30.760 --> 00:12:33.080
Talk some pitfalls, maybe a little bit of Docker.

00:12:33.660 --> 00:12:34.240
How's this?

00:12:34.560 --> 00:12:34.960
- It's a shame.

00:12:35.340 --> 00:12:37.200
- Why did you all attack this problem?

00:12:37.400 --> 00:12:41.580
And I guess setting the stages, where does this fit in your consulting story, right?

00:12:41.600 --> 00:12:51.160
You must need to deliver these applications often in a way that people can continue to let keep them going on their own without you constantly going back. Yeah, there's a there's some pip updates. So we'll take care of that for you.

00:12:51.470 --> 00:13:13.240
Well, and that definitely reaches into the longer tale of the whole story. I think if you go back to the beginning of the story of deployment, a lot of us started out or a lot of us older ones, more seasoned veteran developer folks in a world where if you wanted to deploy your web application, you threw some PHP into a web root. And as long as you had modphp installed, the stuff ran.

00:13:13.520 --> 00:13:17.620
Like you didn't have to think about configuring ingress and egress routes.

00:13:17.900 --> 00:13:21.380
And it was, you know, databases just ran on the same server you were on.

00:13:21.480 --> 00:13:22.720
So you just ran it on local host.

00:13:22.840 --> 00:13:26.100
Like it's the world has changed when it comes to the deployment story.

00:13:26.290 --> 00:13:30.760
But it's because things have gotten more complex and sophisticated because they had to.

00:13:31.000 --> 00:13:35.260
Like we had needs for more sophisticated authentication mechanism.

00:13:35.270 --> 00:13:37.680
We have needs for caching and delivery.

00:13:37.750 --> 00:13:39.840
We have needs for time series data.

00:13:39.960 --> 00:13:46.800
Like, because those opportunities opened up, more sophisticated software gets built, which means it's a little trickier to deploy.

00:13:47.080 --> 00:13:57.720
- Well, looking back, and with your perspective of all this experience as well, and it's something I've seen, every time the technology gets easier to work with, you know, like that used to be 100 lines of code, now it's three.

00:13:58.080 --> 00:14:03.240
You know, we're gonna be out of jobs soon, a lot of people would say, it's like, no, we're just gonna solve bigger, more ambitious problems.

00:14:04.140 --> 00:14:09.880
And that's been the case for so long, and it's not that, well, things got easier, so we're not gonna do it.

00:14:09.920 --> 00:14:16.980
No, every time it got easier, we were able to just think of bigger, more, instead of, we don't need a team, one person can solve this amazing problem.

00:14:17.280 --> 00:14:22.200
But that means, underneath that, there's this mountain, this iceberg of stuff going on, right?

00:14:22.600 --> 00:14:34.040
- Well, and that's where deployment has gotten, I think, hard in a lot of people's minds, is because there is a mountain of knowledge, like there's a giant shoulders that you're standing on that makes that happen.

00:14:35.499 --> 00:14:42.360
And my VP of engineering was complaining to me yesterday, Like, why can't we just, how can we not easily put websites on the internet anymore?

00:14:42.820 --> 00:14:45.300
And it's not that we can't put websites on the internet anymore.

00:14:45.300 --> 00:14:46.860
They just do so much for us.

00:14:47.000 --> 00:14:52.340
Like the complexity and the sophistication and the covers is what's causing a lot of this issue.

00:14:52.420 --> 00:15:01.620
And the person who wrote software is not always the person who deploys software because I think they've just got kind of different mindsets or different ways of thinking about the problems.

00:15:01.820 --> 00:15:09.400
And it's rare you find people who are truly a full stack and do front end to the back into the database, the network, all the layers that are in between.

00:15:09.600 --> 00:15:15.840
And it's nice that services like, you know, the cloud have come about where it greatly simplifies that deployment.

00:15:16.020 --> 00:15:18.420
And that was part of our journey into containers.

00:15:18.960 --> 00:15:30.100
I was resistant to containers probably until 2020 when we did, in 2020 there was a change, obviously, some things happened in the world, but we also

00:15:30.100 --> 00:15:30.340
built...

00:15:30.340 --> 00:15:31.920
- You had more time to be at home and figure out stuff.

00:15:32.020 --> 00:15:32.400
- Right.

00:15:33.280 --> 00:15:40.740
But we also had time to build some software to help us in our little conference we were doing. We put on the Python web conference during the pandemic.

00:15:40.750 --> 00:16:31.700
We actually started the pre-pandemic, but during the pandemic, we took time to write some software to deploy a virtual event platform. And I think containers, at that point in time, I adopted containers and container orchestration because it allowed the developers to think more about developing and less about the deploying part of a sophisticated application like streaming web video, audio mixing, switching, live chats and web sockets. I mean, there's a whole lot of moving parts in something when you're delivering a live video conference experience. And the containers were a nice, like, equalizing layer to allow us to say, I don't care where it goes to, whether it's in Docker Compose or Kubernetes or Docker Swarm, or in our case, we used Amazon's Fargate, because I just didn't want to deal with infrastructure. I just told Fargate, I got some tasks here, some containers, make

00:16:31.700 --> 00:16:33.900
them live, like turn them on.

00:16:34.210 --> 00:16:34.320
Yeah.

00:16:34.630 --> 00:16:36.940
And it sounds like that's for devs as well.

00:16:37.220 --> 00:16:37.420
Yeah.

00:16:37.570 --> 00:16:44.280
And we do-- Not just the infrastructure you're pointing to, but this is, it sounds like you're smoothing the path for the whole team, right?

00:16:44.460 --> 00:16:44.720
Correct.

00:16:44.920 --> 00:16:48.260
That's an opinion I hold that containers are for development as well.

00:16:48.540 --> 00:17:12.939
Like that developer experience, some organizations I've seen, they may be deploying on the Kubernetes because there were operational opinions about deploying into containers, but the developers themselves haven't adopted that fully on their local workstation because it may feel hard until you've got that muscle built up for doing that level of development. That's originally, that's why Scaf came about, to make that development experience just a breeze.

00:17:14.300 --> 00:17:54.260
We focused on how quickly can a developer be productive locally using containers and still have all your tools. It shouldn't feel different than if you were developing with your local Django files on your local file system and you were just running a Postgres instance, you know, out of homebrew, except it's better because now the versions will match what's running in production and you can have five different projects running with five different versions of things because you want to make sure they match your expectations when they go to launch and not be surprised when, you know, the version of Redis doesn't support some new operator because you were one minor version off in your local machine compared to the sandbox and production machines.

00:17:54.380 --> 00:17:54.540
>>

00:17:54.540 --> 00:17:54.700
Yeah.

00:17:54.780 --> 00:18:00.060
I was not against containers, but I was resistant to use them myself because I felt

00:18:00.060 --> 00:18:09.080
like, well, here's another thing to understand, another thing that's a layer between me and my code, and it could go wrong and I don't need it.

00:18:09.420 --> 00:18:11.260
You know what? I'm a believer.

00:18:11.460 --> 00:18:15.380
It is so nice to be able to just say, here's three commands you can run.

00:18:15.550 --> 00:18:16.000
>> Exactly.

00:18:16.000 --> 00:18:17.220
>> Always going to be exactly.

00:18:17.940 --> 00:18:23.880
Another thing that I've done is on my new Macs and stuff, my dev machines, I don't put databases on there.

00:18:24.140 --> 00:18:24.520
Nope.

00:18:24.800 --> 00:18:24.940
Caching.

00:18:25.240 --> 00:18:32.060
I don't even necessarily install Python directly on, you know, as in go to python.org or homebrew or something like that.

00:18:32.260 --> 00:18:39.140
It's, if I want a tool and you know, instead of installing say MongoDB, I can just have a Docker command that runs MongoDB.

00:18:39.380 --> 00:18:40.400
That listens on the same port.

00:18:40.440 --> 00:18:40.540
Yep.

00:18:40.860 --> 00:18:42.260
And it's, it's always up to date.

00:18:42.300 --> 00:18:43.520
And if I don't like it, I get rid of it.

00:18:43.600 --> 00:18:47.340
If I want to change the version of it, I just change the flag somewhere in a file.

00:18:47.420 --> 00:18:49.020
And it's, it's incredible.

00:18:49.340 --> 00:18:49.900
That and uv.

00:18:50.180 --> 00:18:50.360
Yeah.

00:18:50.380 --> 00:18:52.020
Think back to the old, old days.

00:18:52.040 --> 00:19:00.900
and the old days for us, but probably the current state for a lot of people in certain organizations, is you had a large getting started document that you would have to follow top to bottom.

00:19:01.290 --> 00:19:12.700
You know, make sure you get this version of that, make sure you get that version of this, make sure you put these files there, make sure your database is running with these couple extra options because we've enabled some, and maybe we've enabled GIS or some extension to the database.

00:19:13.220 --> 00:19:21.240
If you didn't get all those magic incantations just right and follow the document to the letter, you were having, you know, a long time to get started.

00:19:21.480 --> 00:19:22.440
like it was a struggle.

00:19:22.780 --> 00:19:34.940
Whereas you just tell someone Git pull and then we'll tilt up, in our case for Scaf, we've adopted the tilt management tool, they're running and they can start making, contributing code within an hour.

00:19:35.440 --> 00:19:35.860
That's my goal.

00:19:35.920 --> 00:19:41.600
My goal has always been fresh laptop out of the box, on my desk and be able to contribute like a pull request in an hour.

00:19:43.140 --> 00:19:45.900
- This portion of Talk Python To Me is brought to you by the folks at Posit.

00:19:46.400 --> 00:19:49.240
Posit has made a huge investment in the Python community lately.

00:19:49.860 --> 00:19:55.080
Known originally for RStudio, they've been building out a suite of tools and services for Team Python.

00:19:55.540 --> 00:20:03.960
Over the past few years, we've all learned some pretty scary terms, hyper-squatting, supply chain attack, obfuscated code, and more.

00:20:04.580 --> 00:20:14.920
These all orbit around the idea that when you install Python packages, you're effectively running arbitrary code off the internet on your dev machine, and usually even on your servers.

00:20:15.460 --> 00:20:21.020
The thought alone makes me shudder, and this doesn't even touch the reproducibility issues surrounding external packages.

00:20:21.800 --> 00:20:23.080
But there are tools to help.

00:20:23.580 --> 00:20:26.480
Posit Package Manager can solve both problems for you.

00:20:27.320 --> 00:20:30.580
Think of Posit Package Manager as your personal package concierge.

00:20:30.900 --> 00:20:35.400
Use it to build your own package repositories within your firewall that keep your project safe.

00:20:35.480 --> 00:20:40.500
You can upload your own internal packages to share or import packages directly from PyPI.

00:20:40.900 --> 00:20:46.640
Your team members can install from these repos in normal ways using tools like pip, poetry, and ub.

00:20:47.240 --> 00:20:53.660
Posit Package Manager can help you manage updates ensuring you're using the latest, most secure versions of your packages.

00:20:54.240 --> 00:21:01.400
But it also takes point-in-time snapshots of your repos, which you can use to rerun your code reproducibly in the future.

00:21:01.960 --> 00:21:08.060
Posit Package Manager reports on packages with known CVEs and other vulnerabilities so you can keep ahead of threats.

00:21:08.500 --> 00:21:14.000
And if you need the highest level of security, you can even run Posit Package Manager in air-gapped environments.

00:21:14.620 --> 00:21:20.540
If you work on our data science team where security matters, you owe it to you and your to check out Posit Package Manager.

00:21:21.140 --> 00:21:26.980
Visit talkpython.fm/ppm today and get a three month free trial to see if it's a good fit.

00:21:27.140 --> 00:21:29.460
That's talkpython.fm/ppm.

00:21:29.920 --> 00:21:31.740
The link is in your podcast player show notes.

00:21:32.180 --> 00:21:33.700
Thank you to Posit for supporting the show.

00:21:34.640 --> 00:21:35.120
Do

00:21:35.120 --> 00:21:42.420
you, when you guys are doing development, do you actually do development in containers or do you just use them to support all of your stuff?

00:21:42.700 --> 00:21:43.600
- No, everything's in containers.

00:21:44.500 --> 00:21:48.900
That was, Scaf primarily, And some people will see Scaf as a deployment tool.

00:21:49.000 --> 00:21:52.260
I see Scaf as a developer experience tool and a deployment tool.

00:21:52.430 --> 00:21:58.640
I covered both ends of that spectrum because everything starts obviously with the developer and an idea and some building some software.

00:21:59.060 --> 00:22:06.020
Well, if they can't build the software easily or they can't collaborate with another contributor on that software, it slows things down.

00:22:06.320 --> 00:22:13.540
So part of what we, you know, that Scaf tool is, it's gonna be able to give you the scaffolding to build out of an initial project.

00:22:13.700 --> 00:22:22.340
Like starting from scratch, you have nothing on the file system, Scaf will build out those initial tools, but then Scaf is a set of opinions, more importantly, because lots of scaffolding tools exist out there.

00:22:22.340 --> 00:22:31.380
I mean, current Scaf is built on Cookie Cutter, but we can move that, we can move those opinions as we change our opinions about the development world.

00:22:31.660 --> 00:22:39.080
So as we build a new project and let that get started, we now can develop locally on containers.

00:22:39.240 --> 00:22:42.900
Like we use Kind for our Kubernetes cluster locally, which is nice.

00:22:44.140 --> 00:22:48.600
and you'd think running Kubernetes might be overkill for a local development environment.

00:22:48.850 --> 00:22:54.240
But the nice part about that is, is like now the Kubernetes manifests, you know, layer nicely.

00:22:54.420 --> 00:23:07.060
You've got a local base layer, a local instance, you've got a sandbox instance or a development instance you may launch into the cloud someplace, or you've got your production layers all right in there using customized, for example.

00:23:07.660 --> 00:23:07.880
- Nice.

00:23:07.960 --> 00:23:18.260
- Yeah, nice part about that is, if my machine doesn't have enough horsepower or memory or disk space to run a specific project that where I need to jump in and help, I can just run that in the cloud.

00:23:18.400 --> 00:23:22.120
I don't, there's nothing saying I have to be running that locally on my own machine.

00:23:22.440 --> 00:23:28.260
All the tooling, all the file synchronization will work just as well if it's running in a sidecar.

00:23:28.560 --> 00:23:39.500
Like if I had a big white box, Intel machine or machine sitting in my, under my desk, I can run that or I can just launch it into a digital ocean or an AWS cloud, doesn't matter.

00:23:39.780 --> 00:23:40.580
- Yeah, absolutely.

00:23:40.840 --> 00:23:43.460
So let's dive in, let's dive into Scaf.

00:23:43.680 --> 00:23:50.000
But before we do, have you seen, I think it was in the last episode, this new AI computer thing that NVIDIA announced?

00:23:50.020 --> 00:23:51.360
- I'm pretty excited about that actually.

00:23:51.440 --> 00:23:52.380
- I'm super excited.

00:23:52.700 --> 00:23:55.860
NVIDIA unveils a $3,000 desktop AI computer.

00:23:56.180 --> 00:23:59.840
And I think it's just, you kind of remote in and run containers on it as well, I'm pretty sure.

00:24:00.160 --> 00:24:06.620
- Yeah, I was excited 'cause I felt like CES, this is obviously launched at CES by NVIDIA on stage.

00:24:06.720 --> 00:24:10.980
And I was excited to see CES have something It was interesting for developers again.

00:24:11.200 --> 00:24:15.120
I feel like CES had kind of gotten boring maybe over the last decade.

00:24:15.380 --> 00:24:16.380
And this was exciting.

00:24:17.140 --> 00:24:17.440
I think

00:24:17.440 --> 00:24:17.880
that...

00:24:17.880 --> 00:24:19.100
It's got to be all doorbells and TVs.

00:24:19.360 --> 00:24:19.460
Yeah,

00:24:19.700 --> 00:24:20.160
right.

00:24:20.600 --> 00:24:20.900
Exactly.

00:24:21.100 --> 00:24:23.280
I love home automation.

00:24:23.320 --> 00:24:23.980
Don't get me wrong.

00:24:24.300 --> 00:24:26.960
But there's only so much of that junk I could possibly be interested in.

00:24:27.180 --> 00:24:28.640
This is something I'm very interested in.

00:24:28.940 --> 00:24:29.180
Exactly.

00:24:29.540 --> 00:24:33.600
Well, Jamie out in the audience says, "Totally all in on developing with Guinness.

00:24:33.700 --> 00:24:36.900
Very few tools installed on my Mac, but we're here with you."

00:24:36.940 --> 00:24:37.160
Awesome.

00:24:37.220 --> 00:24:38.140
Yeah, the important tools.

00:24:38.140 --> 00:24:43.660
Like you've got your IDE, your VS Code, you've got your, you know, you've got your favorite Git visualization tool.

00:24:43.850 --> 00:24:47.820
Like, I mean, those, those are critical to your, your tool chain, your workflow and they should work everywhere.

00:24:48.030 --> 00:24:50.660
They should work just as work alike on every project you're on.

00:24:50.980 --> 00:24:52.000
Yeah, I agree.

00:24:52.180 --> 00:25:02.040
I don't develop containers, but I work with local virtual environments and then like basically try to replicate exactly the same, but all the surrounding stuff, all the daemons and the servers and all that.

00:25:02.200 --> 00:25:07.860
It's all like, so we're at a slightly different stage of our container journey, I believe, We're both far down the path, I think.

00:25:07.970 --> 00:25:08.080
>>

00:25:08.080 --> 00:25:09.140
Much further than we used to be.

00:25:09.440 --> 00:25:10.160
>> Certainly.

00:25:11.090 --> 00:25:11.200
[LAUGHTER]

00:25:12.560 --> 00:25:12.920
>>

00:25:12.920 --> 00:25:13.020
All

00:25:13.020 --> 00:25:15.400
right. Here we are, six feet up slash Scaf on GitHub.

00:25:15.710 --> 00:25:15.900
>> Yep.

00:25:16.010 --> 00:25:22.280
>> Scaf provides developers and DevOps engineers with a complete blueprint for a new project using Kubernetes.

00:25:22.390 --> 00:25:26.600
We talked a lot about the motivation and so on, but let's start with the beginning.

00:25:26.640 --> 00:25:29.580
You said I have an idea for a project that wasn't well-structured.

00:25:29.940 --> 00:25:36.500
This is a little cookie cutter-ish in a sense, but what it makes is more than just a Python project, right?

00:25:36.780 --> 00:25:37.520
Tell us what we got here.

00:25:38.240 --> 00:25:48.080
- So this started out, if you've ever followed the Cookie Cutter project, there was a Cookie Cutter Django template out there made by Pi Danning.

00:25:48.500 --> 00:25:49.940
It kind of kicked that off and started it.

00:25:50.100 --> 00:25:55.360
I liked a lot of his opinions, but I wanted more to it, or I wanted to change some of them.

00:25:55.620 --> 00:25:58.660
So that was the original, like, kind of kernel of where this started.

00:25:59.100 --> 00:26:06.460
And then we grew a lot more around the deployment story and some of the developer tools so that we could be on Kubernetes.

00:26:06.530 --> 00:26:17.280
We could standardize on Kubernetes as a container platform, so we could launch into any cloud, whether it's a managed Kubernetes or whether you're bare metal and are running like VMs and EC2, or it doesn't matter.

00:26:17.900 --> 00:26:24.260
Because the nice part about Kubernetes is it gives you that agnostic interface to launch new containers.

00:26:25.020 --> 00:26:31.360
I think a lot of people see Kubernetes as complex and used for like container orchestration and scaling.

00:26:31.580 --> 00:26:37.860
But I see Kubernetes as a way, it's an interface, it's an API to allow us to deploy easily.

00:26:38.180 --> 00:26:41.780
So we wanted to focus on things like CI/CD, and could you make that simple?

00:26:41.940 --> 00:26:45.820
So SCAF includes opinions around Argo CD, for example.

00:26:46.060 --> 00:26:53.080
So when you deploy into Sandbox, it deploys the Argo CD operator, and then it sits and watches your repository for changes.

00:26:53.280 --> 00:26:59.500
So anytime you merge to Dev branch, for example, it will release to Sandbox, and then the QA team can go test.

00:26:59.860 --> 00:27:00.680
You don't have to think about it.

00:27:00.760 --> 00:27:05.260
Like you just make a PR, if it gets reviewed and accepted and merged, the release happens.

00:27:05.400 --> 00:27:06.720
Like no one forgets to do the release.

00:27:07.080 --> 00:27:08.760
No one has to do manual steps to do the release.

00:27:09.320 --> 00:27:20.000
Long gone are the days of shelling into a box and doing a Git pull or SPN up in a directory and forgetting to restart some service to pick up those changes.

00:27:20.800 --> 00:27:22.160
Because humans, we're humans.

00:27:22.380 --> 00:27:28.300
We're terrible about repeatability and maintaining and being able to do maintenance type tasks like that.

00:27:28.560 --> 00:27:29.400
We're just not built for it.

00:27:29.520 --> 00:27:30.920
We're built for creative type thinking.

00:27:31.200 --> 00:27:37.460
We should let the computers do the bits are good at, which I feel like that's what some of these opinions are based around is can we automate those pieces away?

00:27:37.760 --> 00:27:37.880
Right.

00:27:37.980 --> 00:27:39.520
It's like a deployment checkbox.

00:27:39.820 --> 00:27:40.100
Oh yeah.

00:27:40.220 --> 00:27:40.440
Checklist

00:27:40.440 --> 00:27:41.480
and like tech, tech, tech.

00:27:41.540 --> 00:27:42.200
Have we installed this?

00:27:42.200 --> 00:27:43.700
Do you set this version exactly?

00:27:43.940 --> 00:27:44.220
Yeah.

00:27:44.540 --> 00:27:44.700
Yeah.

00:27:45.040 --> 00:27:45.200
Yeah.

00:27:45.520 --> 00:27:47.100
And some, some humans are good at checklists.

00:27:47.200 --> 00:27:49.100
Like there's people who are, that is their thing.

00:27:49.260 --> 00:27:50.680
Like, you know, doctors and surgery.

00:27:50.680 --> 00:27:51.680
Don't take their checks from them.

00:27:51.700 --> 00:27:51.860
Right.

00:27:52.020 --> 00:27:54.580
Like they love their checklists and glad they've got them.

00:27:55.200 --> 00:28:02.780
I feel like people who have gravitated towards software development are craftsmen, kind of artisans around a craft.

00:28:02.920 --> 00:28:08.860
And it's not so much about checking check boxes as it is how do they creatively solve a problem because a lot of the problems they're solving haven't existed.

00:28:09.060 --> 00:28:11.020
If they existed already, they would be solved.

00:28:11.120 --> 00:28:12.880
And what would be the point of us writing any software?

00:28:13.300 --> 00:28:13.360
Yeah.

00:28:13.500 --> 00:28:14.400
And that's why we have that.

00:28:14.400 --> 00:28:15.240
It works on my machine.

00:28:15.260 --> 00:28:15.800
Yeah, totally.

00:28:16.060 --> 00:28:16.880
Program because

00:28:16.880 --> 00:28:18.780
we

00:28:18.780 --> 00:28:24.160
don't check the boxes and we're not amazing at making everything work the same, but yeah.

00:28:24.200 --> 00:28:24.880
And

00:28:24.880 --> 00:28:29.680
this is my goal is the getting rid of the works on my machine.

00:28:29.840 --> 00:28:31.680
Like it should work everywhere the same, exactly the same.

00:28:32.000 --> 00:28:34.440
And you should be able to use your own machine for development.

00:28:34.740 --> 00:28:44.240
Like a lot of I've seen a lot of teams where they have this big central server that's called dev and that's where they all shell into and work simultaneously on a single spot.

00:28:44.480 --> 00:28:49.460
And that just feels fraught with errors and terror to me.

00:28:49.640 --> 00:28:49.760
Yeah.

00:28:50.040 --> 00:28:53.780
You know what it feels like it screams to me is you might end up It doesn't work on my machine.

00:28:53.810 --> 00:28:55.120
It only works on that machine.

00:28:55.510 --> 00:28:55.620
Exactly.

00:28:56.200 --> 00:28:56.660
Even worse.

00:28:56.670 --> 00:28:57.140
It only works.

00:28:57.300 --> 00:29:09.340
I once worked on a research project with a pretty big funding organization and there was a bunch of different contractors, one of them out of Seattle, and we all had to build some pretty complex software team.

00:29:09.380 --> 00:29:12.300
I was on, we built something that kind of coordinated all of them and it was fine.

00:29:12.880 --> 00:29:13.380
Worked great.

00:29:13.520 --> 00:29:13.980
We were all happy.

00:29:14.030 --> 00:29:22.580
The other people will deliver, but there was this one team that had built something on a big, big Linux server and big fat desktop thing.

00:29:22.800 --> 00:29:23.880
Why do I know the size of it?

00:29:24.220 --> 00:29:32.460
Because they had worked on it for nine months and then they tried to get it to run on another, they literally could not get it to run on any other computer.

00:29:32.820 --> 00:29:45.200
And so they put it into the most fragile, or most careful shipping container they could and they drove it from Seattle to San Diego and they set it up in the corner 'cause they literally couldn't get the software they wrote to run on any other system.

00:29:45.500 --> 00:29:46.140
Could you imagine?

00:29:46.400 --> 00:29:48.280
Like, what are you going to do in the next time around?

00:29:48.440 --> 00:29:49.140
What if it breaks?

00:29:49.640 --> 00:29:49.960
- Right.

00:29:50.280 --> 00:29:52.680
- Yeah, that, that, I'm working on a big central server.

00:29:52.760 --> 00:30:01.380
Maybe there's a way to like restore it and stuff, but you could, you could craft your software into a corner on that big server where it's like, well, we're going to move to the cloud.

00:30:01.440 --> 00:30:04.500
Like, no, we're going to keep it on that thing and it better just be enough, you know?

00:30:04.720 --> 00:30:04.900
- Right.

00:30:05.140 --> 00:30:07.340
And how do you onboard someone new to help you?

00:30:07.640 --> 00:30:09.460
Like, you gotta be like, well, be very, very careful.

00:30:09.640 --> 00:30:11.560
There's this one, only one server where it only runs.

00:30:11.640 --> 00:30:12.280
- Oh my goodness.

00:30:12.620 --> 00:30:13.820
Could you, could you not?

00:30:13.860 --> 00:30:15.080
- Onboarding is such a challenge there.

00:30:15.400 --> 00:30:15.540
- Yeah.

00:30:16.160 --> 00:30:29.620
You want to be able to onboard developers like with confidence and they can have the confidence to know that they can make mistakes and they can burn things to the ground and they can try stuff knowing that it's not going to affect like the production machine or even the sandbox machine.

00:30:29.650 --> 00:30:34.420
Like they can experiment with a little bit of reckless abandon because that's how you learn.

00:30:34.620 --> 00:30:35.520
Like you break things.

00:30:35.740 --> 00:30:37.240
In my mind, you break things to learn.

00:30:37.380 --> 00:30:39.560
There's a lot of learning that happens when you get to break things.

00:30:39.610 --> 00:30:46.140
And if you can break things confidently knowing that no big deal, I can just get full or put a branch and delete that branch and start over.

00:30:46.440 --> 00:30:51.540
>> 100 percent. And there's different, there's different layers at which people should embrace that to the maximum.

00:30:51.940 --> 00:30:55.740
They should embrace that in refactoring, reorganizing, right?

00:30:55.880 --> 00:31:00.460
So if I have, if I have Git and I have frequent check-ins, I should be able to go crazy.

00:31:00.480 --> 00:31:07.100
You shouldn't be like, "Oh, don't mess with that." You should be able to go crazy on your code and go, "Oh my gosh, it's better." Or, "That was a horrible idea." Revert.

00:31:08.080 --> 00:31:09.120
>> Get rid of that.

00:31:10.160 --> 00:31:10.280
>>

00:31:10.280 --> 00:31:12.260
And it should not, it should not be terror.

00:31:12.340 --> 00:31:14.060
It should be like, "Oh, let's give that a try.

00:31:14.120 --> 00:31:14.980
I bet that would be awesome.

00:31:15.100 --> 00:31:16.360
And if it's not, we're going to get out.

00:31:16.800 --> 00:31:21.560
Also though, on the containers give you that for your infrastructure locally and in the cloud.

00:31:21.870 --> 00:31:24.360
What if we ran on the newest version of Postgres?

00:31:24.610 --> 00:31:24.740
Yep.

00:31:24.980 --> 00:31:25.320
Let's try it.

00:31:25.320 --> 00:31:25.420
Is that

00:31:25.420 --> 00:31:26.740
amazing or is it a horrible idea?

00:31:26.860 --> 00:31:29.520
Like, you've got the one server that everyone's using.

00:31:29.820 --> 00:31:31.500
You're definitely, or even the QA server.

00:31:31.600 --> 00:31:39.980
You're like, we're not going to break everyone because there's 10 people who are going to lose their productivity if we screw this up, but I can change a number in a Docker file and try it.

00:31:40.150 --> 00:31:53.600
And I've seen this in action, again, in production, in action, in we have with our own customer stuff where a junior, you know, admin, sysadmin was doing some standard maintenance activity, you know, maybe they accidentally dropped the database.

00:31:53.960 --> 00:32:00.080
But if you have all the things lined up and all the infrastructure, you know, set up in this kind of optimal way, no big deal.

00:32:00.460 --> 00:32:01.580
It's like, no problem.

00:32:01.800 --> 00:32:04.680
Like you go push, you go run the command that like restores the DB.

00:32:04.990 --> 00:32:07.860
Like for example, one of our opinions in here is a cloud native PG.

00:32:08.300 --> 00:32:08.840
So you have options.

00:32:08.920 --> 00:32:15.580
Like we can use cloud native PG in the cluster and that does things like point time restore, recovery, you can be using RDS.

00:32:16.399 --> 00:32:28.480
Those opinions can happen afterwards, but given that the whole thing can be blown away and redeployed in a moment, in literally a moment's notice, gives you a lot of confidence in being able to bring something back from a destructive action.

00:32:28.760 --> 00:32:28.920
- Yeah,

00:32:29.120 --> 00:32:29.400
absolutely.

00:32:29.860 --> 00:32:29.920
I

00:32:29.920 --> 00:32:30.060
think

00:32:30.060 --> 00:32:32.720
we're both so excited about this, we keep getting on tangents.

00:32:33.100 --> 00:32:35.680
I originally would have asked you kind of, how do I get started with this?

00:32:35.740 --> 00:32:36.700
Like, talk us through.

00:32:36.920 --> 00:32:37.420
(laughing)

00:32:37.420 --> 00:32:37.980
Talk us through,

00:32:38.140 --> 00:32:40.560
like I'm a-- - Oh, you'd like to try it?

00:32:40.680 --> 00:32:41.360
(laughing)

00:32:41.780 --> 00:32:46.420
They give people a sense of like, if they, if they don't, obviously most people don't have this already.

00:32:46.520 --> 00:32:48.220
Like what are they, they want a new project.

00:32:48.580 --> 00:32:51.060
They want it to have this more forward looking.

00:32:51.440 --> 00:32:51.520
Yep.

00:32:51.800 --> 00:32:53.960
So on that structure, yeah.

00:32:54.140 --> 00:32:58.180
On that GitHub page, there's a one-liner you can just copy paste into your terminal.

00:32:58.600 --> 00:33:00.080
I think it's toward the, yeah, it is right there.

00:33:00.360 --> 00:33:00.440
Yeah.

00:33:00.540 --> 00:33:01.060
There's a little, I

00:33:01.060 --> 00:33:03.420
applaud you for not having the dollar at the beginning.

00:33:03.540 --> 00:33:03.880
Thank you.

00:33:05.440 --> 00:33:05.740
I'm

00:33:05.740 --> 00:33:06.880
dollar fan, not a fan.

00:33:06.960 --> 00:33:07.500
I'm pragmatic about this.

00:33:07.600 --> 00:33:07.680
Yeah.

00:33:07.940 --> 00:33:08.220
Yeah.

00:33:08.820 --> 00:33:12.040
And that one liner will install a lot of the opinions.

00:33:12.400 --> 00:33:27.820
I've mentioned this before to some people that Scaf gives you all of those kind of cool opinions, cool tools, like neat techniques that as a developer, like it takes like decades to refine and hone and kind of gain into your toolbox.

00:33:28.200 --> 00:33:30.200
Scaf tries to give those to you like right away.

00:33:30.460 --> 00:34:10.600
Like, so it's, for example, it's going to install kubectl and kind and tilt and a couple of other tools if they're not found on your system and it'll use, if homebrew installed, it'll just use homebrew out of the box to do that and it puts it into your home directory. It doesn't, it shouldn't require, you know, one of my goals is not to require sudo anywhere in this process, you know, there's no sudo needed here for that curl command to run. And so it should be less impactful on your system than a lot of other tools, but it gives you a lot of power for what you are installing. So you run that one liner, it will now give you in like your dot local bin directory, a scaf CLI command that you'll be able to run.

00:34:10.820 --> 00:34:13.740
And you can just run scaf and then the name of the project you want to build.

00:34:14.060 --> 00:34:15.040
And it'll ask you some questions.

00:34:15.159 --> 00:34:22.159
So this is the kind of cookie cutter part at that point, is that it's going to ask you, "Hey, do you want to build a Django app with Next.js running?

00:34:22.720 --> 00:34:26.580
And do you want to use Sentry? Do you want to have Celery?" Just some standard questions.

00:34:26.760 --> 00:34:28.379
What mail provider are you going to use?

00:34:28.679 --> 00:34:33.260
So it gives you then on your file system a new, in this case, a Django project.

00:34:33.480 --> 00:34:37.620
I'll talk about some of the future vision pieces of that, but that's what it gives you today.

00:34:37.780 --> 00:34:50.320
It also gives you, in addition to a standard Django project, because you can get a Django project just by running the Django start project, a Django admin start project command, it would blow out a very simple version of a Django project.

00:34:50.360 --> 00:34:51.379
This has more to it.

00:34:51.520 --> 00:34:55.080
There's some opinions about users and sites and some other things.

00:34:55.360 --> 00:34:58.580
But not only that, there's going to be all the Kubernetes manifests for running locally.

00:34:58.820 --> 00:35:03.600
There's going to be Terraform in there for deploying into a sandbox cloud, like on Amazon, for example.

00:35:03.870 --> 00:35:10.540
So if you chose Amazon as your target cloud, There's going to be all these kind of other opinions in here.

00:35:10.800 --> 00:35:16.920
What database we're using, what if we're using Celery, we're going to use Redis, actually we should change that.

00:35:16.980 --> 00:35:21.540
We're changing from Redis over to Valkey at the moment as well.

00:35:21.750 --> 00:35:23.320
>> Valkey, what is this?

00:35:23.810 --> 00:35:26.480
>> So Valkey, V-A-L-K-E-Y.

00:35:26.710 --> 00:35:27.080
>> Close.

00:35:27.380 --> 00:35:29.340
>> Valkey, which is the Redis.

00:35:29.720 --> 00:35:30.040
>> Valkey,

00:35:30.280 --> 00:35:30.560
okay.

00:35:31.240 --> 00:35:32.220
>> The Redis for Blake's Code.

00:35:32.710 --> 00:35:33.160
>> Yeah.

00:35:33.510 --> 00:35:34.900
>> Okay. Why this?

00:35:35.140 --> 00:35:37.860
- Just because of licensing changes on the Reddit side of things.

00:35:38.760 --> 00:35:44.480
I think that's another whole, we could do a whole other podcast on just open source licensing and interesting history.

00:35:44.710 --> 00:35:46.840
You know, the Elastic folks did this with ElasticCache.

00:35:47.180 --> 00:35:51.060
I think the Reddit folks kind of were following suit, but then you now-- - I think Mongo did

00:35:51.060 --> 00:35:52.600
maybe a little bit as well.

00:35:52.940 --> 00:35:53.020
- Well,

00:35:53.120 --> 00:35:58.800
now you've seen the Elastic folks kind of go back on that, heading back toward the more open open source licensing.

00:35:59.300 --> 00:35:59.580
We'll see.

00:35:59.760 --> 00:36:10.660
- I'm sympathetic to, at least some of these, because they built these businesses and the cloud folks are just like, "Awesome, we'll host that for you, thanks." You're like, "Wait a minute, we were hoping to kind of "have some kind of deal." - Yeah, be that.

00:36:11.260 --> 00:36:12.400
- Yeah, yeah, yeah. - That'd be great for you.

00:36:12.700 --> 00:36:22.800
- I can also totally understand, "No, we just want this stuff unencumbered." - Yeah. - It's not that complicated, probably we could probably make this work, and we got together and teamed up, and okay, this is news to me, this is awesome.

00:36:23.080 --> 00:36:28.340
- Yeah, no, it's, again, it's drop-in replacement for the most current version of Redis.

00:36:28.860 --> 00:36:29.320
- I was actually

00:36:29.320 --> 00:36:34.520
just thinking about doing something with Redis, but I think I might just do a little Norse legend type of stuff.

00:36:35.680 --> 00:36:36.260
Try that out.

00:36:38.200 --> 00:36:47.020
This portion of the talk Python to me is brought to you by a very special project that I've been working hard on for some time, a new book, the talk Python in production book.

00:36:47.760 --> 00:36:54.440
I've long felt that most guidance and marketing about how we need to run Python apps in production has been overly complex and expensive.

00:36:55.100 --> 00:37:16.620
I'm sure you've heard me espouse the ideas that you're not Google, you're not and you're not Netflix to emphasize that the legitimately incredible technology powering these companies can be admired but mostly shouldn't be used as a guide for your own applications and APIs. This book, "Talk Python in Production" is me pulling back the curtain and showing the world how this can be easily done.

00:37:17.160 --> 00:37:27.800
You'll see how and why various technology choices have led us to truly maintainable web apps that can be managed by a single developer, cost a tiny fraction of most cloud-based solutions

00:37:27.800 --> 00:37:28.680
and

00:37:28.680 --> 00:38:21.140
result in a blazing fast web app built on modern Python. You might be wondering if you need to be an expert in Docker or Linux to benefit from this book. You don't. While having some exposure to Docker or Linux servers helps, the book walks through setting up and managing a modern Docker-based deployment from scratch. Think of it as a guided tour of these technologies with best practices and pitfalls explained along the way. When deploying to the cloud, you often hear that you should just use serverless or other no-touch services. While they can work well, they often suffer from cold start slowness and more importantly, unpredictable bursts of costs if your app becomes popular. In Python in production, we keep these costs low and nearly flat by avoiding dozens of microservices and serverless functions. You won't be blindsided by unpredictable bills if you adopt this methodology.

00:38:21.640 --> 00:38:26.780
Some of the more notable chapters include chapter 4, one big server rather than many small ones.

00:38:27.420 --> 00:38:30.420
Chapter 6, running on Rust Python application servers.

00:38:31.100 --> 00:38:33.660
Chapter 8, visualizing servers and other tools.

00:38:34.260 --> 00:38:36.700
Chapter 14, picking a Python web framework.

00:38:37.220 --> 00:38:43.840
Talk Python in production is available to read online or you can buy the full book at talkpython.fm/devopsbook.

00:38:44.460 --> 00:38:55.720
If you're interested in running professional web applications and APIs in production with high availability and yet keeping things simple and manageable, then please consider the Talk Python in production book from yours truly.

00:38:56.240 --> 00:38:59.920
Read it online or get the full book at talkpython.fm/devopsbook.

00:39:00.780 --> 00:39:04.720
Getting the book is a great way to support Talk Python and keep the show going strong.

00:39:04.920 --> 00:39:07.480
The link to the book is in your podcast player show notes.

00:39:08.780 --> 00:39:10.100
Russ out there asks,

00:39:10.320 --> 00:39:18.300
"Wagtail?" Not yet. I don't believe we have a Wagtail template, but I'll talk about that in the roadmap. That's coming.

00:39:19.780 --> 00:39:25.260
I guess it's worth pointing out to people that this is sort of at its core Django philosophy, right?

00:39:25.720 --> 00:39:29.020
Currently. We have some other

00:39:29.020 --> 00:39:32.420
use cases that we want to be able to satisfy with Scaf as well.

00:39:32.920 --> 00:39:42.140
For example, instead of deploying into a cloud and like you've got Argo CD, watching for like continuous deployment type stuff. What if you were deploying an appliance like into someone's data center.

00:39:42.600 --> 00:39:47.380
And there were different concerns around security and updates and adopting updates and how it got updated.

00:39:47.760 --> 00:39:49.300
We want to be able to support that use case.

00:39:49.300 --> 00:40:02.800
We want to be able to, I'd love to be able to support a fully serverless, you know, SCAF lite type environment where maybe we're using Lambdas and DynamoDB and API Gateway to deploy the backend in a totally serverless manner.

00:40:03.080 --> 00:40:04.700
SCAF should be able to support that too.

00:40:04.900 --> 00:40:05.880
It's not there yet.

00:40:05.960 --> 00:40:08.060
That's definitely, that's the roadmap piece for sure.

00:40:08.340 --> 00:40:20.880
There probably is some, I'm not totally up on it, but it's probably some open source Valkey equivalent Docker based Lambda type stuff as well that you might be able to say, we want to have a self-contained serverless as part of this.

00:40:21.160 --> 00:40:25.200
- Yeah, for example, the Scaf challenge.

00:40:25.460 --> 00:40:36.540
So if you went to DjangoCon last year, 6PF ran a Scaf challenge where it was to see how fast you could basically run and get a running Django project on your machine in Kubernetes, running locally, ready to develop.

00:40:36.820 --> 00:40:44.840
The winner did it in 26 seconds from running Scaf to Django, actually ready to respond to HTTP requests.

00:40:45.260 --> 00:40:45.400
Wow.

00:40:45.840 --> 00:40:53.660
That backend that tracked it was all done in Dynamo, Lambda, and API Gateway using the SAM framework.

00:40:53.880 --> 00:41:00.660
And so on Amazon, there's the serverless application framework that they've got called SAM, which is really nice because you can run it all locally.

00:41:01.180 --> 00:41:09.520
You just do SAM serve or whatever, SAM start, and it spins up containers locally, you spin up your Dynamo container locally.

00:41:09.860 --> 00:41:22.380
So I had the whole thing running on my own machine, much in a way that's why I like about Scaf because it all runs locally, it all is contained and I can play with it, I can destroy it, I can make mistakes, and then when I'm ready, I make a pull request.

00:41:22.650 --> 00:41:52.440
>> Yeah. One of the things that I'm always apprehensive about is building apps that have to have lots of Cloud services constantly active, and not just because I want to be able to say, work in a coffee shop with poor internet connectivity or on an airplane or something like that. But also I feel like there's probably some leakage. I mean I just heard an ad on some podcast about it for a company that whose job is to go and look at all the AWS or Azure stuff you're doing that you might have left running and is costing you $10,000 a month. People just forgot about it.

00:41:52.440 --> 00:41:55.560
You know they'd be like, "Oh, let's try this." >> I think you should say that. We've had that.

00:41:56.080 --> 00:41:57.760
>> Oh really? Tell us a story.

00:41:57.940 --> 00:41:59.120
>> Yeah, that's

00:41:59.120 --> 00:42:04.040
another reason for parts we're adding into SCAF around compliance and cost controls.

00:42:04.920 --> 00:42:11.480
I'm a big fan of an open source tool called Cloud Custodian, which is a event-driven Cloud compliance tool.

00:42:11.740 --> 00:42:18.500
If you haven't checked it out, Cloud Custodian is a really great tool for compliance, but also fin ops.

00:42:19.300 --> 00:42:24.880
Making sure your Dev instances aren't running 24/7 when they really only need to run probably eight hours a day, they don't need to run on weekends.

00:42:25.060 --> 00:42:26.640
Cloud Custodian can shut those things down.

00:42:26.740 --> 00:42:31.340
That's something we're adding into SCAF right now, is some minimum set of things.

00:42:31.500 --> 00:42:35.180
like make sure any cloud resources you get deployed are properly tagged.

00:42:35.300 --> 00:42:37.880
You know, are they tagged with an environment like production or development?

00:42:38.120 --> 00:42:48.060
Are they tagged with a cost center or whatever your policies may be, but that will help you avoid those kinds of instances where we had, for example, someone spun up a spot instance.

00:42:48.440 --> 00:42:55.640
Well, if you're not familiar with Amazon, you can request spot instances, which are kind of excess EC2 VMs that are hanging out.

00:42:55.640 --> 00:42:58.100
And if someone releases one, you can pick it up and use it cheaper.

00:42:58.440 --> 00:43:00.380
And they're typically meant to be used temporarily.

00:43:00.780 --> 00:43:03.360
but you request them and they come asynchronously to you.

00:43:03.680 --> 00:43:13.980
So you could go into your console and request one, and if it doesn't come right away, you're like, "Shoot, that didn't work." And you could take off, you know, go get a coffee and get lunch, and then totally forget you requested the spot instance for a giant GPU, whatever.

00:43:14.380 --> 00:43:15.060
- And then it's ready.

00:43:15.380 --> 00:43:17.480
- Yeah, and then it'll show up later in the day.

00:43:18.060 --> 00:43:24.720
And if you don't go and turn it off, you'll pay for it for the month, which was $10,000 for one of them, once that happened to us.

00:43:24.840 --> 00:43:35.080
So putting in place the fact that if someone did spin up an instance like that, Cloud Custodian would be watching for it, and we'd shut it down within a day if it didn't follow whatever your policy is for starting up new kinds of instances.

00:43:35.460 --> 00:43:36.400
- That's really cool.

00:43:36.840 --> 00:43:38.940
We're learning about a lot of cool open source tools here.

00:43:39.000 --> 00:43:39.400
This is great.

00:43:39.620 --> 00:43:43.120
- And that's why they're all packaged into SCAP because not everyone knows about all these things.

00:43:43.360 --> 00:43:59.960
So we're trying to take our kind of cumulative six feet up journey of 25 years of being on the internet and deploying software and developing software and packaging those opinions into like one spot where it's kind of like someone took our brains, collective brains, and put them into a code repository and now we can deploy and develop like we've been doing

00:43:59.960 --> 00:44:00.700
it for 25 years.

00:44:01.060 --> 00:44:02.500
- Yeah, it's like, well, that was a really sharp edge.

00:44:02.780 --> 00:44:03.880
Let's see if we can come up with that.

00:44:03.910 --> 00:44:04.000
- Oh my gosh,

00:44:04.020 --> 00:44:04.220
yes.

00:44:04.839 --> 00:44:05.200
(both laughing)

00:44:06.799 --> 00:44:11.460
- Somebody's like, guys, sorry, but there's a big bill.

00:44:11.940 --> 00:44:12.500
- There was a big bill.

00:44:13.060 --> 00:44:14.440
Look, I'll give a shout out to Amazon.

00:44:15.199 --> 00:44:19.280
I contacted them and they did refund us for that accidental big bill.

00:44:19.600 --> 00:44:21.980
They're generally pretty good about it if you make that mistake once.

00:44:22.260 --> 00:44:26.420
Now, you gotta make sure you show them, you can demonstrate to them, you've put in place things to not have it happen again.

00:44:26.560 --> 00:44:27.520
- Okay, 'cause you might

00:44:27.520 --> 00:44:28.480
pay for it again.

00:44:28.560 --> 00:44:33.780
- Yeah, I honestly work in the cloud, it's super scary in that regard, you know, when it's overly automated.

00:44:34.040 --> 00:44:42.620
So, one of the things, speaking of deployments and all this that I do when I'm working with my Docker stuff is I'll set up a Docker compose file, that's kind of my zen right now.

00:44:42.840 --> 00:44:43.080
- Yeah.

00:44:43.360 --> 00:44:55.500
- And in there you can set deployment limits, like this container can only use so much CPU, more significantly for me usually is like, this container can only use one gig of RAM, even though the server's got 16, tell it it has one.

00:44:55.760 --> 00:45:19.620
And the reason that I think that's super useful is, something goes crazy or starts using too much memory or something like that, you could say, "Oh, there's something going on here without it taking down everything else." And there's other things, especially databases. They're like, "Oh, I've got 16 gigs. I was just going to load everything into memory because that'll be more efficient." Like, no, no, no, you're sharing this with everyone. Could you just load the indexes into your two gigs? That would be good, right? Is there stuff like that here?

00:45:19.980 --> 00:45:26.280
Yeah, exactly. And our opinions on that are in the Kubernetes world. You can be able to put in resource limits and priorities.

00:45:26.620 --> 00:45:28.700
This actually also literally happened to us.

00:45:29.840 --> 00:45:31.680
Again, all of our experience you get to benefit from.

00:45:32.380 --> 00:45:34.040
If you aren't careful with Kubernetes.

00:45:34.400 --> 00:45:34.460
>>

00:45:34.460 --> 00:45:38.060
I think every one of these that have a little double dagger thing, you click on it.

00:45:38.230 --> 00:45:38.900
>> That's totally right.

00:45:39.660 --> 00:45:40.180
>> Here's the

00:45:40.180 --> 00:45:41.020
story why this is here.

00:45:41.040 --> 00:45:43.620
Here's the story why this is here, because that's the truth.

00:45:44.859 --> 00:45:48.980
If you don't use resource limits on Kubernetes, they will absolutely stomp on each other.

00:45:49.440 --> 00:45:52.380
Kubernetes is an amazing orchestrator and it will do exactly what it's told.

00:45:52.580 --> 00:45:57.400
And if you've told it that this doesn't have limits, it will give it all the things all the time.

00:45:57.670 --> 00:46:04.080
And you can run into a situation, for example, if you're using cloud native PG, your database is in the cluster, which means it's orchestrated by the cluster.

00:46:04.480 --> 00:46:10.840
If you don't give it any limits and you're running multiples and you do a backup, the resources when you do a backup go up.

00:46:11.160 --> 00:46:11.400
Yes,

00:46:11.520 --> 00:46:12.320
100%. Yeah.

00:46:12.630 --> 00:46:16.100
If you do, it basically like scans through all of the data.

00:46:16.180 --> 00:46:16.880
And all the things.

00:46:17.020 --> 00:46:19.200
Why is it using three gigs? It was using just one.

00:46:19.440 --> 00:46:21.200
Oh, because I asked for a full backup.

00:46:21.380 --> 00:46:21.480
>>

00:46:21.480 --> 00:46:33.320
Well, and I tell you what it'll do is it'll consume all the resources on one node and then it'll fail over, orchestrated, it'll fail over to the second node and then use all the resources on the second node and then it'll corrupt your database and crash the whole thing.

00:46:33.940 --> 00:46:42.440
Now, if you put in the resource limits and the priorities, because what it should do is it should go off and be like, there's a lot of Django instances running that I don't need to be, I can kill those first.

00:46:42.740 --> 00:46:47.060
I can orchestrate smartly for you only if you smartly configure it.

00:46:47.160 --> 00:46:50.200
>> Right. Here's my goal is to not let this get out of control.

00:46:50.400 --> 00:46:52.900
help me with that. Don't just feed it everything.

00:46:53.480 --> 00:46:53.620
- Yeah.

00:46:53.700 --> 00:47:00.840
- Yeah, it's interesting. A lot of these servers are like, "We could do better if we could just take it, "we could load up more and pre-cache more." But they don't work well together like

00:47:00.840 --> 00:47:00.940
that.

00:47:01.140 --> 00:47:03.960
- Right, yeah. I mean, they're greedy.

00:47:04.100 --> 00:47:09.080
They're gonna try and take the resources they need to do the job they need to do, but they can be told to be less greedy.

00:47:10.039 --> 00:47:11.900
And Kubernetes is how we do that.

00:47:12.330 --> 00:47:12.740
- Yeah, more

00:47:12.740 --> 00:47:14.200
importantly, they can be forced to be less greedy.

00:47:14.220 --> 00:47:14.460
- You

00:47:14.460 --> 00:47:15.780
need to stay in line.

00:47:16.519 --> 00:47:16.880
(laughing)

00:47:17.320 --> 00:47:18.700
- So what you got? You're not getting more.

00:47:18.760 --> 00:47:20.880
All right, let's talk through the building blocks here.

00:47:20.940 --> 00:47:27.040
You mentioned a couple of them, but there's a big long list of things that I think is gonna be pretty interesting to people.

00:47:27.280 --> 00:47:27.880
Started with Django.

00:47:28.220 --> 00:47:28.320
- Yeah.

00:47:28.380 --> 00:47:30.060
- And then let's go down the building block.

00:47:30.240 --> 00:47:33.380
When I make an app like this, it has an opinion, it looks like as well.

00:47:33.440 --> 00:47:35.520
It's not just a vanilla Django app.

00:47:35.800 --> 00:47:35.980
- Correct.

00:47:36.380 --> 00:47:40.040
Yeah, you could be doing asynchronous tasks, so that's why there's a Celery opinion in there.

00:47:40.180 --> 00:47:43.420
Like we, you know, if you've got a project, you know you're gonna have jobs in the background.

00:47:43.940 --> 00:47:45.720
Sure, let's get Celery installed.

00:47:46.240 --> 00:48:19.880
If you're doing something with a fancy front end React, where our opinion is really to use Next.js. And if you install Next.js, you'll get like the strawberry GraphQL stuff out of the box, which is kind of nice and Apollo on the front end, if the Next.js is also chosen. So some GraphQL opinions have been made and the plumbing laid to make it just work, which is kind of hard sometimes. If you're diving into a new technology like React and GraphQL, it's nice to have some opinions and to have them pre-wired up for you. So you can just just kind of follow the pattern that's already been laid for you.

00:48:20.760 --> 00:48:21.860
Okay. I'm told that

00:48:21.860 --> 00:48:23.520
Next.js is really, really popular.

00:48:23.800 --> 00:48:24.180
Yeah.

00:48:24.900 --> 00:48:26.320
Tell us about what is Next.js.

00:48:26.520 --> 00:48:30.260
Yeah, I mean, Next.js is a set of opinions around React.

00:48:30.440 --> 00:48:36.920
Much in the way that, for example, like Zope and Plone were opinions around how to do a Python web framework.

00:48:37.340 --> 00:48:44.960
Next.js is kind of a packaging of some opinions about how I would deploy and write React applications and keep them up to date.

00:48:45.180 --> 00:48:50.940
For anyone who's done a React application, you can start with the standard React demo application.

00:48:51.400 --> 00:48:52.620
But from there, you start adding on it.

00:48:53.100 --> 00:49:13.520
Again, I'm definitely not the TypeScript, JavaScript front-end person, but dependency spaghetti mess will happen very quickly in this world, or can happen very quickly in this world, which will lead you into a spot where it's really difficult to upgrade your React application to get all the dependencies upgraded.

00:49:13.640 --> 00:49:17.040
and there's security vulnerabilities and issues you need to be aware of and performance things.

00:49:17.180 --> 00:49:19.500
So you want to make sure you can stay on top of those versions.

00:49:19.620 --> 00:49:25.500
And Next.js is basically a set of guidelines and opinions that should help guide you down a more happy path.

00:49:25.720 --> 00:49:26.480
And that's why we chose it.

00:49:26.780 --> 00:49:35.900
I think even the React folks tend to suggest using Next.js instead of just React on its own because you get those opinions and should have an easier time keeping things up to date.

00:49:36.140 --> 00:49:36.200
Yeah,

00:49:36.460 --> 00:49:40.040
I know the JS stuff feels like it's so complicated, but it's again because we're

00:49:40.040 --> 00:49:41.520
asking more and more.

00:49:41.700 --> 00:49:47.620
People have high expectations of the web applications that they interact with on a daily basis.

00:49:48.520 --> 00:49:54.300
It's just a fact of life that people expect, have expectations about how things are going to behave and the experience they're going to get.

00:49:54.540 --> 00:49:56.060
Yeah. They're like, Gmail's cool.

00:49:56.420 --> 00:49:58.100
Google Maps is cool. Can ours do that?

00:49:58.160 --> 00:50:03.800
Like, you realize this is a static website.

00:50:04.180 --> 00:50:05.680
You're the developer behind that?

00:50:06.120 --> 00:50:06.300
Yeah.

00:50:06.600 --> 00:50:07.100
And then if we

00:50:07.100 --> 00:50:10.060
keep going down this list, I mean, we've standardized on Postgres.

00:50:10.460 --> 00:50:12.240
and that's historic.

00:50:12.520 --> 00:50:15.040
We probably 15 years ago used MySQL.

00:50:16.080 --> 00:50:20.800
And that was back in the days of MySQL silently dropping data, on you.

00:50:21.120 --> 00:50:23.300
but I don't think those You got enough.

00:50:23.300 --> 00:50:25.400
I mean, you got enough of your data kept. There's a lot.

00:50:25.460 --> 00:50:33.740
That's exactly what it was. So we, we switched to Postgres and haven't looked back. and there's just a lot of exciting things happening there. So if you're not on Postgres, I highly

00:50:33.740 --> 00:50:42.260
recommend it. Good, good, good bet there, because if you look at the surveys and stuff, like The majority of people are doing that, especially if they're doing relational databases.

00:50:42.920 --> 00:50:46.860
It's Postgres and then you better justify why you're not using Postgres.

00:50:47.640 --> 00:50:52.780
>> Then if you're going to run Postgres and you're running Kubernetes, you're going to want to have some kind of an operator to manage it for you.

00:50:53.020 --> 00:50:57.700
If you want to have high availability, you want to have data backups, and that's what Cloud Native PG gives you.

00:50:58.180 --> 00:51:02.100
You can back up into S3 buckets, or you can back up into, you name it.

00:51:02.520 --> 00:51:06.640
There's multiple kinds of targets that are supported, but it manages all that hard complexity for you.

00:51:06.700 --> 00:51:21.160
If you've ever set up Postgres replication and high availability on your own and had to deal with all the wall files and moving them around and backing them up, it's a sophisticated beast, a complicated, sophisticated beast and no one wants to deal with that.

00:51:21.200 --> 00:51:22.500
And that's what Cloud Native PG does for you.

00:51:22.980 --> 00:51:25.980
It gives you UI and a way to configure it and away you go.

00:51:26.200 --> 00:51:26.900
- And then after that,

00:51:26.980 --> 00:51:27.600
we have Valkey.

00:51:27.920 --> 00:51:28.440
- Yeah, Valkey.

00:51:29.900 --> 00:51:31.620
Which is our Redis drop-in replacement.

00:51:32.420 --> 00:51:34.280
If you're not using Redis in your Django apps, you should be.

00:51:34.760 --> 00:51:38.540
even if nothing more than just the Django template cache, I would turn that on.

00:51:39.040 --> 00:51:41.800
We've been using Mailhog for our email locally.

00:51:41.900 --> 00:51:43.820
So this is a local developer tool.

00:51:44.360 --> 00:51:49.740
Allows you to simulate email being sent off of your development instance without actually sending email anywhere.

00:51:50.260 --> 00:51:50.860
- So it's a little

00:51:50.860 --> 00:51:51.960
bit like mocking email.

00:51:52.440 --> 00:51:53.360
- Yeah, yeah, it's super nice.

00:51:53.360 --> 00:51:55.560
It runs an SMTP server, it gives you a web UI.

00:51:56.700 --> 00:52:02.420
It looks like real email, it gives you an inbox so you can basically see what your end users are gonna see.

00:52:03.280 --> 00:52:07.080
Argo is the CI/CD product, but the open source GitOps.

00:52:07.540 --> 00:52:11.560
So it watches your repositories, kind of tracks the status of the deployments.

00:52:12.020 --> 00:52:12.960
- Okay, so you basically pick

00:52:12.960 --> 00:52:17.060
a prod branch or something like that and you push the prod then magic happens.

00:52:17.360 --> 00:52:19.080
- Yeah, Argo does the magic behind that.

00:52:19.080 --> 00:52:34.440
And you can see that it also gives you a bit of a insight into your cluster, you know, what's running, what's being deployed, what state they're in, you know, it handles all the like blue green, you know, rollout of new code, new pods and new containers into your clusters.

00:52:35.180 --> 00:52:36.880
It's, yeah, I can set up a

00:52:36.880 --> 00:52:38.620
QA cluster as well.

00:52:38.940 --> 00:52:41.280
Yep. Right. Just pick a different branch and have it watch that. Right.

00:52:41.460 --> 00:52:57.780
But that's what we do. So inside the SCAF built skeleton you get on your file system, you're going to have a Kubernetes manifest directory that has a base set of manifests, which are, this is what's needed to define the deployment and the services and all the bits.

00:52:57.880 --> 00:53:30.300
And then each environment, for example, like the sandbox environment, has an Argo running that'll be watching for sandbox changes, and the production environment will be watching for production changes. Another thing we standardize on here that's not listed is things like sealed secrets. So you can check in your secrets to your Git repository for sandbox, for example, but the only machine on the planet that can decrypt them is the sandbox instance, because you actually use the sealed secrets operator to do the encryption. And the only The only way it can be decrypted is if those things are sitting in that cluster, in the sandbox cluster or in the production cluster.

00:53:30.440 --> 00:53:34.820
So what's nice is the sandbox cluster cannot decrypt the production secrets.

00:53:34.890 --> 00:53:38.740
So you can have, obviously you want to have different secrets for production than you do for sandbox.

00:53:39.260 --> 00:53:40.440
So you can have least privilege.

00:53:40.590 --> 00:53:46.400
You know, developers have access, maybe more unfettered access to sandbox, but they may have more limited access on production.

00:53:46.860 --> 00:53:52.640
And tools like sealed secrets and customize and Kubernetes manifests and sealed secrets actually make all that work.

00:53:52.780 --> 00:53:53.020
Okay.

00:53:53.480 --> 00:53:53.580
Yeah.

00:53:53.600 --> 00:53:55.740
And that's, that's news to me as well.

00:53:55.840 --> 00:53:56.780
This one, I love it.

00:53:56.940 --> 00:53:58.800
I do something similar with my things as well.

00:53:58.860 --> 00:54:09.820
Like I know a lot of people have huge environment variable definitions of all their, I'm like, yeah, you just, you just need one value that unlocks the other, you know, highly encrypted stuff.

00:54:10.080 --> 00:55:43.460
Now for, for someone actually asked a question I'm getting ready to answer, which is about external secrets and services for those things, local development, we've have an opinion around using one password for all of our secrets management, whether it's like passwords for websites or API keys, or in this case, development environment, database passwords, development environment, you know, secrets, like Django has a secret, Django secret in there, things like that. Those are actually, in our case, environment variables. And we use the one password command line tool to only decrypt them ever in memory. So when you run like the Django start, or like the anytime you run the Kubernetes cluster locally and kind, it will feed those environment variables via the config map into your cluster so that it can access the database in the cluster locally. So even locally, you have a long, random, unknown password to you that is actually stored in one password. So if you want to go use your, I use Postico as a GUI for accessing my local Postgres, I can use that. I can actually feed the data from one password and actually access my services. So locally using one password and environment variables and config maps. But when going to sandbox, we just use sealed secrets on sandbox and production for mostly cross-platform consistency. You could be using, you know, SSM parameter store on Amazon or secrets manager on Amazon, but then that won't work on Google or won't work on Azure. And so we just standardize around the sealed secrets for ease of deployment to any cluster in any platform anywhere.

00:55:43.830 --> 00:55:46.880
Yeah, the one password new CLI stuff and SSH.

00:55:46.880 --> 00:55:47.320
So nice.

00:55:48.060 --> 00:55:49.880
Secret provider, whatever you call that thing.

00:55:50.180 --> 00:55:51.380
Yeah, it's super nice.

00:55:51.980 --> 00:56:01.200
Yeah, if you've not turned on the SSH keys for your 1Password CLI, I have no secret keys, no SSH keys, no API credentials.

00:56:01.380 --> 00:56:04.060
I have no secrets on my file system unencrypted.

00:56:04.520 --> 00:56:08.260
They're living in 1Password and 1Password proxies that access when needed.

00:56:08.640 --> 00:56:09.380
Yeah, that's pretty neat.

00:56:09.560 --> 00:56:10.900
I feel like I should maybe embrace that more.

00:56:11.000 --> 00:56:13.940
I embrace 1Password a lot, but there's more.

00:56:13.940 --> 00:56:14.920
Especially when

00:56:14.920 --> 00:56:21.000
you're working on multiple projects and multiple environments and you want to, again, have that least privileged access.

00:56:21.150 --> 00:56:23.400
You don't want to have one key to rule them all.

00:56:23.410 --> 00:56:32.200
You want to have keys to get you access to Sandbox, keys that can get you access to production, and you want to be able to give only certain people access to those production keys and only certain people access to Sandbox keys.

00:56:32.520 --> 00:56:36.340
And we actually do that with, so we're a Microsoft 365 shop.

00:56:36.490 --> 00:56:43.280
We use Microsoft's Entra Directory service, which is their Azure Active Directory product, and we use security groups.

00:56:43.540 --> 00:56:56.800
And so based on what security groups or what project you're working on, gives you access to only certain vaults inside of one password, gives you access to only certain accounts inside of Amazon and those kinds of things are all wired up to our, our single sign on platform.

00:56:57.080 --> 00:56:57.540
Yeah. Very nice.

00:56:57.740 --> 00:56:58.080
Traffic.

00:56:58.660 --> 00:57:02.260
Traffic's just an ingress controller. it's like a load balancer

00:57:02.260 --> 00:57:02.680
type thing.

00:57:02.900 --> 00:57:04.740
Yeah. It's a load balancer kind of cloud.

00:57:04.980 --> 00:57:13.220
If you rethought about a web server and it was cloud native and containers and understood clusters like Kubernetes clusters, this is what traffic is.

00:57:13.520 --> 00:57:14.000
Um,

00:57:14.520 --> 00:57:14.840
I see.

00:57:14.840 --> 00:57:18.680
So maybe a better analogy would be like NGINX or yeah.

00:57:19.020 --> 00:57:19.120
Yeah.

00:57:19.120 --> 00:57:20.260
I mean, I think we all grew up,

00:57:20.360 --> 00:57:29.680
we all grew up on NGINX and made it do all the crazy reverse proxy things like traffic is the one born in the cloud native world version of that.

00:57:29.920 --> 00:57:34.840
Now NGINX has their own ingress controller as well that they've re rewritten to be more cloud native.

00:57:35.060 --> 00:57:36.400
That's just what traffic is for us.

00:57:36.640 --> 00:57:43.040
cert manager again, handling things like TLS certificates and renewals and you name it, cert manager, make sure.

00:57:43.060 --> 00:57:47.220
How's that different than Let's Encrypt and Certbot and things like that?

00:57:48.360 --> 00:57:50.560
I mean, it's really similar in those cases.

00:57:50.560 --> 00:57:53.520
I think actually Certmanager, I think, is using Let's Encrypt under the covers.

00:57:54.480 --> 00:57:55.600
I could be wrong on that one.

00:57:55.740 --> 00:57:56.220
Maybe more

00:57:56.220 --> 00:57:58.520
cluster focused because that could be a real challenge.

00:57:58.660 --> 00:57:58.780
Well,

00:57:58.800 --> 00:58:04.080
because a lot of the, again, another beauty of Kubernetes that I don't think a lot of people talk about is the operators.

00:58:04.420 --> 00:58:14.420
These are like, you know, extensions or plugins to the Kubernetes cluster that give you superpowers to do things like make sure the certs are always, you know, renewed, make sure the latest code is always deployed.

00:58:14.840 --> 00:58:17.420
Make sure the database is highly available and backed up.

00:58:17.620 --> 00:58:21.140
Make sure, you know, that's what these operators do in the Kubernetes world.

00:58:21.340 --> 00:58:25.280
Is there like just plugins to your cluster that give you these extended capabilities?

00:58:25.860 --> 00:58:27.560
And that's what CertManager is, it's another one of those.

00:58:27.800 --> 00:58:30.040
So, and that handles the certificates and grass routes.

00:58:30.140 --> 00:58:32.580
That's all like kind of traffic CertManager certificates.

00:58:32.780 --> 00:58:33.140
It's all,

00:58:33.460 --> 00:58:34.260
yeah, it's all together.

00:58:34.500 --> 00:58:34.860
All together.

00:58:35.260 --> 00:58:41.240
Won't give you the certificate unless it can prove that certificate, that domain routes back to that thing.

00:58:41.380 --> 00:58:45.320
And yeah, it's great, but it does get a little complicated in Docker already.

00:58:45.520 --> 00:58:48.800
And then I can imagine auto scaling blusters that gets thrown away.

00:58:49.020 --> 00:58:50.000
You want it all just to work.

00:58:50.620 --> 00:58:52.000
Yeah, you don't want the certificate expired.

00:58:52.200 --> 00:58:54.060
Warning, danger, do not proceed to this website.

00:58:54.200 --> 00:58:54.580
Oh, no.

00:58:55.370 --> 00:58:56.980
All right, we got Prometheus in the house.

00:58:57.360 --> 00:58:59.000
Well, and Prometheus and Grafana are

00:58:59.000 --> 00:58:59.940
kind of together here.

00:59:00.300 --> 00:59:08.380
It's nice to have a observability, be able to see stats and trending data, to be able to make decisions on how you're scaling or handling load.

00:59:08.859 --> 00:59:14.060
It's hard to predict sometimes what a service is going to do when you go deploy it to real users.

00:59:14.540 --> 00:59:22.640
Real users have an uncanny knack of pushing buttons and making things happen that produce lots of crazy edge cases.

00:59:22.940 --> 00:59:24.920
- Right, this part was slow, so I just kept pushing the button.

00:59:25.080 --> 00:59:25.800
Like, you know, it's how

00:59:25.800 --> 00:59:26.980
much more load you're putting.

00:59:26.990 --> 00:59:28.660
It was really slow, 'cause I couldn't handle it.

00:59:28.820 --> 00:59:30.120
- And you'd prefer

00:59:30.120 --> 00:59:34.660
that you know about these problems before your users report them to you.

00:59:34.680 --> 00:59:38.220
So tools like Prometheus and Grafana and Loki.

00:59:38.700 --> 00:59:41.740
So Loki specifically is log aggregation.

00:59:42.520 --> 00:59:43.980
Prometheus is going to be a lot of metrics.

00:59:44.160 --> 00:59:46.200
And we combine those all into like Grafana dashboards.

00:59:46.640 --> 00:59:51.440
The trick here is, you know, you want to be able to get all the data, but then you got to make something meaningful of the data.

00:59:51.530 --> 00:59:57.100
And so we try to put in some, you know, default dashboards that give you that.

00:59:57.230 --> 01:00:06.940
If I was stuck on an island, what was the one screen of information I might need to make a business decision about what's happening here type view of things and not overload you with too much information.

01:00:07.100 --> 01:00:15.760
But you want to be able to dive deeper and see, oh, you know, when the database backup kicks in, the IO all of a sudden goes crazy. And that's why we're seeing a dip in here.

01:00:15.820 --> 01:00:36.640
And that's why there was a failover. Like, be able to trace back those things without data is impossible. And you only again, because we're in a clustered world and there's lots of interdependencies and these things can scale out, you could have many, many nodes running these tools, you got to have some way of getting a, I hate to say it, a single pane of glass. I'll put that out there.

01:00:36.720 --> 01:00:36.820
I

01:00:36.820 --> 01:00:42.040
can see my entire business in a single pane of glass. It is humming smoothly.

01:00:42.440 --> 01:00:43.180
Yeah, I'm sure

01:00:43.180 --> 01:00:48.740
all the IT folks, they all just cringe to like, "Oh my God, he just said it." Some

01:00:48.740 --> 01:00:58.520
people cringe and say, "Yes, they're speaking my language." Out there, my goal in the audience, the Media Cube from EPS is all of the pre-configured dashboards for Yeah, it's out of the box.

01:00:58.860 --> 01:00:58.940
Yeah,

01:00:58.960 --> 01:01:00.500
yeah, yeah, yeah, definitely.

01:01:00.530 --> 01:01:06.540
I mean, there's there's so many good example dashboards under Fanta that it is no reason not to be using this for durability.

01:01:07.060 --> 01:01:10.480
And this is like the table stakes, like you better start here and you better just do it.

01:01:10.900 --> 01:01:18.140
But a lot of people deploy an app and then they they I mean, how many times have you worked within a developer and you're like, well, if something's wrong, I can't figure out why.

01:01:18.320 --> 01:01:22.160
And the first thing you tell them, I guarantee you, Michael, the first thing you tell them to do is did you look in the logs?

01:01:22.440 --> 01:01:23.960
And they're like, no, I didn't look in the logs.

01:01:24.040 --> 01:01:26.080
I'm like, well, that's the first thing I do is go look at the logs.

01:01:26.560 --> 01:01:28.940
Yeah, that's the second thing you tell them.

01:01:29.040 --> 01:01:29.580
What's the first?

01:01:29.640 --> 01:01:31.460
First thing is, do you have logging?

01:01:32.680 --> 01:01:33.000
[laughing]

01:01:33.359 --> 01:01:34.020
True, okay.

01:01:34.160 --> 01:01:34.880
Yes, I have it.

01:01:34.940 --> 01:01:35.860
Okay, did you look at them?

01:01:36.320 --> 01:01:36.740
Fair enough.

01:01:36.900 --> 01:01:40.080
I was about to ask you though, like, do you have, do you have logging set up in this?

01:01:40.140 --> 01:01:44.340
And do you have like Log Guru or do you have Logbook or do you just do Python logging or what's the

01:01:44.340 --> 01:01:44.500
story?

01:01:44.700 --> 01:01:51.580
Yeah, I mean, we're using containers, so things should be set up to log as we would expect them in Kubernetes.

01:01:51.880 --> 01:01:58.060
So it's kind of like the if you've ever looked at the 12 factor app, you know, there's opinions about how logging should happen.

01:01:58.360 --> 01:02:07.340
That's what we adhere to is that logging should end up in a natural spot where it's easy for us to aggregate with tools like Prometheus and Grafana and actually then action and do something with them.

01:02:07.660 --> 01:02:09.800
So we typically have another SSH

01:02:09.800 --> 01:02:12.760
into other machines to see, well, what's this thing doing? What's that doing?

01:02:13.080 --> 01:02:16.720
And that's one thing I want to have no SSH into these clusters.

01:02:17.600 --> 01:02:23.580
Actually, one of our deployment opinions here is using things like Talos Linux for our Kubernetes deployments.

01:02:23.980 --> 01:02:26.560
Talos does not have a SSH shell enabled.

01:02:27.080 --> 01:02:30.420
Talos Linux has the ability to launch Kubernetes clusters.

01:02:30.560 --> 01:02:36.200
So you can use kubectl to manage your Kubernetes, but then you have the Talos CTL to manage Talos.

01:02:36.360 --> 01:02:38.200
There's no reason to shell into a box.

01:02:38.560 --> 01:02:42.340
It's just another security surface that you can now get rid of.

01:02:42.450 --> 01:02:44.020
>> Yeah. Very interesting. There's a couple of

01:02:44.060 --> 01:02:48.200
these single-purpose Linux distributions out there that are really, really cool.

01:02:48.370 --> 01:02:48.480
>>

01:02:48.480 --> 01:02:50.900
We've evaluated quite a few, And this is the one we picked.

01:02:51.260 --> 01:02:52.300
I liked its opinions.

01:02:52.410 --> 01:02:53.280
I liked its approach.

01:02:53.370 --> 01:02:54.860
I like the community that's behind it.

01:02:55.100 --> 01:02:58.080
One thing when you're picking a lot of these software tools is you need to look at the communities.

01:02:58.180 --> 01:02:59.400
You need to see how active they are.

01:02:59.700 --> 01:03:03.300
You need to understand, is this going to be a viable project, you know, five years from now?

01:03:03.420 --> 01:03:07.380
'Cause these are opinions you'll pick now and you'll have to live with potentially a long time.

01:03:07.640 --> 01:03:08.540
- That's a great point.

01:03:08.840 --> 01:03:11.680
Is this going to be your hobby project that you're going to have to keep it running for

01:03:11.680 --> 01:03:12.260
everyone else?

01:03:12.340 --> 01:03:14.080
Or is this thing got a life of its own?

01:03:14.180 --> 01:03:15.420
'Cause I don't need another hobby.

01:03:15.760 --> 01:03:16.240
- Yeah, exactly.

01:03:16.880 --> 01:03:18.100
We want this to be for real.

01:03:18.300 --> 01:03:18.460
Yeah.

01:03:18.760 --> 01:03:21.040
Let's do one more shout out of all the building blocks here.

01:03:21.540 --> 01:03:23.960
Sentry, you know, long time sponsor, friend of the show.

01:03:24.180 --> 01:03:36.100
Yeah. So again, observability tools like this, especially when it comes to like tools like Sentry or even DataDog and New Relic, we just happen to pick Sentry because I like, again, like the community.

01:03:36.160 --> 01:03:38.500
I like the people who are behind that tool.

01:03:38.940 --> 01:03:45.360
I can't tell you how much time a tool like Sentry has saved us when trying to diagnose and debug performance issues.

01:03:45.580 --> 01:04:01.380
I know it has lots and lots of features it can do, But when you're looking at a stack and you've got a n plus one performance issue going on with your database queries and its integrations with Django, its integrations with Redis and Postgres, just make tracking down that kind of stuff so much easier.

01:04:02.020 --> 01:04:08.520
We again, I'll go back to that 2020, 2021, when we launched Loud Swarm as a virtual event platform space.

01:04:08.760 --> 01:04:17.520
being able to deliver the schedule to a React application quickly as it's changing throughout the day was actually a big performance challenge.

01:04:17.780 --> 01:04:20.540
And Sentry highlighted exactly where the problems were.

01:04:20.860 --> 01:04:27.040
And then we just implemented a simple Redis cache that took us from 90 second generation of the schedule down to like milliseconds.

01:04:27.600 --> 01:04:32.240
And that was because we were able to pinpoint the issue really, really carefully and really, really close to a Sentry.

01:04:32.540 --> 01:04:36.560
It just, it bubbles up your problems and now you just go pick off the low hanging fruit.

01:04:36.760 --> 01:04:53.180
Yeah, that's awesome. I've also used it for error monitoring stuff and it's, I'm more than one, I know I say this on the show for some of the ads, but more than once, and this is not an ad, but I've certainly gotten an error and it's got all the variables of not just the stack trace, but actually the variables of what user ran into problems and all sorts of stuff.

01:04:53.240 --> 01:05:04.780
And I reached out to multiple people, said, I see you ran into this problem. I'm really sorry. I fixed it. Give it another try. And I'm sure that's a creepy experience in one way, but also you're like, geez, that doesn't happen very often.

01:05:04.880 --> 01:05:06.760
But you know, like, well, I fix it and I know who it is.

01:05:06.800 --> 01:05:08.740
I might as well tell them like, hey, sorry, you hit this.

01:05:08.900 --> 01:05:08.980
Yeah.

01:05:09.759 --> 01:05:15.340
One tool we've not mentioned here that is not in this list that I think is super important to our staff stack is Tilt.

01:05:16.080 --> 01:05:20.720
That is the local Kubernetes management tool of choice that we have picked.

01:05:21.000 --> 01:05:25.980
And if you've not played with Tilt, we've gone through different tools along the way.

01:05:26.060 --> 01:05:30.300
There was one called Scaffold and I can't remember the other ones we tried.

01:05:30.420 --> 01:05:34.820
There's numerous ones out there who basically sit in this space and try and solve this problem.

01:05:35.120 --> 01:05:40.720
But the killer feature for Tilt was two-way sync between your cluster and your local machine.

01:05:41.020 --> 01:05:50.980
So again, if you're running locally and using Kine, you probably don't notice anything because Tilt is watching your file system, synchronizing your files into the Kubernetes cluster for you to work, but it also does the reverse.

01:05:51.440 --> 01:06:11.440
One of the key bits I wanted was when you do a compilation of your requirements for your project, you're running Django and you've got a whole set of requirements, if you get into some trickier things, like around the data science world, there may be things that compile differently on macOS than on Linux, than on Windows, because they use some slightly different dependencies.

01:06:11.720 --> 01:06:14.400
That can be tricky when you're working in a container world.

01:06:14.560 --> 01:06:29.740
So you want to make sure you're doing your pip-tools compile, well, via uv, but your pip-tools compile in the container, in the target environment of where this is going to be deployed and built, because you'll get different results if you ran that pip-tools compile on your Mac, as opposed to into the Linux VM or Linux container.

01:06:29.760 --> 01:06:29.880
- Yeah,

01:06:29.880 --> 01:06:30.320
that's true.

01:06:30.700 --> 01:06:32.700
>> A platform specific wheels.

01:06:33.110 --> 01:06:41.660
>> Yeah. So tools like Tilt makes sure that I can run my thing in the container, and the result of it synchronizes back to my file system, and then I check that into the repository.

01:06:42.300 --> 01:06:43.540
That was a key bit there.

01:06:44.059 --> 01:06:46.480
Again, it has a lot of other cool things, nice UI.

01:06:47.440 --> 01:06:52.920
If you fire up Scaf, at the very end of it, it'll tell you, "Congratulations, you got a new project on your file system.

01:06:53.560 --> 01:07:02.740
CD in your project and just type Tilt up." You type Tilt up and you hit space bar, I think it is, and it launches a web browser with all the status of all the containers that are running locally.

01:07:03.220 --> 01:07:11.000
You can see all the logging, you can tilt watches for changes to your local file system for the code, tilt watches for changes to the Docker files.

01:07:11.240 --> 01:07:22.240
If you change the Docker file out from underneath tilt, like while you're developing, say you're adding a new layer, a new dependency or something that's needed in Docker and not in your Python, tilt will rebuild the container immediately for you.

01:07:22.400 --> 01:07:26.760
Like without you having to do anything, like you just kind of, you just code along and tilt keeps up.

01:07:27.000 --> 01:07:27.980
- Wow, that's awesome.

01:07:28.280 --> 01:07:28.360
- Yeah.

01:07:29.020 --> 01:07:29.980
setting your unit has

01:07:29.980 --> 01:07:31.260
to run on every save.

01:07:31.260 --> 01:07:31.960
>> Exactly.

01:07:32.240 --> 01:07:33.840
It is. It's fast.

01:07:34.260 --> 01:07:35.600
Sometimes you barely even notice.

01:07:35.660 --> 01:07:41.940
Like if you're working in a very late layer in the build, those builds can happen really, really quickly because most of the stuff is cached.

01:07:42.620 --> 01:07:43.820
Just notice of opinions.

01:07:44.620 --> 01:07:53.140
We've really tried to finally tune all the caching in the Docker files and all the layers so that these images build fast, they build slim, they use caches.

01:07:54.020 --> 01:07:57.980
So if you're running locally, it's going to cache things locally in your file system.

01:07:58.100 --> 01:08:01.700
you blow things away and start over again, it doesn't take forever to download all the stuff.

01:08:01.700 --> 01:08:03.240
It should be pulling from your local cache.

01:08:03.520 --> 01:08:07.180
- Yeah, that's a big shift when you're doing container type stuff.

01:08:07.280 --> 01:08:15.000
- Oh, man, 'cause some folks may have a not great experience with containers because of the size of some of these things and because they're not effectively using caching.

01:08:15.180 --> 01:08:16.180
This is a game changer.

01:08:16.319 --> 01:08:17.540
- Right, it 100% is.

01:08:17.600 --> 01:08:19.000
And just maybe potentially just

01:08:19.000 --> 01:08:22.040
reordering or splitting up commands could make - Oh, yeah.

01:08:22.680 --> 01:08:23.819
- 10x difference in speed.

01:08:25.020 --> 01:08:30.819
- Well, and you were the one who convinced me to switch over to uv inside their container builds as well.

01:08:30.980 --> 01:08:32.819
And that absolutely sped things up.

01:08:33.120 --> 01:08:33.700
Speed is a feature.

01:08:33.859 --> 01:08:41.080
I know you had that interview with Charlie, and that was one of the things that came out of that, but it's stuck in my head is speed is a feature, and I take that everywhere with me.

01:08:41.339 --> 01:08:41.759
- Yeah, that's awesome.

01:08:42.240 --> 01:08:43.799
It's a cheat code for sure.

01:08:43.870 --> 01:08:45.120
It's like, oh, we've hit it three, 10 times.

01:08:45.259 --> 01:08:46.380
Let's try that, that's awesome.

01:08:46.580 --> 01:08:51.880
And then, yeah, you can layer on more caching on top of that and make it even more ridiculous.

01:08:52.500 --> 01:08:54.880
All right, I think that's probably it for the time to talk through this.

01:08:54.920 --> 01:08:56.160
What a cool project you got here.

01:08:56.440 --> 01:08:59.920
Let's close it out with a roadmap.

01:09:00.410 --> 01:09:01.339
- So we've got a lot of things coming.

01:09:02.020 --> 01:09:10.720
One of the big ones is a big shift from using Cookie Cutter, which I've mentioned already, to using Copier as our underlying templating product.

01:09:11.040 --> 01:09:12.020
The big benefit-- - Tell people what Copier

01:09:12.020 --> 01:09:12.500
is, yeah.

01:09:12.680 --> 01:09:16.020
- Yeah, so Copiers, like Cookie Cutter, actually is a drop-in replacement for Cookie Cutter.

01:09:16.020 --> 01:09:23.420
You can use your Cookie Cutter templates you've already built with Copier, but now you can actually modularize them and upgrade them.

01:09:23.660 --> 01:09:27.680
So one of the problems with Cookie Cutter, was it was kind of one and done.

01:09:27.900 --> 01:09:32.880
Like you blew out your template onto the file system, you've got your code. That's the last time you would touch cookie cutter.

01:09:33.200 --> 01:09:43.600
But if new opinions come around, which we're constantly adding new opinions to SCAF about how we do dev and how we do deployment, you would want those to roll back into old projects that had been built with that same tool.

01:09:43.759 --> 01:09:44.700
Copier enables this.

01:09:44.839 --> 01:09:58.580
Copier now allows us to rerun against an existing project and adopt new opinions that have been made from the source template. And that's another change we're making is we're actually allowing Scaf to have multiple template types.

01:09:58.800 --> 01:10:02.960
So right now, the Scaf kind of runs in a full stack Django app mode.

01:10:03.280 --> 01:10:06.220
We're going to have the Scaf Lite version, which may be serverless.

01:10:06.320 --> 01:10:11.720
We're going to have the appliance mode, which would enable not using Argo CD, for example, but different ways of updating.

01:10:12.040 --> 01:10:15.420
We'll have opinions that are not Django necessarily.

01:10:15.580 --> 01:10:19.340
They may be more data pipeline versions of your apps.

01:10:19.400 --> 01:10:23.860
And so those will be templates that can be updated and and redeployed and kept up to date with Copier.

01:10:24.080 --> 01:10:29.620
That's cool. Yeah, I can see a whole idea, a whole concept of this for ML workloads and science

01:10:29.620 --> 01:10:32.780
workloads. And we don't actually need a web app. Exactly.

01:10:32.910 --> 01:10:39.560
What we need is data ingestion and intel and we want results, either a notebook or just something in a database on the other end of them.

01:10:39.800 --> 01:10:58.160
Yeah. Yeah, that's a big, that's a big deal. And that's another thing that is included in Skap Opinions is the CI pipeline, the GitHub actions, Bitbucket Act, you know, workflows or whatever their CI thing is called. Because those Those are important, those need to be there day one, 'cause they're so hard to tack on later, or you just get busy and you don't tack them on when you should have.

01:10:58.260 --> 01:11:06.060
- Yeah, it's good to have all this experience and all these rounded off rough edges put together in one box for you, very cool.

01:11:06.540 --> 01:11:13.440
All right, well we're certainly out of time, Calvin, so how about, we've got two things to close this out, unlike normal.

01:11:13.720 --> 01:11:15.680
So let's close it out with a final call to action.

01:11:15.720 --> 01:11:16.840
People are interested in SCAF.

01:11:17.160 --> 01:11:18.420
- Yeah, they

01:11:18.420 --> 01:11:19.660
should definitely go to-- - Should I go to Starrett?

01:11:20.020 --> 01:11:20.780
- Yep, go to Starrett.

01:11:20.920 --> 01:11:53.700
log in apparently. Yeah, go hang out, go to the 6github/scaph GitHub repository. It's a one-liner to install. I would love to hear your feedback, you know, any feature requests, you know, any bugs you find. We've worked really hard on ironing out a lot of those issues over the last year as we kind of pushed toward DjangoCon last year. It's amazing and mind-blowing to see how fast you can get a Django project up and running on your own machine with Kubernetes in the mix. Maybe people a little background information, like they're like, I heard of Kubernetes.

01:11:54.340 --> 01:11:55.460
What do I do with it?

01:11:55.520 --> 01:11:59.940
Like you got good resources for them to Oh, on YouTube, there's

01:11:59.940 --> 01:12:11.380
an excellent YouTuber. Her name's Nana. So if you just search Nana and Kubernetes, she does an incredible job of explaining Kubernetes to everybody.

01:12:12.180 --> 01:12:15.640
Yeah. I believe it's Nana Codes. Yeah. Technical Nana.

01:12:16.010 --> 01:12:16.140
Yeah.

01:12:16.360 --> 01:12:17.240
Yeah. She's awesome.

01:12:17.240 --> 01:12:18.160
She's really good. Yeah.

01:12:18.260 --> 01:12:18.720
She's really good.

01:12:18.740 --> 01:12:19.340
She's really good.

01:12:19.600 --> 01:12:23.040
a great way of explaining these kind of deeper technology things.

01:12:23.140 --> 01:12:24.700
That's literally where I went.

01:12:24.800 --> 01:12:26.320
I was like, I need to know more about Kubernetes.

01:12:26.480 --> 01:12:27.540
I went and watched her videos.

01:12:28.160 --> 01:12:28.720
I met her in person.

01:12:28.840 --> 01:12:29.860
She's actually an AWS hero.

01:12:30.180 --> 01:12:31.960
And she was at reInvent a couple of years ago.

01:12:32.060 --> 01:12:36.120
And just again, superhuman being doing this for the love of technology.

01:12:36.700 --> 01:12:39.600
Actually, I can give a shout out also to one of the people in the chat.

01:12:39.920 --> 01:12:44.000
Michael Levin is also a prolific YouTuber on Kubernetes.

01:12:44.400 --> 01:12:44.900
Oh, no kidding.

01:12:45.120 --> 01:12:46.920
Okay, I'll put a link to his channel as well.

01:12:47.280 --> 01:12:47.360
Awesome.

01:12:47.440 --> 01:12:49.600
All right, well, Calvin, thank you for being here.

01:12:49.940 --> 01:12:50.580
It's been awesome.

01:12:51.000 --> 01:12:54.320
I can't tell you how excited I was about the opportunity.

01:12:54.580 --> 01:12:55.460
Yeah, it's been super

01:12:55.460 --> 01:12:56.240
fun and I

01:12:56.240 --> 01:12:56.980
was excited as well.

01:12:57.620 --> 01:13:01.760
So much so, so much so that I've made a theme song for this episode.

01:13:02.060 --> 01:13:04.460
I'm not going to play it on the YouTube live stream version.

01:13:04.580 --> 01:13:06.460
It's just the logistics of that are a little bit challenging.

01:13:07.000 --> 01:13:08.200
But I'll put a link

01:13:08.200 --> 01:13:08.620
in

01:13:08.620 --> 01:13:11.100
the YouTube description in a day or two.

01:13:11.340 --> 01:13:14.440
And when this show comes out, it's going to be at the end.

01:13:14.440 --> 01:13:18.360
And so if you're listening through the MP3 version of your podcast player, be sure to listen to the end.

01:13:18.580 --> 01:13:19.680
There's gonna be a-- - Get ready to crank

01:13:19.680 --> 01:13:19.920
it up.

01:13:20.280 --> 01:13:21.520
- Yeah, so here's the thing.

01:13:21.660 --> 01:13:24.360
If you like Linkin Park and that style of music, you're gonna love it.

01:13:24.380 --> 01:13:26.420
If you hate Linkin Park, maybe call it a show.

01:13:27.240 --> 01:13:28.640
Anyway, it's gonna be super fun.

01:13:29.220 --> 01:13:31.700
We'll put, let's deploy, or deploy the dream at the end.

01:13:31.740 --> 01:13:33.700
It'll be a great theme song to round things out.

01:13:34.060 --> 01:13:35.540
And with that, Calvin, thanks for being on the show.

01:13:35.780 --> 01:13:36.640
- Awesome, thanks, Michael.

01:13:36.960 --> 01:13:37.320
- Yeah, bye.

01:13:41.140 --> 01:13:41.780
(gentle music)

01:13:41.780 --> 01:13:42.680
(dramatic music)

01:14:11.780 --> 01:14:18.140
Every line in the repo, a key to set us free And now we break through on Talk Python To Me!

01:14:18.740 --> 01:17:01.120
Deploy the dream Shake the ground under your feet Surge forward in the stream Python code is moving heat With Talk Python To Me We ignite the synergy Let's tear down walls, let's own the scene Deploy the dream ♪ Deploy the dream Shake the ground under your feet Search forward in the street ♪ Python code is moving heat ♪ With talk Python to me We ignite the synergy ♪ ♪ Let's tear down walls ♪ ♪ Let's own the scene ♪ ♪ Deploy the dream Shards of GML swirling in the night ♪ ♪ Argo CDs overhead guiding by its light ♪ ♪ We watch the pipeline triggers ♪ ♪ Silent countdown clock ♪ ♪ From dev to prod, we're unstoppable stock ♪ ♪ The logs are rolling in, Prometheus can see ♪ ♪ Our metrics rise like signals, a living symphony ♪ ♪ Mailog sends illusions to the test in the sky ♪ ♪ While Sentry's capturing errors with an all-seeing eye ♪ ♪ We commit, we build, we test once more ♪ ♪ Containers racing onward to the cloud's front door ♪ ♪ Resilience in the code, watch the pods come free ♪ ♪ The stage is set now on top, Python to May Deploy the dream Shatter limits that confine A brand new scheme Pushing progress down the line We're unstoppable now Calvin's leading strategy Let's break the mold, let's rewrite souls Deploy the dream Deploy the cap Offtense beat and build dealing intensity ♪ I see the server lights blinking in the distance ♪ ♪ Code commits illusion smashing with persistence ♪ ♪ Dive deep into the backlog we're forging the path ♪ ♪ Docker image at the ready time to feel the wrath ♪ ♪ Python in my veins blueprint on the screen ♪ ♪ Dev to stage to prod no in between ♪ ♪ We scale up, scale out then break the routine ♪ ♪ This is talk Python to me ♪ ♪ A new reality ♪ Toss the girls belt, belt them ♪ ♪ No code left behind ♪ ♪ We share the knowledge so all devs can find ♪ ♪ A way to unify the spark ♪ ♪ A chance to break free ♪ ♪ Join Calvin, Hendrix, Parker ♪ ♪ Let's make history ♪ Deploy the dream ♪ ♪ High voltage in our core Evolve the theme We're unstoppable once more ♪ Untalk Python to me ♪ ♪ Our voices ring in synergy ♪ Now let's ascend ♪ ♪ Let's set this free ♪ I dream

01:17:01.120 --> 01:17:01.900
the

01:17:01.900 --> 01:17:02.400
dream

01:17:28.400 --> 01:17:30.820
This has been another episode of Talk Python To Me.

01:17:31.540 --> 01:17:32.600
Thank you to our sponsors.

01:17:32.980 --> 01:17:34.300
Be sure to check out what they're offering.

01:17:34.400 --> 01:17:35.660
It really helps support the show.

01:17:36.460 --> 01:17:40.260
This episode is sponsored by Posit Connect from the makers of Shiny.

01:17:40.900 --> 01:17:44.800
Publish, share, and deploy all of your data projects that you're creating using Python.

01:17:45.280 --> 01:17:51.440
Streamlit, Dash, Shiny, Bokeh, FastAPI, Flask, Quarto, Reports, Dashboards, and APIs.

01:17:52.240 --> 01:17:53.860
Posit Connect supports all of them.

01:17:54.120 --> 01:17:59.480
Try Posit Connect for free by going to talkpython.fm/posit, P-O-S-I-T.

01:18:00.300 --> 01:18:11.780
This episode is brought to you by my new book, "Talk Python in Production." I've long felt that most guidance and marketing about how we need to run Python apps in production has been overly complex and expensive.

01:18:12.140 --> 01:18:18.400
This book is both a look at the history of Talk Python To Me and an antidote to this overly complex cloud world.

01:18:19.020 --> 01:18:23.620
Read it online and get the full book at talkpython.fm/devopsbook.

01:18:24.500 --> 01:18:40.120
And to level up your Python, we have one of the largest catalogs of Python video courses over at Talk Python. Our content ranges from true beginners to deeply advanced topics like memory and async. And best of all, there's not a subscription in sight. Check it out for yourself at training.talkpython.fm.

01:18:40.880 --> 01:18:45.020
Be sure to subscribe to the show, open your favorite podcast app, and search for Python.

01:18:45.380 --> 01:19:06.580
We should be right at the top. You can also find the iTunes feed at /itunes, the Google play feed at /play and the direct RSS feed at /rss on talkpython.fm. We're live streaming most of our recordings these days. If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talkpython.fm/youtube.

01:19:07.100 --> 01:19:07.580
This

01:19:07.580 --> 01:19:12.920
is your host Michael Kennedy. Thanks so much for listening. I really appreciate it. Now get out there and write some Python code.

