-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
52ae534
commit abdd9c4
Showing
10 changed files
with
482 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Docker | ||
Run a monolith website inside a docker container | ||
|
||
## Enable Docker | ||
```bash | ||
sudo systemctl enable docker | ||
sudo systemctl start docker | ||
``` | ||
|
||
## Overview | ||
For the example, assume the domain is `pistonite.org` and the subdomain/sitename | ||
is `example`. Also, assume the docker image is `pistonite/example` and the container | ||
will run on port `5001` | ||
|
||
## Setup Tasks | ||
Create tasks to manage sites with docker | ||
```yaml | ||
tasks: | ||
# ... other tasks | ||
docker-pull: | ||
cmds: | ||
- mkdir -p '/opt/pistonite/{{.SITE}}' | ||
- touch '/opt/pistonite/{{.SITE}}/.env' | ||
- docker pull '{{.IMAGE}}' | ||
- docker tag '{{.IMAGE}}' '{{.SITE}}:deploy' | ||
|
||
docker-run: | ||
cmds: | ||
- chown -R root:root '/opt/pistonite/{{.SITE}}' | ||
- chmod -R 600 '/opt/pistonite/{{.SITE}}' | ||
- docker container prune -f | ||
- docker run -d --name '{{.SITE}}' -p '{{.PORT}}:80' --env-file '/opt/pistonite/{{.SITE}}/.env' '{{.SITE}}:deploy' | ||
- docker image prune -a -f | ||
|
||
``` | ||
|
||
## Add Site Commands | ||
Create tasks to manage the site `example` | ||
```yaml | ||
tasks: | ||
# ... other tasks | ||
start:example: | ||
desc: Start `example` | ||
cmds: | ||
- task: docker-run | ||
vars: | ||
SITE: example | ||
PORT: 5001 | ||
deploy:example: | ||
desc: Deploy `example` | ||
cmds: | ||
- task: docker-pull | ||
vars: | ||
IMAGE: pistonite/example:latest | ||
SITE: example | ||
- docker stop example | ||
- task: start:example | ||
``` | ||
## Environment Variables | ||
Environment variables can be configured in the `/opt/pistonite/example/.env` file | ||
``` | ||
FOO=BAR | ||
MY_SECRET=SECRET | ||
``` | ||
## Nginx Config | ||
Create config file, replace `example` with the site name | ||
```bash | ||
sudo nvim /etc/nginx/sites-available/example.conf | ||
``` | ||
Then paste in the following template and change as needed | ||
```nginx | ||
server { | ||
listen 443 ssl; | ||
server_name example.pistonite.org; | ||
ssl_protocols TLSv1.2 TLSv1.3; | ||
# Enable gzip if the web server doesn't have built-in compression | ||
gzip on; | ||
gzip_min_length 1000; | ||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/gif image/jpeg image/png image/svg+xml image/tiff image/webp; | ||
gzip_disable "msie6"; | ||
# Cross Origin Isolation? | ||
#add_header Cross-Origin-Opener-Policy same-origin; | ||
#add_header Cross-Origin-Embedder-Policy require-corp; | ||
# Cache? | ||
#add_header Cache-Control max-age=604800; | ||
location / { | ||
proxy_pass http://localhost:5001; | ||
} | ||
} | ||
``` | ||
|
||
## Enable the Site | ||
First run `deploy:example`, which will pull the image, but fail to stop the previous container because it doesn't exist | ||
```bash | ||
sudo task deploy:example | ||
``` | ||
Then start the container and enable the site | ||
```bash | ||
sudo task start:example | ||
sudo task enable -- example | ||
sudo task restart | ||
``` | ||
|
||
## Operations | ||
To deploy newer image tagged `latest` | ||
```bash | ||
sudo task deploy:example | ||
``` | ||
:::tip | ||
This will pull the image, stop the old container, start a new container, and remove old container and images | ||
::: | ||
To restore the previous version, change the `IMAGE` in the deploy task, and re-run the deploy task |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
# Prod | ||
TODO | ||
# Production Environment | ||
|
||
I use an Arch Linux server that runs nginx to serve static files and reverse proxy to some docker containers. | ||
|
||
First, update the system and install `nvim`, so we can edit files. | ||
|
||
```bash | ||
sudo pacman -Syu nvim | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# Nginx | ||
Create basic config for `nginx`, without any sites yet. | ||
|
||
## Create `www` user | ||
First create a user that will own the nginx files, and set the permissions | ||
so only that user can read/write the files. | ||
```bash | ||
sudo useradd --system -s /usr/bin/nologin www -U | ||
sudo chown -R www:www /etc/nginx | ||
sudo chmod -R 600 /etc/nginx | ||
``` | ||
|
||
## Store Certificate | ||
Assume you have a certificate file `foo.com.pem` and key file `foo.com.key`, | ||
where `foo.com` is the site name. | ||
|
||
Create the certificate file, and paste in the contents of the certificate and key. | ||
```bash | ||
sudo mkdir /etc/nginx/certs | ||
sudo nvim /etc/nginx/certs/foo.com.pem | ||
sudo nvim /etc/nginx/certs/foo.com.key | ||
``` | ||
:::danger | ||
Make sure to clear clipboard history/data after pasting in the key! | ||
::: | ||
|
||
Then, lock it down so only the `www` user can read it. | ||
```bash | ||
sudo chown -R www:www /etc/nginx/certs | ||
sudo chmod -R 400 /etc/nginx/certs | ||
``` | ||
|
||
## Base Config | ||
|
||
Open the config file | ||
```bash | ||
sudo nvim /etc/nginx/nginx.conf | ||
``` | ||
Paste in the following: | ||
```nginx | ||
user www; | ||
worker_processes auto; | ||
events { | ||
multi_accept on; | ||
worker_connections 1024; | ||
} | ||
http { | ||
include mime.types; | ||
default_type application/octet-stream; | ||
#log_format main '$remote_addr - $remote_user [$time_local] "$request" ' | ||
# '$status $body_bytes_sent "$http_referer" ' | ||
# '"$http_user_agent" "$http_x_forwarded_for"'; | ||
#access_log logs/access.log main; | ||
# Set Certificate | ||
ssl_certificate /etc/nginx/certs/pistonite.org.pem; | ||
ssl_certificate_key /etc/nginx/certs/pistonite.org.key; | ||
# Reuse SSL sessions | ||
ssl_session_cache shared:SSL:10m; | ||
ssl_session_timeout 10m; | ||
keepalive_timeout 70; | ||
include sites-enabled/*; | ||
# Block default requests | ||
server { | ||
listen 443 default_server; | ||
server_name _; | ||
return 444; | ||
} | ||
} | ||
``` | ||
|
||
## Enable Service | ||
Enable and start the `nginx` service. | ||
```bash | ||
sudo systemctl enable nginx | ||
sudo systemctl start nginx | ||
``` | ||
:::tip | ||
If `nginx` fails to start, you can debug with `sudo nginx -t` | ||
::: | ||
|
||
## Firewall | ||
Define firewall rules for port 80 and 443 | ||
for your desired traffic. | ||
|
||
For example, since I use Cloudflare, | ||
I will only allow the [IPs for Cloudflare](https://www.cloudflare.com/ips/) | ||
and IP addresses for other necessary services | ||
to access my server. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Security | ||
|
||
Have a production breach is bad so we want to have as much security as possible. | ||
|
||
## Non-Root User | ||
Follow [here](../arch/user.md#add-non-root-user) to create a non-root | ||
user and add it to the `wheel` group. | ||
|
||
## SSH | ||
:::warning | ||
Before preceeding, setup the key for SSH following [here](../arch/user.md#setting-up-ssh-keys), | ||
so you don't get locked out of the machine! Sometimes you need to | ||
set up the SSH key with the server provider. | ||
::: | ||
|
||
Login to the server with the non-root user and the SSH key, then, | ||
follow [here](../arch/user.md#hardening-ssh-security) to edit the SSH config. | ||
Restart the `sshd` service afterward. | ||
|
||
## Firewall | ||
You should use the server provider's service to configure firewall for the VM. | ||
|
||
My firewall configuration is basically: | ||
- Allow inbound TCP on port 22, from my IP | ||
- Allow only inbound TCP on port 443 from Cloudflare IPs | ||
- Allow outbound TCP/UDP to port 53 (for DNS) for all IPs | ||
- Allow outbound TCP to port 80, 443 for all IPs | ||
- Drop all other traffic | ||
:::tip | ||
The ports specified above for outbound rules are port on the remote machine | ||
(not the port of my machine) | ||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Manage Sites | ||
|
||
## Taskfile | ||
Create a `Taskfile.yml` in your home directory. | ||
```yaml | ||
version: '3' | ||
|
||
# Add environment variables | ||
#env: | ||
# FOO: BAR | ||
|
||
tasks: | ||
restart: | ||
desc: Reset the permissions and restart the nginx service | ||
cmds: | ||
- chown -R www:www /etc/nginx | ||
- chmod -R 600 /etc/nginx | ||
- chmod -R 400 /etc/nginx/certs | ||
- systemctl restart nginx | ||
enable: | ||
desc: Enable a site (-- SITE) | ||
cmds: | ||
- ln -s '/etc/nginx/sites-available/{{.CLI_ARGS}}.conf' '/etc/nginx/sites-enabled/{{.CLI_ARGS}}.conf' | ||
disable: | ||
desc: Disable a site (-- SITE) | ||
cmds: | ||
- unlink '/etc/nginx/sites-enabled/{{.CLI_ARGS}}.conf' | ||
list: | ||
desc: List all sites | ||
cmds: | ||
- ls /etc/nginx/sites-available | ||
``` | ||
Then, lock it down so only the current user can read/write it | ||
```bash | ||
USER=$(whoami) | ||
sudo chown $USER:$USER /home/$USER/Taskfile.yml | ||
sudo chmod 600 /home/$USER/Taskfile.yml | ||
``` | ||
|
||
Now, it should be (relatively) safe to store secrets in the `Taskfile.yml`. | ||
|
Oops, something went wrong.