Skip to content

Commit 4691a1f

Browse files
author
Tom Softreck
committed
ansbile tests
1 parent 20e9595 commit 4691a1f

File tree

14 files changed

+311
-39
lines changed

14 files changed

+311
-39
lines changed

PRODUCTION.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Production Deployment Guide
2+
3+
This guide explains how to deploy the application stack in a production environment using Traefik as a reverse proxy with Let's Encrypt SSL certificates.
4+
5+
## Prerequisites
6+
7+
1. A server with Docker and Docker Compose installed
8+
2. A domain name (e.g., `devopsterminal.com`) with DNS access
9+
3. Ports 80 and 443 open in your firewall
10+
11+
## Setup Instructions
12+
13+
1. **Update DNS Records**
14+
Create the following DNS A records pointing to your server's IP address:
15+
- `devopsterminal.com`
16+
- `projekt1.devopsterminal.com`
17+
- `projekt2.devopsterminal.com`
18+
- `traefik.devopsterminal.com`
19+
20+
2. **Update Configuration**
21+
- Update the email address in `docker-compose.prod.yml` (search for `[email protected]`)
22+
- Update the domain names if you're using a different domain than `devopsterminal.com`
23+
- Change the default credentials for the Traefik dashboard (see below)
24+
25+
3. **Change Default Credentials**
26+
The default credentials for the Traefik dashboard are:
27+
- Username: `admin`
28+
- Password: `changeme`
29+
30+
To generate a new password hash:
31+
```bash
32+
echo $(htpasswd -nb admin your-new-password) | sed -e s/\\$/\\$\$/g
33+
```
34+
Update the `traefik.http.middlewares.auth.basicauth.users` label in `docker-compose.prod.yml` with the new hash.
35+
36+
4. **Deploy the Stack**
37+
```bash
38+
# Create the network if it doesn't exist
39+
podman network create prod_network
40+
41+
# Create required directories
42+
mkdir -p letsencrypt traefik
43+
chmod 600 letsencrypt
44+
45+
# Start the stack
46+
podman-compose -f docker-compose.prod.yml up -d
47+
```
48+
49+
## Accessing Services
50+
51+
- **Project 1**: https://projekt1.devopsterminal.com
52+
- **Project 2**: https://projekt2.devopsterminal.com
53+
- **Traefik Dashboard**: https://traefik.devopsterminal.com (requires authentication)
54+
55+
## Monitoring
56+
57+
Traefik logs are available in the container and also mounted to:
58+
- `./traefik/traefik.log` - Traefik service logs
59+
- `./traefik/access.log` - Access logs
60+
61+
## Maintenance
62+
63+
### View Logs
64+
```bash
65+
podman-compose -f docker-compose.prod.yml logs -f
66+
```
67+
68+
### Update Containers
69+
```bash
70+
podman-compose -f docker-compose.prod.yml pull
71+
podman-compose -f docker-compose.prod.yml up -d --force-recreate
72+
```
73+
74+
### Backup and Restore
75+
76+
**Backup Let's Encrypt certificates:**
77+
```bash
78+
tar -czvf letsencrypt_backup_$(date +%Y%m%d).tar.gz letsencrypt/
79+
```
80+
81+
**Restore from backup:**
82+
```bash
83+
tar -xzvf letsencrypt_backup_YYYYMMDD.tar.gz
84+
```
85+
86+
## Security Considerations
87+
88+
1. **Firewall**: Ensure only necessary ports (80, 443) are open to the internet
89+
2. **Updates**: Regularly update your containers and host system
90+
3. **Monitoring**: Set up monitoring for your services
91+
4. **Backups**: Regularly back up your Let's Encrypt certificates and application data

README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ services:
116116
ports:
117117
- "80:80"
118118
- "443:443"
119-
- "8080:8080" # Dashboard
119+
- "8082:8080" # Dashboard
120120

121121
volumes:
122122
- "/var/run/docker.sock:/var/run/docker.sock:ro"
@@ -282,7 +282,7 @@ services:
282282
- "--entrypoints.web.address=:80"
283283
ports:
284284
- "80:80"
285-
- "8080:8080"
285+
- "8082:8080"
286286
volumes:
287287
- "/var/run/docker.sock:/var/run/docker.sock:ro"
288288
networks:
@@ -356,7 +356,7 @@ docker-compose -f docker-compose-local.yml ps
356356
### Testowanie
357357
```bash
358358
# Sprawdź dashboard Traefik
359-
curl http://localhost:8080
359+
curl http://localhost:8082
360360

361361
# Testuj aplikacje
362362
curl http://localhost/sklep
@@ -370,7 +370,7 @@ curl http://localhost/portfolio
370370
## Krop 6: Monitoring i Dashboard
371371

372372
### Dostęp do Dashboard Traefik
373-
Idź na: `http://twój-ip:8080`
373+
Idź na: `http://twój-ip:8082`
374374

375375
W dashboard zobaczysz:
376376
- **HTTP Routers**: Twoje trasy
@@ -431,7 +431,7 @@ case $1 in
431431
;;
432432
dashboard)
433433
echo "🖥️ Dashboard dostępny na:"
434-
echo "http://$(curl -s ifconfig.me):8080"
434+
echo "http://$(curl -s ifconfig.me):8082"
435435
;;
436436
*)
437437
echo "Użycie: $0 {start|stop|restart|rebuild|logs|status|dashboard}"
@@ -550,8 +550,8 @@ ls -la letsencrypt/
550550

551551
#### Dashboard nie działa
552552
```bash
553-
# Sprawdź czy port 8080 jest otwarty
554-
sudo netstat -tlnp | grep 8080
553+
# Sprawdź czy port 8082 jest otwarty
554+
sudo netstat -tlnp | grep 8082
555555

556556
# Sprawdź konfigurację
557557
docker-compose exec traefik traefik version
@@ -560,13 +560,13 @@ docker-compose exec traefik traefik version
560560
### Przydatne komendy debugowania
561561
```bash
562562
# Zobacz wszystkie routery
563-
curl -s http://localhost:8080/api/http/routers | jq
563+
curl -s http://localhost:8082/api/http/routers | jq
564564

565565
# Zobacz wszystkie serwisy
566-
curl -s http://localhost:8080/api/http/services | jq
566+
curl -s http://localhost:8082/api/http/services | jq
567567

568568
# Status Traefik
569-
curl -s http://localhost:8080/api/overview
569+
curl -s http://localhost:8082/api/overview
570570
```
571571

572572
---
@@ -684,7 +684,7 @@ global:
684684
scrape_configs:
685685
- job_name: 'traefik'
686686
static_configs:
687-
- targets: ['traefik:8080']
687+
- targets: ['traefik:8082']
688688
```
689689
690690
---

ansible/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ansible>=2.9
2+
requests>=2.25.1

ansible/test.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
- name: Test Podman Traefik Setup
3+
hosts: localhost
4+
connection: local
5+
gather_facts: false
6+
tasks:
7+
- name: Check if Traefik dashboard is accessible
8+
uri:
9+
url: http://localhost:8083/dashboard/
10+
method: GET
11+
status_code: 200
12+
timeout: 5
13+
register: traefik_dashboard
14+
ignore_errors: yes
15+
16+
- name: Check Projekt1 service
17+
uri:
18+
url: http://localhost:8081/projekt1
19+
method: GET
20+
status_code: 200
21+
return_content: yes
22+
timeout: 5
23+
register: projekt1_check
24+
until: projekt1_check.status == 200
25+
retries: 3
26+
delay: 2
27+
28+
- name: Check Projekt2 service
29+
uri:
30+
url: http://localhost:8081/projekt2
31+
method: GET
32+
status_code: 200
33+
return_content: yes
34+
timeout: 5
35+
register: projekt2_check
36+
until: projekt2_check.status == 200
37+
retries: 3
38+
delay: 2
39+
40+
- name: Show test results
41+
debug:
42+
msg:
43+
- "Traefik Dashboard: {{ 'Accessible' if traefik_dashboard.status == 200 else 'Not Accessible' }}"
44+
- "Projekt1 Status: {{ projekt1_check.status }} - Content: {{ projekt1_check.content | b64decode | regex_search('>([^<]+)<') | default('No content') }}"
45+
- "Projekt2 Status: {{ projekt2_check.status }} - Content: {{ projekt2_check.content | b64decode | regex_search('>([^<]+)<') | default('No content') }}"

docker-compose.prod.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ services:
1111
- "--providers.docker.exposedbydefault=false"
1212
- "--entrypoints.web.address=:80"
1313
- "--entrypoints.websecure.address=:443"
14-
- "--entrypoints.dashboard.address=:8080"
14+
- "--entrypoints.dashboard.address=:8082"
1515
# Enable automatic HTTPS with Let's Encrypt
1616
- "--certificatesresolvers.leresolver.acme.httpchallenge=true"
1717
- "--certificatesresolvers.leresolver.acme.httpchallenge.entrypoint=web"
@@ -22,9 +22,9 @@ services:
2222
# Use podman network
2323
- "--providers.docker.network=prod_network"
2424
ports:
25-
- "80:80"
26-
- "443:443"
27-
- "8080:8080" # Dashboard - should be restricted in production
25+
- "8081:80" # HTTP traffic (mapped from 80 to 8081)
26+
- "8443:443" # HTTPS traffic (mapped from 443 to 8443)
27+
- "8082:8080" # Dashboard - should be restricted in production
2828
volumes:
2929
- "/var/run/docker.sock:/var/run/docker.sock:ro"
3030
- "./letsencrypt:/letsencrypt"

docker-compose.yml

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,19 @@ version: '3.8'
33
services:
44
traefik:
55
image: traefik:v2.10
6-
command:
7-
- "--api.insecure=true"
8-
- "--providers.docker=true"
9-
- "--providers.docker.exposedbydefault=false"
10-
- "--entrypoints.web.address=:80"
11-
- "--entrypoints.websecure.address=:443"
12-
- "--entrypoints.dashboard.address=:8080"
13-
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
14-
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
15-
16-
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
17-
- "--api.dashboard=true"
18-
- "--providers.docker.network=podman"
6+
command: --configFile=/etc/traefik/traefik.yml
197
ports:
20-
- "8082:8080" # Traefik dashboard
21-
- "8081:80" # HTTP traffic
22-
- "8443:443" # HTTPS traffic
8+
- "8081:80" # HTTP traffic
9+
- "8083:8083" # Traefik dashboard
2310
volumes:
24-
- "/var/run/docker.sock:/var/run/docker.sock:ro"
25-
- "./letsencrypt:/letsencrypt"
11+
- "./traefik/traefik.yml:/etc/traefik/traefik.yml:ro"
12+
- "./traefik/rules.yml:/etc/traefik/rules.yml:ro"
13+
networks:
14+
- podman
2615
restart: unless-stopped
16+
depends_on:
17+
- "projekt1"
18+
- "projekt2"
2719

2820
projekt1:
2921
build: ./projekt1
@@ -45,14 +37,9 @@ services:
4537
labels:
4638
- "traefik.enable=true"
4739
- "traefik.http.routers.projekt2.rule=Host(`localhost`) && PathPrefix(`/projekt2`)"
48-
- "traefik.http.routers.projekt2.entrypoints=web"
49-
- "traefik.http.services.projekt2.loadbalancer.server.port=5000"
50-
- "traefik.http.middlewares.strip-prefix.stripprefix.prefixes=/projekt2"
51-
- "traefik.http.routers.projekt2.middlewares=strip-prefix@docker"
5240
restart: unless-stopped
5341

5442
networks:
5543
podman:
5644
name: podman
5745
external: false
58-

projekt1/Dockerfile

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,31 @@ FROM python:3.9-slim
22

33
WORKDIR /app
44

5+
# Set environment variables
6+
ENV PYTHONDONTWRITEBYTECODE 1
7+
ENV PYTHONUNBUFFERED 1
8+
ENV FLASK_APP=app.py
9+
ENV FLASK_ENV=production
10+
11+
# Install system dependencies
12+
RUN apt-get update && apt-get install -y --no-install-recommends \
13+
build-essential \
14+
&& rm -rf /var/lib/apt/lists/*
15+
16+
# Install Python dependencies
517
COPY requirements.txt .
618
RUN pip install --no-cache-dir -r requirements.txt
719

20+
# Copy application code
821
COPY . .
922

23+
# Create a non-root user and switch to it
24+
RUN adduser --disabled-password --gecos '' appuser && \
25+
chown -R appuser:appuser /app
26+
USER appuser
27+
28+
# Expose the port the app runs on
1029
EXPOSE 5000
1130

12-
CMD ["python", "app.py"]
31+
# Command to run the application
32+
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

projekt1/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
Flask==2.0.1
22
Werkzeug==2.0.1
3+
gunicorn==20.1.0

projekt2/Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM python:3.9-slim
2+
3+
WORKDIR /app
4+
5+
# Set environment variables
6+
ENV PYTHONDONTWRITEBYTECODE 1
7+
ENV PYTHONUNBUFFERED 1
8+
ENV FLASK_APP=app.py
9+
ENV FLASK_ENV=production
10+
11+
# Install system dependencies
12+
RUN apt-get update && apt-get install -y --no-install-recommends \
13+
build-essential \
14+
&& rm -rf /var/lib/apt/lists/*
15+
16+
# Install Python dependencies
17+
COPY requirements.txt .
18+
RUN pip install --no-cache-dir -r requirements.txt
19+
20+
# Copy application code
21+
COPY . .
22+
23+
# Create a non-root user and switch to it
24+
RUN adduser --disabled-password --gecos '' appuser && \
25+
chown -R appuser:appuser /app
26+
USER appuser
27+
28+
# Expose the port the app runs on
29+
EXPOSE 5000
30+
31+
# Command to run the application with Gunicorn
32+
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "--worker-class", "gthread", "--threads", "2", "--timeout", "120", "--access-logfile", "-", "--error-logfile", "-", "app:app"]

projekt2/app.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from flask import Flask
2+
3+
app = Flask(__name__)
4+
5+
@app.route('/')
6+
def hello():
7+
return "<h1>Witaj w Projekcie 2!</h1><p>To jest druga aplikacja Flask działająca za pośrednictwem Traefik.</p>"
8+
9+
if __name__ == '__main__':
10+
app.run(host='0.0.0.0', port=5000)

0 commit comments

Comments
 (0)